diff options
| author | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
| commit | 7514efc2f38c9ace4557d4e69d68e7d380389030 (patch) | |
| tree | 7fb00fda86cfcc2ca377f191633a7cfdbfea7ca3 /src | |
| parent | d6201f5d8daada3d64a0a3e0038e14eebec683ce (diff) | |
Imported Upstream version 1.4.0 upstream/1.4.0
Diffstat (limited to 'src')
387 files changed, 14060 insertions, 6747 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 48af5a06..c460caff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,41 +32,95 @@ SUBDIRS += \ tests endif -AM_CPPFLAGS = \ - -I$(top_srcdir)/shared \ +AM_CPPFLAGS = \ + -I$(top_srcdir)/shared \ -I$(top_builddir)/shared \ - -I$(top_builddir)/introspection \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/callouts \ + -I$(top_builddir)/introspection \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + \ + $(foreach d,$(sort $(dir $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) \ + \ -DPREFIX=\"$(prefix)\" \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ - -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ + \ + -DBINDIR=\"$(bindir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DRUNSTATEDIR=\"$(runstatedir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DRUNDIR=\"$(rundir)\" \ + \ + -DNMCONFDIR=\"$(nmconfdir)\" \ + -DNMLOCALEDIR=\"$(datadir)/locale\" \ + -DNMPLUGINDIR=\"$(pkglibdir)\" \ + -DNMRUNDIR=\"$(nmrundir)\" \ + -DNMSTATEDIR=\"$(nmstatedir)\" \ + -DNMLIBDIR=\"$(nmlibdir)\" \ + \ + -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ + -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ + -DPPPD_PLUGIN_DIR=\"$(PPPD_PLUGIN_DIR)\" \ + \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(LIBNDP_CFLAGS) \ + $(LIBSOUP_CFLAGS) \ + $(SELINUX_CFLAGS) \ + $(LIBAUDIT_CFLAGS) \ + $(SYSTEMD_LOGIN_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) \ + \ + -I$(top_srcdir)/src/systemd/src/systemd/ \ + -I$(top_srcdir)/src/systemd/ \ + \ + $(NULL) -# add each subdirectory that contains a libNM source file. $(sort) is being used -# primarily for its side effect of removing duplicates. -AM_CPPFLAGS += $(foreach d,$(sort $(dir $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) +AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) + +sbin_PROGRAMS = \ + NetworkManager + +libexec_PROGRAMS = \ + nm-iface-helper noinst_LTLIBRARIES = \ + libNetworkManagerBase.la \ libNetworkManager.la \ + libNetworkManagerTest.la \ libnm-iface-helper.la \ libsystemd-nm.la -###################### -# libsystemd-nm -###################### - -SYSTEMD_NM_CFLAGS_PATHS = \ - -I$(top_srcdir)/src/systemd/src/systemd \ - -I$(top_srcdir)/src/systemd/src/libsystemd-network \ - -I$(top_srcdir)/src/systemd/src/basic \ - -I$(top_srcdir)/src/systemd +############################################################################### libsystemd_nm_la_SOURCES = \ systemd/nm-sd.c \ systemd/nm-sd.h \ - systemd/nm-sd-adapt.c \ - systemd/nm-sd-adapt.h \ + systemd/sd-adapt/nm-sd-adapt.c \ + systemd/sd-adapt/nm-sd-adapt.h \ + systemd/sd-adapt/build.h \ + systemd/sd-adapt/cgroup-util.h \ + systemd/sd-adapt/condition.h \ + systemd/sd-adapt/conf-parser.h \ + systemd/sd-adapt/def.h \ + systemd/sd-adapt/dirent-util.h \ + systemd/sd-adapt/formats-util.h \ + systemd/sd-adapt/gunicode.h \ + systemd/sd-adapt/libudev.h \ + systemd/sd-adapt/missing.h \ + systemd/sd-adapt/mkdir.h \ + systemd/sd-adapt/process-util.h \ + systemd/sd-adapt/sd-daemon.h \ + systemd/sd-adapt/stat-util.h \ + systemd/sd-adapt/udev-util.h \ + systemd/sd-adapt/udev.h \ + systemd/sd-adapt/user-util.h \ + systemd/sd-adapt/virt.h \ systemd/src/basic/alloc-util.c \ systemd/src/basic/alloc-util.h \ systemd/src/basic/async.h \ @@ -74,6 +128,8 @@ libsystemd_nm_la_SOURCES = \ systemd/src/basic/escape.h \ systemd/src/basic/ether-addr-util.c \ systemd/src/basic/ether-addr-util.h \ + systemd/src/basic/extract-word.c \ + systemd/src/basic/extract-word.h \ systemd/src/basic/fd-util.c \ systemd/src/basic/fd-util.h \ systemd/src/basic/fileio.c \ @@ -107,6 +163,7 @@ libsystemd_nm_la_SOURCES = \ systemd/src/basic/random-util.h \ systemd/src/basic/refcnt.h \ systemd/src/basic/set.h \ + systemd/src/basic/signal-util.h \ systemd/src/basic/siphash24.c \ systemd/src/basic/siphash24.h \ systemd/src/basic/socket-util.c \ @@ -157,6 +214,8 @@ libsystemd_nm_la_SOURCES = \ systemd/src/libsystemd-network/sd-ipv4ll.c \ systemd/src/libsystemd-network/sd-lldp.c \ systemd/src/libsystemd/sd-event/sd-event.c \ + systemd/src/libsystemd/sd-id128/id128-util.c \ + systemd/src/libsystemd/sd-id128/id128-util.h \ systemd/src/libsystemd/sd-id128/sd-id128.c \ systemd/src/shared/dns-domain.c \ systemd/src/shared/dns-domain.h \ @@ -173,64 +232,40 @@ libsystemd_nm_la_SOURCES = \ systemd/src/systemd/sd-ndisc.h libsystemd_nm_la_CPPFLAGS = \ - -I$(top_srcdir)/shared \ - -I$(top_builddir)/shared \ + -I$(top_srcdir)/shared/ \ + -I$(top_builddir)/shared/ \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ - $(SYSTEMD_NM_CFLAGS_PATHS) \ - -I$(top_srcdir)/src/systemd/src/shared \ + -I$(top_srcdir)/src/systemd/sd-adapt/ \ + -I$(top_srcdir)/src/systemd/src/systemd/ \ + -I$(top_srcdir)/src/systemd/src/basic/ \ + -I$(top_srcdir)/src/systemd/src/shared/ \ + -I$(top_srcdir)/src/systemd/src/libsystemd-network/ \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_SYSTEMD \ $(GLIB_CFLAGS) libsystemd_nm_la_LIBADD = \ $(GLIB_LIBS) -###################### -# libsystemd-nm-base -###################### +############################################################################### -if ENABLE_TESTS -noinst_LTLIBRARIES += \ - libNetworkManager-base.la - -libNetworkManager_base_la_SOURCES = \ +libNetworkManagerBase_la_SOURCES = \ nm-core-utils.c \ nm-core-utils.h \ nm-logging.c \ nm-logging.h -libNetworkManager_base_la_CPPFLAGS = \ - -I$(top_srcdir)/shared \ - -I$(top_builddir)/shared \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/src/platform \ - -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - -DNO_SYSTEMD_JOURNAL \ - -DPREFIX=\"$(prefix)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" \ - $(GLIB_CFLAGS) - -libNetworkManager_base_la_LIBADD = \ +libNetworkManagerBase_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ - $(GLIB_LIBS) -endif - -########################################### -# NetworkManager -########################################### - -sbin_PROGRAMS = NetworkManager + $(GLIB_LIBS) \ + $(SYSTEMD_JOURNAL_LIBS) \ + $(NULL) -NetworkManager_SOURCES = \ - $(nm_device_sources) $(nm_device_headers) \ - $(nm_dhcp_client_sources) $(nm_dhcp_client_headers) \ - main-utils.c \ - main-utils.h \ - main.c +############################################################################### -NetworkManager_LDADD = libNetworkManager.la +# These source files have a attribute((constructor)) to register their factories. +# This gets stripped out from the resulting binary if we add them to libNetworkManager.la. +# Instead, add them to the binary. An alternative would be to link with --as-needed. nm_device_sources = \ devices/nm-device-bond.c \ @@ -255,23 +290,33 @@ nm_device_headers = \ devices/nm-device-tun.h \ devices/nm-device-veth.h \ devices/nm-device-vlan.h \ - devices/nm-device-vxlan.h + devices/nm-device-vxlan.h \ + $(NULL) nm_dhcp_client_sources = \ dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhclient-utils.c \ dhcp-manager/nm-dhcp-dhcpcd.c \ - dhcp-manager/nm-dhcp-systemd.c + dhcp-manager/nm-dhcp-systemd.c \ + $(NULL) nm_dhcp_client_headers = \ dhcp-manager/nm-dhcp-dhclient.h \ - dhcp-manager/nm-dhcp-dhclient-utils.h \ dhcp-manager/nm-dhcp-dhcpcd.h \ - dhcp-manager/nm-dhcp-systemd.h + dhcp-manager/nm-dhcp-systemd.h \ + $(NULL) + +############################################################################### libNetworkManager_la_SOURCES = \ - $(nm_device_headers) \ - $(nm_dhcp_client_headers) \ + \ + dhcp-manager/nm-dhcp-dhclient-utils.c \ + dhcp-manager/nm-dhcp-dhclient-utils.h \ + \ + nm-checkpoint-manager.c \ + nm-checkpoint-manager.h \ + nm-checkpoint.c \ + nm-checkpoint.h \ + \ devices/nm-device.c \ devices/nm-device.h \ devices/nm-lldp-listener.c \ @@ -321,16 +366,12 @@ libNetworkManager_la_SOURCES = \ platform/nm-platform.h \ platform/nm-linux-platform.c \ platform/nm-linux-platform.h \ - platform/nm-fake-platform.c \ - platform/nm-fake-platform.h \ platform/wifi/wifi-utils-nl80211.c \ platform/wifi/wifi-utils-nl80211.h \ platform/wifi/wifi-utils-private.h \ platform/wifi/wifi-utils.c \ 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 \ @@ -392,8 +433,6 @@ libNetworkManager_la_SOURCES = \ nm-config.h \ nm-config-data.c \ nm-config-data.h \ - nm-connection-provider.c \ - nm-connection-provider.h \ nm-connectivity.c \ nm-connectivity.h \ nm-dcb.c \ @@ -418,8 +457,6 @@ libNetworkManager_la_SOURCES = \ nm-ip4-config.h \ nm-ip6-config.c \ nm-ip6-config.h \ - nm-logging.c \ - nm-logging.h \ nm-auth-manager.c \ nm-auth-manager.h \ nm-auth-subject.c \ @@ -439,11 +476,9 @@ libNetworkManager_la_SOURCES = \ nm-sleep-monitor.c \ nm-sleep-monitor.h \ nm-types.h \ - nm-core-utils.c \ - nm-core-utils.h \ NetworkManagerUtils.c \ - NetworkManagerUtils.h - + NetworkManagerUtils.h \ + $(NULL) if WITH_WEXT libNetworkManager_la_SOURCES += \ @@ -452,64 +487,17 @@ libNetworkManager_la_SOURCES += \ endif -GLIB_GENERATED = nm-enum-types.h nm-enum-types.c -GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include <nm-core-enum-types.h>\n' -GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_enum_types_sources = $(filter-out \ - %/nm-device-private.h \ - %/nm-rdisc-private.h \ - %/wifi-utils-private.h \ - %/nm-dhcp-client-logging.h \ - %/nm-device-logging.h \ - , $(libNetworkManager_la_SOURCES)) - -BUILT_SOURCES = $(GLIB_GENERATED) - -AM_CPPFLAGS += \ - $(GLIB_CFLAGS) \ - $(GUDEV_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(LIBNDP_CFLAGS) \ - $(LIBSOUP_CFLAGS) \ - $(SELINUX_CFLAGS) \ - $(LIBAUDIT_CFLAGS) \ - $(SYSTEMD_LOGIN_CFLAGS) \ - $(SYSTEMD_JOURNAL_CFLAGS) \ - $(SYSTEMD_NM_CFLAGS_PATHS) \ - \ - -DBINDIR=\"$(bindir)\" \ - -DDATADIR=\"$(datadir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DRUNSTATEDIR=\"$(runstatedir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DRUNDIR=\"$(rundir)\" \ - \ - -DNMCONFDIR=\"$(nmconfdir)\" \ - -DNMLOCALEDIR=\"$(datadir)/locale\" \ - -DNMPLUGINDIR=\"$(pkglibdir)\" \ - -DNMRUNDIR=\"$(nmrundir)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" \ - -DNMLIBDIR=\"$(nmlibdir)\" \ - \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ - -DPPPD_PLUGIN_DIR=\"$(PPPD_PLUGIN_DIR)\" \ - \ - $(NULL) - libNetworkManager_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la \ libsystemd-nm.la \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ - $(SYSTEMD_JOURNAL_LIBS) \ $(LIBNDP_LIBS) \ - $(LIBDL) \ + $(DL_LIBS) \ $(LIBM) \ $(SELINUX_LIBS) \ $(LIBAUDIT_LIBS) @@ -518,13 +506,42 @@ if WITH_LIBSOUP libNetworkManager_la_LIBADD += $(LIBSOUP_LIBS) endif +############################################################################### + +libNetworkManagerTest_la_SOURCES = \ + rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h \ + platform/nm-fake-platform.c \ + platform/nm-fake-platform.h + +libNetworkManagerTest_la_LIBADD = \ + libNetworkManager.la + +############################################################################### + +NetworkManager_SOURCES = \ + \ + $(nm_device_sources) \ + $(nm_device_headers) \ + \ + $(nm_dhcp_client_sources) \ + $(nm_dhcp_client_headers) \ + \ + main-utils.c \ + main-utils.h \ + main.c + +NetworkManager_LDADD = \ + libNetworkManager.la + NetworkManager_LDFLAGS = \ -rdynamic \ -Wl,--version-script="$(srcdir)/NetworkManager.ver" -###################### +############################################################################### libnm_iface_helper_la_SOURCES = \ + \ dhcp-manager/nm-dhcp-client.c \ dhcp-manager/nm-dhcp-client.h \ dhcp-manager/nm-dhcp-client-logging.h \ @@ -549,8 +566,6 @@ libnm_iface_helper_la_SOURCES = \ platform/wifi/wifi-utils.c \ 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 \ @@ -568,12 +583,8 @@ libnm_iface_helper_la_SOURCES = \ \ nm-enum-types.c \ nm-enum-types.h \ - nm-logging.c \ - nm-logging.h \ nm-multi-index.c \ nm-multi-index.h \ - nm-core-utils.c \ - nm-core-utils.h \ NetworkManagerUtils.c \ NetworkManagerUtils.h @@ -586,16 +597,15 @@ endif libnm_iface_helper_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la \ libsystemd-nm.la \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ $(LIBNDP_LIBS) \ - $(LIBDL) \ + $(DL_LIBS) \ $(LIBM) -libexec_PROGRAMS = nm-iface-helper - nm_iface_helper_SOURCES = \ dhcp-manager/nm-dhcp-systemd.h \ dhcp-manager/nm-dhcp-systemd.c \ @@ -605,18 +615,32 @@ nm_iface_helper_SOURCES = \ nm_iface_helper_LDADD = \ $(top_builddir)/libnm-core/libnm-core.la \ - libsystemd-nm.la \ libnm-iface-helper.la \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ - $(SYSTEMD_JOURNAL_LIBS) \ $(LIBNL_LIBS) \ $(LIBNDP_LIBS) \ $(LIBM) -nm_iface_helper_LDFLAGS = -rdynamic +nm_iface_helper_LDFLAGS = \ + -rdynamic + +############################################################################### + +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include <nm-core-enum-types.h>\n' +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' +nm_enum_types_sources = $(filter-out \ + %/nm-device-private.h \ + %/nm-rdisc-private.h \ + %/wifi-utils-private.h \ + %/nm-dhcp-client-logging.h \ + %/nm-device-logging.h \ + , $(libNetworkManager_la_SOURCES)) + +BUILT_SOURCES = $(GLIB_GENERATED) -###################### +############################################################################### dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = org.freedesktop.NetworkManager.conf @@ -624,6 +648,7 @@ dbusservice_DATA = org.freedesktop.NetworkManager.conf EXTRA_DIST = \ $(dbusservice_DATA) \ $(NetworkManager_DATA) \ + nm-test-utils-core.h \ NetworkManager.ver rundir=$(runstatedir)/NetworkManager diff --git a/src/Makefile.in b/src/Makefile.in index 1047880d..7f4cf252 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -102,28 +102,22 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@ supplicant-manager/tests \ @ENABLE_TESTS_TRUE@ tests - -###################### -# libsystemd-nm-base -###################### -@ENABLE_TESTS_TRUE@am__append_5 = \ -@ENABLE_TESTS_TRUE@ libNetworkManager-base.la - sbin_PROGRAMS = NetworkManager$(EXEEXT) -@WITH_WEXT_TRUE@am__append_6 = \ +libexec_PROGRAMS = nm-iface-helper$(EXEEXT) +@WITH_WEXT_TRUE@am__append_5 = \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.c \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.h -@WITH_LIBSOUP_TRUE@am__append_7 = $(LIBSOUP_LIBS) -@WITH_WEXT_TRUE@am__append_8 = \ +@WITH_LIBSOUP_TRUE@am__append_6 = $(LIBSOUP_LIBS) +@WITH_WEXT_TRUE@am__append_7 = \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.c \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.h -libexec_PROGRAMS = nm-iface-helper$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -144,39 +138,20 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = -@ENABLE_TESTS_TRUE@libNetworkManager_base_la_DEPENDENCIES = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ -@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) -am__libNetworkManager_base_la_SOURCES_DIST = nm-core-utils.c \ - nm-core-utils.h nm-logging.c nm-logging.h -@ENABLE_TESTS_TRUE@am_libNetworkManager_base_la_OBJECTS = \ -@ENABLE_TESTS_TRUE@ libNetworkManager_base_la-nm-core-utils.lo \ -@ENABLE_TESTS_TRUE@ libNetworkManager_base_la-nm-logging.lo -libNetworkManager_base_la_OBJECTS = \ - $(am_libNetworkManager_base_la_OBJECTS) -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 = -@ENABLE_TESTS_TRUE@am_libNetworkManager_base_la_rpath = @WITH_LIBSOUP_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libNetworkManager_la_DEPENDENCIES = \ $(top_builddir)/libnm-core/libnm-core.la \ - $(top_builddir)/introspection/libnmdbus.la libsystemd-nm.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la libsystemd-nm.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_2) -am__libNetworkManager_la_SOURCES_DIST = devices/nm-device-bond.h \ - devices/nm-device-bridge.h devices/nm-device-ethernet.h \ - devices/nm-device-infiniband.h devices/nm-device-ip-tunnel.h \ - devices/nm-device-macvlan.h devices/nm-device-tun.h \ - devices/nm-device-veth.h devices/nm-device-vlan.h \ - devices/nm-device-vxlan.h dhcp-manager/nm-dhcp-dhclient.h \ - dhcp-manager/nm-dhcp-dhclient-utils.h \ - dhcp-manager/nm-dhcp-dhcpcd.h dhcp-manager/nm-dhcp-systemd.h \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__libNetworkManager_la_SOURCES_DIST = \ + dhcp-manager/nm-dhcp-dhclient-utils.c \ + dhcp-manager/nm-dhcp-dhclient-utils.h nm-checkpoint-manager.c \ + nm-checkpoint-manager.h nm-checkpoint.c nm-checkpoint.h \ devices/nm-device.c devices/nm-device.h \ devices/nm-lldp-listener.c devices/nm-lldp-listener.h \ devices/nm-arping-manager.c devices/nm-arping-manager.h \ @@ -203,12 +178,11 @@ am__libNetworkManager_la_SOURCES_DIST = devices/nm-device-bond.h \ platform/nmp-object.h platform/nm-platform-utils.c \ platform/nm-platform-utils.h platform/nm-platform.c \ platform/nm-platform.h platform/nm-linux-platform.c \ - platform/nm-linux-platform.h platform/nm-fake-platform.c \ - platform/nm-fake-platform.h platform/wifi/wifi-utils-nl80211.c \ + platform/nm-linux-platform.h \ + platform/wifi/wifi-utils-nl80211.c \ platform/wifi/wifi-utils-nl80211.h \ platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ - platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ - rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + platform/wifi/wifi-utils.h rdisc/nm-lndp-rdisc.c \ 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 ppp-manager/nm-ppp-status.h \ @@ -244,59 +218,72 @@ am__libNetworkManager_la_SOURCES_DIST = devices/nm-device-bond.h \ nm-activation-request.h nm-active-connection.c \ nm-active-connection.h nm-audit-manager.c nm-audit-manager.h \ nm-bus-manager.c nm-bus-manager.h nm-config.c nm-config.h \ - nm-config-data.c nm-config-data.h nm-connection-provider.c \ - nm-connection-provider.h nm-connectivity.c nm-connectivity.h \ - nm-dcb.c nm-dcb.h nm-route-manager.c nm-route-manager.h \ - nm-default-route-manager.c nm-default-route-manager.h \ - nm-dhcp4-config.c nm-dhcp4-config.h nm-dhcp6-config.c \ - nm-dhcp6-config.h nm-dispatcher.c nm-dispatcher.h \ - nm-enum-types.c nm-enum-types.h nm-exported-object.c \ - nm-exported-object.h nm-firewall-manager.c \ - nm-firewall-manager.h nm-ip4-config.c nm-ip4-config.h \ - nm-ip6-config.c nm-ip6-config.h nm-logging.c nm-logging.h \ + nm-config-data.c nm-config-data.h nm-connectivity.c \ + nm-connectivity.h nm-dcb.c nm-dcb.h nm-route-manager.c \ + nm-route-manager.h nm-default-route-manager.c \ + nm-default-route-manager.h nm-dhcp4-config.c nm-dhcp4-config.h \ + nm-dhcp6-config.c nm-dhcp6-config.h nm-dispatcher.c \ + nm-dispatcher.h nm-enum-types.c nm-enum-types.h \ + nm-exported-object.c nm-exported-object.h \ + nm-firewall-manager.c nm-firewall-manager.h nm-ip4-config.c \ + nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h \ nm-auth-manager.c nm-auth-manager.h nm-auth-subject.c \ nm-auth-subject.h nm-auth-utils.c nm-auth-utils.h nm-manager.c \ nm-manager.h nm-multi-index.c nm-multi-index.h nm-policy.c \ nm-policy.h nm-rfkill-manager.c nm-rfkill-manager.h \ nm-session-monitor.h nm-session-monitor.c nm-sleep-monitor.c \ - nm-sleep-monitor.h nm-types.h nm-core-utils.c nm-core-utils.h \ - NetworkManagerUtils.c NetworkManagerUtils.h \ - platform/wifi/wifi-utils-wext.c \ + nm-sleep-monitor.h nm-types.h NetworkManagerUtils.c \ + NetworkManagerUtils.h platform/wifi/wifi-utils-wext.c \ platform/wifi/wifi-utils-wext.h -am__objects_1 = -@WITH_WEXT_TRUE@am__objects_2 = wifi-utils-wext.lo -am_libNetworkManager_la_OBJECTS = $(am__objects_1) $(am__objects_1) \ - nm-device.lo nm-lldp-listener.lo nm-arping-manager.lo \ +@WITH_WEXT_TRUE@am__objects_1 = wifi-utils-wext.lo +am_libNetworkManager_la_OBJECTS = nm-dhcp-dhclient-utils.lo \ + nm-checkpoint-manager.lo nm-checkpoint.lo nm-device.lo \ + nm-lldp-listener.lo nm-arping-manager.lo \ nm-device-ethernet-utils.lo nm-device-factory.lo \ nm-device-generic.lo nm-dhcp-client.lo nm-dhcp-utils.lo \ nm-dhcp-listener.lo nm-dhcp-manager.lo nm-dns-dnsmasq.lo \ nm-dns-unbound.lo nm-dns-manager.lo nm-dns-plugin.lo \ nm-dnsmasq-manager.lo nm-dnsmasq-utils.lo nmp-netns.lo \ nmp-object.lo nm-platform-utils.lo nm-platform.lo \ - nm-linux-platform.lo nm-fake-platform.lo wifi-utils-nl80211.lo \ - wifi-utils.lo nm-fake-rdisc.lo nm-lndp-rdisc.lo nm-rdisc.lo \ - nm-ppp-manager.lo nm-agent-manager.lo nm-inotify-helper.lo \ - nm-secret-agent.lo nm-settings-connection.lo \ - nm-settings-plugin.lo nm-settings.lo nm-keyfile-connection.lo \ - plugin.lo reader.lo utils.lo writer.lo nm-supplicant-config.lo \ - nm-supplicant-interface.lo nm-supplicant-manager.lo \ - nm-supplicant-settings-verify.lo nm-vpn-connection.lo \ - nm-vpn-manager.lo nm-activation-request.lo \ - nm-active-connection.lo nm-audit-manager.lo nm-bus-manager.lo \ - nm-config.lo nm-config-data.lo nm-connection-provider.lo \ - nm-connectivity.lo nm-dcb.lo nm-route-manager.lo \ - nm-default-route-manager.lo nm-dhcp4-config.lo \ - nm-dhcp6-config.lo nm-dispatcher.lo nm-enum-types.lo \ - nm-exported-object.lo nm-firewall-manager.lo nm-ip4-config.lo \ - nm-ip6-config.lo nm-logging.lo nm-auth-manager.lo \ + nm-linux-platform.lo wifi-utils-nl80211.lo wifi-utils.lo \ + nm-lndp-rdisc.lo nm-rdisc.lo nm-ppp-manager.lo \ + nm-agent-manager.lo nm-inotify-helper.lo nm-secret-agent.lo \ + nm-settings-connection.lo nm-settings-plugin.lo nm-settings.lo \ + nm-keyfile-connection.lo plugin.lo reader.lo utils.lo \ + writer.lo nm-supplicant-config.lo nm-supplicant-interface.lo \ + nm-supplicant-manager.lo nm-supplicant-settings-verify.lo \ + nm-vpn-connection.lo nm-vpn-manager.lo \ + nm-activation-request.lo nm-active-connection.lo \ + nm-audit-manager.lo nm-bus-manager.lo nm-config.lo \ + nm-config-data.lo nm-connectivity.lo nm-dcb.lo \ + nm-route-manager.lo nm-default-route-manager.lo \ + nm-dhcp4-config.lo nm-dhcp6-config.lo nm-dispatcher.lo \ + nm-enum-types.lo nm-exported-object.lo nm-firewall-manager.lo \ + nm-ip4-config.lo nm-ip6-config.lo nm-auth-manager.lo \ nm-auth-subject.lo nm-auth-utils.lo nm-manager.lo \ nm-multi-index.lo nm-policy.lo nm-rfkill-manager.lo \ - nm-session-monitor.lo nm-sleep-monitor.lo nm-core-utils.lo \ - NetworkManagerUtils.lo $(am__objects_2) + nm-session-monitor.lo nm-sleep-monitor.lo \ + NetworkManagerUtils.lo $(am__objects_1) libNetworkManager_la_OBJECTS = $(am_libNetworkManager_la_OBJECTS) +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 = +libNetworkManagerBase_la_DEPENDENCIES = \ + $(top_builddir)/libnm-core/libnm-core.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libNetworkManagerBase_la_OBJECTS = nm-core-utils.lo nm-logging.lo +libNetworkManagerBase_la_OBJECTS = \ + $(am_libNetworkManagerBase_la_OBJECTS) +libNetworkManagerTest_la_DEPENDENCIES = libNetworkManager.la +am_libNetworkManagerTest_la_OBJECTS = nm-fake-rdisc.lo \ + nm-fake-platform.lo +libNetworkManagerTest_la_OBJECTS = \ + $(am_libNetworkManagerTest_la_OBJECTS) libnm_iface_helper_la_DEPENDENCIES = \ $(top_builddir)/libnm-core/libnm-core.la \ - $(top_builddir)/introspection/libnmdbus.la libsystemd-nm.la \ + $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la libsystemd-nm.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -313,33 +300,31 @@ am__libnm_iface_helper_la_SOURCES_DIST = \ platform/wifi/wifi-utils-nl80211.c \ platform/wifi/wifi-utils-nl80211.h \ platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ - platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ - rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + platform/wifi/wifi-utils.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ nm-route-manager.c nm-route-manager.h nm-exported-object.c \ nm-exported-object.h nm-ip4-config.c nm-ip4-config.h \ nm-ip6-config.c nm-ip6-config.h nm-enum-types.c \ - nm-enum-types.h nm-logging.c nm-logging.h nm-multi-index.c \ - nm-multi-index.h nm-core-utils.c nm-core-utils.h \ + nm-enum-types.h nm-multi-index.c nm-multi-index.h \ NetworkManagerUtils.c NetworkManagerUtils.h \ platform/wifi/wifi-utils-wext.c \ platform/wifi/wifi-utils-wext.h am_libnm_iface_helper_la_OBJECTS = nm-dhcp-client.lo nm-dhcp-utils.lo \ nm-dhcp-manager.lo nmp-netns.lo nmp-object.lo \ nm-platform-utils.lo nm-platform.lo nm-linux-platform.lo \ - wifi-utils-nl80211.lo wifi-utils.lo nm-fake-rdisc.lo \ - nm-lndp-rdisc.lo nm-rdisc.lo nm-route-manager.lo \ - nm-exported-object.lo nm-ip4-config.lo nm-ip6-config.lo \ - nm-enum-types.lo nm-logging.lo nm-multi-index.lo \ - nm-core-utils.lo NetworkManagerUtils.lo $(am__objects_2) + wifi-utils-nl80211.lo wifi-utils.lo nm-lndp-rdisc.lo \ + nm-rdisc.lo nm-route-manager.lo nm-exported-object.lo \ + nm-ip4-config.lo nm-ip6-config.lo nm-enum-types.lo \ + nm-multi-index.lo NetworkManagerUtils.lo $(am__objects_1) libnm_iface_helper_la_OBJECTS = $(am_libnm_iface_helper_la_OBJECTS) libsystemd_nm_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libsystemd_nm_la_OBJECTS = libsystemd_nm_la-nm-sd.lo \ libsystemd_nm_la-nm-sd-adapt.lo libsystemd_nm_la-alloc-util.lo \ libsystemd_nm_la-escape.lo libsystemd_nm_la-ether-addr-util.lo \ - libsystemd_nm_la-fd-util.lo libsystemd_nm_la-fileio.lo \ - libsystemd_nm_la-fs-util.lo libsystemd_nm_la-hash-funcs.lo \ - libsystemd_nm_la-hashmap.lo libsystemd_nm_la-hexdecoct.lo \ + libsystemd_nm_la-extract-word.lo libsystemd_nm_la-fd-util.lo \ + libsystemd_nm_la-fileio.lo libsystemd_nm_la-fs-util.lo \ + libsystemd_nm_la-hash-funcs.lo libsystemd_nm_la-hashmap.lo \ + libsystemd_nm_la-hexdecoct.lo \ libsystemd_nm_la-hostname-util.lo \ libsystemd_nm_la-in-addr-util.lo libsystemd_nm_la-io-util.lo \ libsystemd_nm_la-mempool.lo libsystemd_nm_la-parse-util.lo \ @@ -365,21 +350,22 @@ am_libsystemd_nm_la_OBJECTS = libsystemd_nm_la-nm-sd.lo \ libsystemd_nm_la-sd-dhcp6-lease.lo \ libsystemd_nm_la-sd-ipv4acd.lo libsystemd_nm_la-sd-ipv4ll.lo \ libsystemd_nm_la-sd-lldp.lo libsystemd_nm_la-sd-event.lo \ - libsystemd_nm_la-sd-id128.lo libsystemd_nm_la-dns-domain.lo + libsystemd_nm_la-id128-util.lo libsystemd_nm_la-sd-id128.lo \ + libsystemd_nm_la-dns-domain.lo libsystemd_nm_la_OBJECTS = $(am_libsystemd_nm_la_OBJECTS) am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \ "$(DESTDIR)$(dbusservicedir)" PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS) -am__objects_3 = nm-device-bond.$(OBJEXT) nm-device-bridge.$(OBJEXT) \ +am__objects_2 = nm-device-bond.$(OBJEXT) nm-device-bridge.$(OBJEXT) \ nm-device-ethernet.$(OBJEXT) nm-device-infiniband.$(OBJEXT) \ nm-device-ip-tunnel.$(OBJEXT) nm-device-macvlan.$(OBJEXT) \ nm-device-tun.$(OBJEXT) nm-device-veth.$(OBJEXT) \ nm-device-vlan.$(OBJEXT) nm-device-vxlan.$(OBJEXT) -am__objects_4 = nm-dhcp-dhclient.$(OBJEXT) \ - nm-dhcp-dhclient-utils.$(OBJEXT) nm-dhcp-dhcpcd.$(OBJEXT) \ +am__objects_3 = +am__objects_4 = nm-dhcp-dhclient.$(OBJEXT) nm-dhcp-dhcpcd.$(OBJEXT) \ nm-dhcp-systemd.$(OBJEXT) -am_NetworkManager_OBJECTS = $(am__objects_3) $(am__objects_1) \ - $(am__objects_4) $(am__objects_1) main-utils.$(OBJEXT) \ +am_NetworkManager_OBJECTS = $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) $(am__objects_3) main-utils.$(OBJEXT) \ main.$(OBJEXT) NetworkManager_OBJECTS = $(am_NetworkManager_OBJECTS) NetworkManager_DEPENDENCIES = libNetworkManager.la @@ -391,8 +377,7 @@ am_nm_iface_helper_OBJECTS = nm-dhcp-systemd.$(OBJEXT) \ nm-iface-helper.$(OBJEXT) main-utils.$(OBJEXT) nm_iface_helper_OBJECTS = $(am_nm_iface_helper_OBJECTS) nm_iface_helper_DEPENDENCIES = \ - $(top_builddir)/libnm-core/libnm-core.la libsystemd-nm.la \ - libnm-iface-helper.la $(am__DEPENDENCIES_1) \ + $(top_builddir)/libnm-core/libnm-core.la libnm-iface-helper.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -434,12 +419,14 @@ 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 = $(libNetworkManager_base_la_SOURCES) \ - $(libNetworkManager_la_SOURCES) \ +SOURCES = $(libNetworkManager_la_SOURCES) \ + $(libNetworkManagerBase_la_SOURCES) \ + $(libNetworkManagerTest_la_SOURCES) \ $(libnm_iface_helper_la_SOURCES) $(libsystemd_nm_la_SOURCES) \ $(NetworkManager_SOURCES) $(nm_iface_helper_SOURCES) -DIST_SOURCES = $(am__libNetworkManager_base_la_SOURCES_DIST) \ - $(am__libNetworkManager_la_SOURCES_DIST) \ +DIST_SOURCES = $(am__libNetworkManager_la_SOURCES_DIST) \ + $(libNetworkManagerBase_la_SOURCES) \ + $(libNetworkManagerTest_la_SOURCES) \ $(am__libnm_iface_helper_la_SOURCES_DIST) \ $(libsystemd_nm_la_SOURCES) $(NetworkManager_SOURCES) \ $(nm_iface_helper_SOURCES) @@ -577,6 +564,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -633,13 +621,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -651,6 +640,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -711,6 +702,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -746,6 +739,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -810,49 +804,88 @@ with_valgrind = @with_valgrind@ SUBDIRS = . dhcp-manager ppp-manager settings/plugins devices/adsl \ $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) - -# add each subdirectory that contains a libNM source file. $(sort) is being used -# primarily for its side effect of removing duplicates. -AM_CPPFLAGS = -I$(top_srcdir)/shared -I$(top_builddir)/shared \ - -I$(top_builddir)/introspection -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core -I$(top_srcdir)/callouts \ - -DPREFIX=\"$(prefix)\" -DG_LOG_DOMAIN=\""NetworkManager"\" \ +AM_CPPFLAGS = \ + -I$(top_srcdir)/shared \ + -I$(top_builddir)/shared \ + -I$(top_builddir)/introspection \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + \ + $(foreach d,$(sort $(dir $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) \ + \ + -DPREFIX=\"$(prefix)\" \ + -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - $(foreach d,$(sort $(dir \ - $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) \ - $(GLIB_CFLAGS) $(GUDEV_CFLAGS) $(LIBNL_CFLAGS) \ - $(LIBNDP_CFLAGS) $(LIBSOUP_CFLAGS) $(SELINUX_CFLAGS) \ - $(LIBAUDIT_CFLAGS) $(SYSTEMD_LOGIN_CFLAGS) \ - $(SYSTEMD_JOURNAL_CFLAGS) $(SYSTEMD_NM_CFLAGS_PATHS) \ - -DBINDIR=\"$(bindir)\" -DDATADIR=\"$(datadir)\" \ + \ + -DBINDIR=\"$(bindir)\" \ + -DDATADIR=\"$(datadir)\" \ -DLIBEXECDIR=\"$(libexecdir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DRUNSTATEDIR=\"$(runstatedir)\" -DSBINDIR=\"$(sbindir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" -DRUNDIR=\"$(rundir)\" \ + -DRUNSTATEDIR=\"$(runstatedir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DRUNDIR=\"$(rundir)\" \ + \ -DNMCONFDIR=\"$(nmconfdir)\" \ -DNMLOCALEDIR=\"$(datadir)/locale\" \ - -DNMPLUGINDIR=\"$(pkglibdir)\" -DNMRUNDIR=\"$(nmrundir)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" -DNMLIBDIR=\"$(nmlibdir)\" \ + -DNMPLUGINDIR=\"$(pkglibdir)\" \ + -DNMRUNDIR=\"$(nmrundir)\" \ + -DNMSTATEDIR=\"$(nmstatedir)\" \ + -DNMLIBDIR=\"$(nmlibdir)\" \ + \ -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ - -DPPPD_PLUGIN_DIR=\"$(PPPD_PLUGIN_DIR)\" $(NULL) -noinst_LTLIBRARIES = libNetworkManager.la libnm-iface-helper.la \ - libsystemd-nm.la $(am__append_5) - -###################### -# libsystemd-nm -###################### -SYSTEMD_NM_CFLAGS_PATHS = \ - -I$(top_srcdir)/src/systemd/src/systemd \ - -I$(top_srcdir)/src/systemd/src/libsystemd-network \ - -I$(top_srcdir)/src/systemd/src/basic \ - -I$(top_srcdir)/src/systemd + -DPPPD_PLUGIN_DIR=\"$(PPPD_PLUGIN_DIR)\" \ + \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(LIBNDP_CFLAGS) \ + $(LIBSOUP_CFLAGS) \ + $(SELINUX_CFLAGS) \ + $(LIBAUDIT_CFLAGS) \ + $(SYSTEMD_LOGIN_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) \ + \ + -I$(top_srcdir)/src/systemd/src/systemd/ \ + -I$(top_srcdir)/src/systemd/ \ + \ + $(NULL) + +AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) +noinst_LTLIBRARIES = \ + libNetworkManagerBase.la \ + libNetworkManager.la \ + libNetworkManagerTest.la \ + libnm-iface-helper.la \ + libsystemd-nm.la + +############################################################################### libsystemd_nm_la_SOURCES = \ systemd/nm-sd.c \ systemd/nm-sd.h \ - systemd/nm-sd-adapt.c \ - systemd/nm-sd-adapt.h \ + systemd/sd-adapt/nm-sd-adapt.c \ + systemd/sd-adapt/nm-sd-adapt.h \ + systemd/sd-adapt/build.h \ + systemd/sd-adapt/cgroup-util.h \ + systemd/sd-adapt/condition.h \ + systemd/sd-adapt/conf-parser.h \ + systemd/sd-adapt/def.h \ + systemd/sd-adapt/dirent-util.h \ + systemd/sd-adapt/formats-util.h \ + systemd/sd-adapt/gunicode.h \ + systemd/sd-adapt/libudev.h \ + systemd/sd-adapt/missing.h \ + systemd/sd-adapt/mkdir.h \ + systemd/sd-adapt/process-util.h \ + systemd/sd-adapt/sd-daemon.h \ + systemd/sd-adapt/stat-util.h \ + systemd/sd-adapt/udev-util.h \ + systemd/sd-adapt/udev.h \ + systemd/sd-adapt/user-util.h \ + systemd/sd-adapt/virt.h \ systemd/src/basic/alloc-util.c \ systemd/src/basic/alloc-util.h \ systemd/src/basic/async.h \ @@ -860,6 +893,8 @@ libsystemd_nm_la_SOURCES = \ systemd/src/basic/escape.h \ systemd/src/basic/ether-addr-util.c \ systemd/src/basic/ether-addr-util.h \ + systemd/src/basic/extract-word.c \ + systemd/src/basic/extract-word.h \ systemd/src/basic/fd-util.c \ systemd/src/basic/fd-util.h \ systemd/src/basic/fileio.c \ @@ -893,6 +928,7 @@ libsystemd_nm_la_SOURCES = \ systemd/src/basic/random-util.h \ systemd/src/basic/refcnt.h \ systemd/src/basic/set.h \ + systemd/src/basic/signal-util.h \ systemd/src/basic/siphash24.c \ systemd/src/basic/siphash24.h \ systemd/src/basic/socket-util.c \ @@ -943,6 +979,8 @@ libsystemd_nm_la_SOURCES = \ systemd/src/libsystemd-network/sd-ipv4ll.c \ systemd/src/libsystemd-network/sd-lldp.c \ systemd/src/libsystemd/sd-event/sd-event.c \ + systemd/src/libsystemd/sd-id128/id128-util.c \ + systemd/src/libsystemd/sd-id128/id128-util.h \ systemd/src/libsystemd/sd-id128/sd-id128.c \ systemd/src/shared/dns-domain.c \ systemd/src/shared/dns-domain.h \ @@ -959,49 +997,41 @@ libsystemd_nm_la_SOURCES = \ systemd/src/systemd/sd-ndisc.h libsystemd_nm_la_CPPFLAGS = \ - -I$(top_srcdir)/shared \ - -I$(top_builddir)/shared \ + -I$(top_srcdir)/shared/ \ + -I$(top_builddir)/shared/ \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ - $(SYSTEMD_NM_CFLAGS_PATHS) \ - -I$(top_srcdir)/src/systemd/src/shared \ + -I$(top_srcdir)/src/systemd/sd-adapt/ \ + -I$(top_srcdir)/src/systemd/src/systemd/ \ + -I$(top_srcdir)/src/systemd/src/basic/ \ + -I$(top_srcdir)/src/systemd/src/shared/ \ + -I$(top_srcdir)/src/systemd/src/libsystemd-network/ \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_SYSTEMD \ $(GLIB_CFLAGS) libsystemd_nm_la_LIBADD = \ $(GLIB_LIBS) -@ENABLE_TESTS_TRUE@libNetworkManager_base_la_SOURCES = \ -@ENABLE_TESTS_TRUE@ nm-core-utils.c \ -@ENABLE_TESTS_TRUE@ nm-core-utils.h \ -@ENABLE_TESTS_TRUE@ nm-logging.c \ -@ENABLE_TESTS_TRUE@ nm-logging.h - -@ENABLE_TESTS_TRUE@libNetworkManager_base_la_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/shared \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/shared \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/platform \ -@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ -@ENABLE_TESTS_TRUE@ -DNO_SYSTEMD_JOURNAL \ -@ENABLE_TESTS_TRUE@ -DPREFIX=\"$(prefix)\" \ -@ENABLE_TESTS_TRUE@ -DLOCALSTATEDIR=\"$(localstatedir)\" \ -@ENABLE_TESTS_TRUE@ -DNMSTATEDIR=\"$(nmstatedir)\" \ -@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) - -@ENABLE_TESTS_TRUE@libNetworkManager_base_la_LIBADD = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ -@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) -NetworkManager_SOURCES = \ - $(nm_device_sources) $(nm_device_headers) \ - $(nm_dhcp_client_sources) $(nm_dhcp_client_headers) \ - main-utils.c \ - main-utils.h \ - main.c +############################################################################### +libNetworkManagerBase_la_SOURCES = \ + nm-core-utils.c \ + nm-core-utils.h \ + nm-logging.c \ + nm-logging.h + +libNetworkManagerBase_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + $(GLIB_LIBS) \ + $(SYSTEMD_JOURNAL_LIBS) \ + $(NULL) + + +############################################################################### -NetworkManager_LDADD = libNetworkManager.la +# These source files have a attribute((constructor)) to register their factories. +# This gets stripped out from the resulting binary if we add them to libNetworkManager.la. +# Instead, add them to the binary. An alternative would be to link with --as-needed. nm_device_sources = \ devices/nm-device-bond.c \ devices/nm-device-bridge.c \ @@ -1025,25 +1055,30 @@ nm_device_headers = \ devices/nm-device-tun.h \ devices/nm-device-veth.h \ devices/nm-device-vlan.h \ - devices/nm-device-vxlan.h + devices/nm-device-vxlan.h \ + $(NULL) nm_dhcp_client_sources = \ dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhclient-utils.c \ dhcp-manager/nm-dhcp-dhcpcd.c \ - dhcp-manager/nm-dhcp-systemd.c + dhcp-manager/nm-dhcp-systemd.c \ + $(NULL) nm_dhcp_client_headers = \ dhcp-manager/nm-dhcp-dhclient.h \ - dhcp-manager/nm-dhcp-dhclient-utils.h \ dhcp-manager/nm-dhcp-dhcpcd.h \ - dhcp-manager/nm-dhcp-systemd.h + dhcp-manager/nm-dhcp-systemd.h \ + $(NULL) -libNetworkManager_la_SOURCES = $(nm_device_headers) \ - $(nm_dhcp_client_headers) devices/nm-device.c \ - devices/nm-device.h devices/nm-lldp-listener.c \ - devices/nm-lldp-listener.h devices/nm-arping-manager.c \ - devices/nm-arping-manager.h devices/nm-device-ethernet-utils.c \ + +############################################################################### +libNetworkManager_la_SOURCES = dhcp-manager/nm-dhcp-dhclient-utils.c \ + dhcp-manager/nm-dhcp-dhclient-utils.h nm-checkpoint-manager.c \ + nm-checkpoint-manager.h nm-checkpoint.c nm-checkpoint.h \ + devices/nm-device.c devices/nm-device.h \ + devices/nm-lldp-listener.c devices/nm-lldp-listener.h \ + devices/nm-arping-manager.c devices/nm-arping-manager.h \ + devices/nm-device-ethernet-utils.c \ devices/nm-device-ethernet-utils.h devices/nm-device-factory.c \ devices/nm-device-factory.h devices/nm-device-generic.c \ devices/nm-device-generic.h devices/nm-device-logging.h \ @@ -1066,12 +1101,11 @@ libNetworkManager_la_SOURCES = $(nm_device_headers) \ platform/nmp-object.h platform/nm-platform-utils.c \ platform/nm-platform-utils.h platform/nm-platform.c \ platform/nm-platform.h platform/nm-linux-platform.c \ - platform/nm-linux-platform.h platform/nm-fake-platform.c \ - platform/nm-fake-platform.h platform/wifi/wifi-utils-nl80211.c \ + platform/nm-linux-platform.h \ + platform/wifi/wifi-utils-nl80211.c \ platform/wifi/wifi-utils-nl80211.h \ platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ - platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ - rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + platform/wifi/wifi-utils.h rdisc/nm-lndp-rdisc.c \ 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 ppp-manager/nm-ppp-status.h \ @@ -1107,47 +1141,63 @@ libNetworkManager_la_SOURCES = $(nm_device_headers) \ nm-activation-request.h nm-active-connection.c \ nm-active-connection.h nm-audit-manager.c nm-audit-manager.h \ nm-bus-manager.c nm-bus-manager.h nm-config.c nm-config.h \ - nm-config-data.c nm-config-data.h nm-connection-provider.c \ - nm-connection-provider.h nm-connectivity.c nm-connectivity.h \ - nm-dcb.c nm-dcb.h nm-route-manager.c nm-route-manager.h \ - nm-default-route-manager.c nm-default-route-manager.h \ - nm-dhcp4-config.c nm-dhcp4-config.h nm-dhcp6-config.c \ - nm-dhcp6-config.h nm-dispatcher.c nm-dispatcher.h \ - nm-enum-types.c nm-enum-types.h nm-exported-object.c \ - nm-exported-object.h nm-firewall-manager.c \ - nm-firewall-manager.h nm-ip4-config.c nm-ip4-config.h \ - nm-ip6-config.c nm-ip6-config.h nm-logging.c nm-logging.h \ + nm-config-data.c nm-config-data.h nm-connectivity.c \ + nm-connectivity.h nm-dcb.c nm-dcb.h nm-route-manager.c \ + nm-route-manager.h nm-default-route-manager.c \ + nm-default-route-manager.h nm-dhcp4-config.c nm-dhcp4-config.h \ + nm-dhcp6-config.c nm-dhcp6-config.h nm-dispatcher.c \ + nm-dispatcher.h nm-enum-types.c nm-enum-types.h \ + nm-exported-object.c nm-exported-object.h \ + nm-firewall-manager.c nm-firewall-manager.h nm-ip4-config.c \ + nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h \ nm-auth-manager.c nm-auth-manager.h nm-auth-subject.c \ nm-auth-subject.h nm-auth-utils.c nm-auth-utils.h nm-manager.c \ nm-manager.h nm-multi-index.c nm-multi-index.h nm-policy.c \ nm-policy.h nm-rfkill-manager.c nm-rfkill-manager.h \ nm-session-monitor.h nm-session-monitor.c nm-sleep-monitor.c \ - nm-sleep-monitor.h nm-types.h nm-core-utils.c nm-core-utils.h \ - NetworkManagerUtils.c NetworkManagerUtils.h $(am__append_6) -GLIB_GENERATED = nm-enum-types.h nm-enum-types.c -GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include <nm-core-enum-types.h>\n' -GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_enum_types_sources = $(filter-out \ - %/nm-device-private.h \ - %/nm-rdisc-private.h \ - %/wifi-utils-private.h \ - %/nm-dhcp-client-logging.h \ - %/nm-device-logging.h \ - , $(libNetworkManager_la_SOURCES)) - -BUILT_SOURCES = $(GLIB_GENERATED) + nm-sleep-monitor.h nm-types.h NetworkManagerUtils.c \ + NetworkManagerUtils.h $(NULL) $(am__append_5) libNetworkManager_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ - $(top_builddir)/introspection/libnmdbus.la libsystemd-nm.la \ - $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(SYSTEMD_LOGIN_LIBS) \ - $(SYSTEMD_JOURNAL_LIBS) $(LIBNDP_LIBS) $(LIBDL) $(LIBM) \ - $(SELINUX_LIBS) $(LIBAUDIT_LIBS) $(am__append_7) + $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la libsystemd-nm.la $(GLIB_LIBS) \ + $(GUDEV_LIBS) $(LIBNL_LIBS) $(SYSTEMD_LOGIN_LIBS) \ + $(LIBNDP_LIBS) $(DL_LIBS) $(LIBM) $(SELINUX_LIBS) \ + $(LIBAUDIT_LIBS) $(am__append_6) + +############################################################################### +libNetworkManagerTest_la_SOURCES = \ + rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h \ + platform/nm-fake-platform.c \ + platform/nm-fake-platform.h + +libNetworkManagerTest_la_LIBADD = \ + libNetworkManager.la + + +############################################################################### +NetworkManager_SOURCES = \ + \ + $(nm_device_sources) \ + $(nm_device_headers) \ + \ + $(nm_dhcp_client_sources) \ + $(nm_dhcp_client_headers) \ + \ + main-utils.c \ + main-utils.h \ + main.c + +NetworkManager_LDADD = \ + libNetworkManager.la + NetworkManager_LDFLAGS = \ -rdynamic \ -Wl,--version-script="$(srcdir)/NetworkManager.ver" -###################### +############################################################################### libnm_iface_helper_la_SOURCES = dhcp-manager/nm-dhcp-client.c \ dhcp-manager/nm-dhcp-client.h \ dhcp-manager/nm-dhcp-client-logging.h \ @@ -1161,24 +1211,23 @@ libnm_iface_helper_la_SOURCES = dhcp-manager/nm-dhcp-client.c \ platform/wifi/wifi-utils-nl80211.c \ platform/wifi/wifi-utils-nl80211.h \ platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ - platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ - rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + platform/wifi/wifi-utils.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ nm-route-manager.c nm-route-manager.h nm-exported-object.c \ nm-exported-object.h nm-ip4-config.c nm-ip4-config.h \ nm-ip6-config.c nm-ip6-config.h nm-enum-types.c \ - nm-enum-types.h nm-logging.c nm-logging.h nm-multi-index.c \ - nm-multi-index.h nm-core-utils.c nm-core-utils.h \ - NetworkManagerUtils.c NetworkManagerUtils.h $(am__append_8) + nm-enum-types.h nm-multi-index.c nm-multi-index.h \ + NetworkManagerUtils.c NetworkManagerUtils.h $(am__append_7) libnm_iface_helper_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ $(top_builddir)/introspection/libnmdbus.la \ + libNetworkManagerBase.la \ libsystemd-nm.la \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ $(LIBNDP_LIBS) \ - $(LIBDL) \ + $(DL_LIBS) \ $(LIBM) nm_iface_helper_SOURCES = \ @@ -1190,23 +1239,38 @@ nm_iface_helper_SOURCES = \ nm_iface_helper_LDADD = \ $(top_builddir)/libnm-core/libnm-core.la \ - libsystemd-nm.la \ libnm-iface-helper.la \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ - $(SYSTEMD_JOURNAL_LIBS) \ $(LIBNL_LIBS) \ $(LIBNDP_LIBS) \ $(LIBM) -nm_iface_helper_LDFLAGS = -rdynamic +nm_iface_helper_LDFLAGS = \ + -rdynamic + -###################### +############################################################################### +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include <nm-core-enum-types.h>\n' +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' +nm_enum_types_sources = $(filter-out \ + %/nm-device-private.h \ + %/nm-rdisc-private.h \ + %/wifi-utils-private.h \ + %/nm-dhcp-client-logging.h \ + %/nm-device-logging.h \ + , $(libNetworkManager_la_SOURCES)) + +BUILT_SOURCES = $(GLIB_GENERATED) + +############################################################################### dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = org.freedesktop.NetworkManager.conf EXTRA_DIST = \ $(dbusservice_DATA) \ $(NetworkManager_DATA) \ + nm-test-utils-core.h \ NetworkManager.ver rundir = $(runstatedir)/NetworkManager @@ -1260,12 +1324,15 @@ clean-noinstLTLIBRARIES: rm -f $${locs}; \ } -libNetworkManager-base.la: $(libNetworkManager_base_la_OBJECTS) $(libNetworkManager_base_la_DEPENDENCIES) $(EXTRA_libNetworkManager_base_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libNetworkManager_base_la_rpath) $(libNetworkManager_base_la_OBJECTS) $(libNetworkManager_base_la_LIBADD) $(LIBS) - libNetworkManager.la: $(libNetworkManager_la_OBJECTS) $(libNetworkManager_la_DEPENDENCIES) $(EXTRA_libNetworkManager_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libNetworkManager_la_OBJECTS) $(libNetworkManager_la_LIBADD) $(LIBS) +libNetworkManagerBase.la: $(libNetworkManagerBase_la_OBJECTS) $(libNetworkManagerBase_la_DEPENDENCIES) $(EXTRA_libNetworkManagerBase_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libNetworkManagerBase_la_OBJECTS) $(libNetworkManagerBase_la_LIBADD) $(LIBS) + +libNetworkManagerTest.la: $(libNetworkManagerTest_la_OBJECTS) $(libNetworkManagerTest_la_DEPENDENCIES) $(EXTRA_libNetworkManagerTest_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libNetworkManagerTest_la_OBJECTS) $(libNetworkManagerTest_la_LIBADD) $(LIBS) + libnm-iface-helper.la: $(libnm_iface_helper_la_OBJECTS) $(libnm_iface_helper_la_DEPENDENCIES) $(EXTRA_libnm_iface_helper_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libnm_iface_helper_la_OBJECTS) $(libnm_iface_helper_la_LIBADD) $(LIBS) @@ -1385,8 +1452,6 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManagerUtils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libNetworkManager_base_la-nm-core-utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libNetworkManager_base_la-nm-logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-alloc-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-arp-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-dhcp-identifier.Plo@am__quote@ @@ -1398,6 +1463,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-dns-domain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-escape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-ether-addr-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-extract-word.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-fd-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-fileio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-fs-util.Plo@am__quote@ @@ -1405,6 +1471,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-hashmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-hexdecoct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-hostname-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-id128-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-in-addr-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-io-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_nm_la-lldp-neighbor.Plo@am__quote@ @@ -1445,9 +1512,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-auth-subject.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-auth-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bus-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-checkpoint-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-checkpoint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-config-data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connection-provider.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connectivity.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-core-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dcb.Plo@am__quote@ @@ -1467,7 +1535,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vxlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhcpcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-listener.Plo@am__quote@ @@ -1549,19 +1617,12 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libNetworkManager_base_la-nm-core-utils.lo: nm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libNetworkManager_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libNetworkManager_base_la-nm-core-utils.lo -MD -MP -MF $(DEPDIR)/libNetworkManager_base_la-nm-core-utils.Tpo -c -o libNetworkManager_base_la-nm-core-utils.lo `test -f 'nm-core-utils.c' || echo '$(srcdir)/'`nm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libNetworkManager_base_la-nm-core-utils.Tpo $(DEPDIR)/libNetworkManager_base_la-nm-core-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-core-utils.c' object='libNetworkManager_base_la-nm-core-utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libNetworkManager_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libNetworkManager_base_la-nm-core-utils.lo `test -f 'nm-core-utils.c' || echo '$(srcdir)/'`nm-core-utils.c - -libNetworkManager_base_la-nm-logging.lo: nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libNetworkManager_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libNetworkManager_base_la-nm-logging.lo -MD -MP -MF $(DEPDIR)/libNetworkManager_base_la-nm-logging.Tpo -c -o libNetworkManager_base_la-nm-logging.lo `test -f 'nm-logging.c' || echo '$(srcdir)/'`nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libNetworkManager_base_la-nm-logging.Tpo $(DEPDIR)/libNetworkManager_base_la-nm-logging.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-logging.c' object='libNetworkManager_base_la-nm-logging.lo' libtool=yes @AMDEPBACKSLASH@ +nm-dhcp-dhclient-utils.lo: dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.lo `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libNetworkManager_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libNetworkManager_base_la-nm-logging.lo `test -f 'nm-logging.c' || echo '$(srcdir)/'`nm-logging.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.lo `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c nm-device.lo: devices/nm-device.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device.lo -MD -MP -MF $(DEPDIR)/nm-device.Tpo -c -o nm-device.lo `test -f 'devices/nm-device.c' || echo '$(srcdir)/'`devices/nm-device.c @@ -1710,13 +1771,6 @@ nm-linux-platform.lo: platform/nm-linux-platform.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-linux-platform.lo `test -f 'platform/nm-linux-platform.c' || echo '$(srcdir)/'`platform/nm-linux-platform.c -nm-fake-platform.lo: platform/nm-fake-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-fake-platform.lo -MD -MP -MF $(DEPDIR)/nm-fake-platform.Tpo -c -o nm-fake-platform.lo `test -f 'platform/nm-fake-platform.c' || echo '$(srcdir)/'`platform/nm-fake-platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-fake-platform.Tpo $(DEPDIR)/nm-fake-platform.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='platform/nm-fake-platform.c' object='nm-fake-platform.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-fake-platform.lo `test -f 'platform/nm-fake-platform.c' || echo '$(srcdir)/'`platform/nm-fake-platform.c - wifi-utils-nl80211.lo: platform/wifi/wifi-utils-nl80211.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wifi-utils-nl80211.lo -MD -MP -MF $(DEPDIR)/wifi-utils-nl80211.Tpo -c -o wifi-utils-nl80211.lo `test -f 'platform/wifi/wifi-utils-nl80211.c' || echo '$(srcdir)/'`platform/wifi/wifi-utils-nl80211.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/wifi-utils-nl80211.Tpo $(DEPDIR)/wifi-utils-nl80211.Plo @@ -1731,13 +1785,6 @@ wifi-utils.lo: platform/wifi/wifi-utils.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wifi-utils.lo `test -f 'platform/wifi/wifi-utils.c' || echo '$(srcdir)/'`platform/wifi/wifi-utils.c -nm-fake-rdisc.lo: rdisc/nm-fake-rdisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-fake-rdisc.lo -MD -MP -MF $(DEPDIR)/nm-fake-rdisc.Tpo -c -o nm-fake-rdisc.lo `test -f 'rdisc/nm-fake-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-fake-rdisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-fake-rdisc.Tpo $(DEPDIR)/nm-fake-rdisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rdisc/nm-fake-rdisc.c' object='nm-fake-rdisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-fake-rdisc.lo `test -f 'rdisc/nm-fake-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-fake-rdisc.c - nm-lndp-rdisc.lo: rdisc/nm-lndp-rdisc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-lndp-rdisc.lo -MD -MP -MF $(DEPDIR)/nm-lndp-rdisc.Tpo -c -o nm-lndp-rdisc.lo `test -f 'rdisc/nm-lndp-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-lndp-rdisc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-lndp-rdisc.Tpo $(DEPDIR)/nm-lndp-rdisc.Plo @@ -1885,6 +1932,20 @@ wifi-utils-wext.lo: platform/wifi/wifi-utils-wext.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wifi-utils-wext.lo `test -f 'platform/wifi/wifi-utils-wext.c' || echo '$(srcdir)/'`platform/wifi/wifi-utils-wext.c +nm-fake-rdisc.lo: rdisc/nm-fake-rdisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-fake-rdisc.lo -MD -MP -MF $(DEPDIR)/nm-fake-rdisc.Tpo -c -o nm-fake-rdisc.lo `test -f 'rdisc/nm-fake-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-fake-rdisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-fake-rdisc.Tpo $(DEPDIR)/nm-fake-rdisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rdisc/nm-fake-rdisc.c' object='nm-fake-rdisc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-fake-rdisc.lo `test -f 'rdisc/nm-fake-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-fake-rdisc.c + +nm-fake-platform.lo: platform/nm-fake-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-fake-platform.lo -MD -MP -MF $(DEPDIR)/nm-fake-platform.Tpo -c -o nm-fake-platform.lo `test -f 'platform/nm-fake-platform.c' || echo '$(srcdir)/'`platform/nm-fake-platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-fake-platform.Tpo $(DEPDIR)/nm-fake-platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='platform/nm-fake-platform.c' object='nm-fake-platform.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-fake-platform.lo `test -f 'platform/nm-fake-platform.c' || echo '$(srcdir)/'`platform/nm-fake-platform.c + libsystemd_nm_la-nm-sd.lo: systemd/nm-sd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-nm-sd.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-nm-sd.Tpo -c -o libsystemd_nm_la-nm-sd.lo `test -f 'systemd/nm-sd.c' || echo '$(srcdir)/'`systemd/nm-sd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-nm-sd.Tpo $(DEPDIR)/libsystemd_nm_la-nm-sd.Plo @@ -1892,12 +1953,12 @@ libsystemd_nm_la-nm-sd.lo: systemd/nm-sd.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-nm-sd.lo `test -f 'systemd/nm-sd.c' || echo '$(srcdir)/'`systemd/nm-sd.c -libsystemd_nm_la-nm-sd-adapt.lo: systemd/nm-sd-adapt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-nm-sd-adapt.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-nm-sd-adapt.Tpo -c -o libsystemd_nm_la-nm-sd-adapt.lo `test -f 'systemd/nm-sd-adapt.c' || echo '$(srcdir)/'`systemd/nm-sd-adapt.c +libsystemd_nm_la-nm-sd-adapt.lo: systemd/sd-adapt/nm-sd-adapt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-nm-sd-adapt.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-nm-sd-adapt.Tpo -c -o libsystemd_nm_la-nm-sd-adapt.lo `test -f 'systemd/sd-adapt/nm-sd-adapt.c' || echo '$(srcdir)/'`systemd/sd-adapt/nm-sd-adapt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-nm-sd-adapt.Tpo $(DEPDIR)/libsystemd_nm_la-nm-sd-adapt.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='systemd/nm-sd-adapt.c' object='libsystemd_nm_la-nm-sd-adapt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='systemd/sd-adapt/nm-sd-adapt.c' object='libsystemd_nm_la-nm-sd-adapt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-nm-sd-adapt.lo `test -f 'systemd/nm-sd-adapt.c' || echo '$(srcdir)/'`systemd/nm-sd-adapt.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-nm-sd-adapt.lo `test -f 'systemd/sd-adapt/nm-sd-adapt.c' || echo '$(srcdir)/'`systemd/sd-adapt/nm-sd-adapt.c libsystemd_nm_la-alloc-util.lo: systemd/src/basic/alloc-util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-alloc-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-alloc-util.Tpo -c -o libsystemd_nm_la-alloc-util.lo `test -f 'systemd/src/basic/alloc-util.c' || echo '$(srcdir)/'`systemd/src/basic/alloc-util.c @@ -1920,6 +1981,13 @@ libsystemd_nm_la-ether-addr-util.lo: systemd/src/basic/ether-addr-util.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-ether-addr-util.lo `test -f 'systemd/src/basic/ether-addr-util.c' || echo '$(srcdir)/'`systemd/src/basic/ether-addr-util.c +libsystemd_nm_la-extract-word.lo: systemd/src/basic/extract-word.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-extract-word.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-extract-word.Tpo -c -o libsystemd_nm_la-extract-word.lo `test -f 'systemd/src/basic/extract-word.c' || echo '$(srcdir)/'`systemd/src/basic/extract-word.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-extract-word.Tpo $(DEPDIR)/libsystemd_nm_la-extract-word.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='systemd/src/basic/extract-word.c' object='libsystemd_nm_la-extract-word.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-extract-word.lo `test -f 'systemd/src/basic/extract-word.c' || echo '$(srcdir)/'`systemd/src/basic/extract-word.c + libsystemd_nm_la-fd-util.lo: systemd/src/basic/fd-util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-fd-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-fd-util.Tpo -c -o libsystemd_nm_la-fd-util.lo `test -f 'systemd/src/basic/fd-util.c' || echo '$(srcdir)/'`systemd/src/basic/fd-util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-fd-util.Tpo $(DEPDIR)/libsystemd_nm_la-fd-util.Plo @@ -2200,6 +2268,13 @@ libsystemd_nm_la-sd-event.lo: systemd/src/libsystemd/sd-event/sd-event.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-sd-event.lo `test -f 'systemd/src/libsystemd/sd-event/sd-event.c' || echo '$(srcdir)/'`systemd/src/libsystemd/sd-event/sd-event.c +libsystemd_nm_la-id128-util.lo: systemd/src/libsystemd/sd-id128/id128-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-id128-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-id128-util.Tpo -c -o libsystemd_nm_la-id128-util.lo `test -f 'systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`systemd/src/libsystemd/sd-id128/id128-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-id128-util.Tpo $(DEPDIR)/libsystemd_nm_la-id128-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='systemd/src/libsystemd/sd-id128/id128-util.c' object='libsystemd_nm_la-id128-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_nm_la-id128-util.lo `test -f 'systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`systemd/src/libsystemd/sd-id128/id128-util.c + libsystemd_nm_la-sd-id128.lo: systemd/src/libsystemd/sd-id128/sd-id128.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_nm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_nm_la-sd-id128.lo -MD -MP -MF $(DEPDIR)/libsystemd_nm_la-sd-id128.Tpo -c -o libsystemd_nm_la-sd-id128.lo `test -f 'systemd/src/libsystemd/sd-id128/sd-id128.c' || echo '$(srcdir)/'`systemd/src/libsystemd/sd-id128/sd-id128.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_nm_la-sd-id128.Tpo $(DEPDIR)/libsystemd_nm_la-sd-id128.Plo @@ -2368,20 +2443,6 @@ nm-dhcp-dhclient.obj: dhcp-manager/nm-dhcp-dhclient.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient.c'; fi` -nm-dhcp-dhclient-utils.o: dhcp-manager/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.o `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.o `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c - -nm-dhcp-dhclient-utils.obj: dhcp-manager/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` - nm-dhcp-dhcpcd.o: dhcp-manager/nm-dhcp-dhcpcd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhcpcd.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhcpcd.Tpo -c -o nm-dhcp-dhcpcd.o `test -f 'dhcp-manager/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhcpcd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhcpcd.Tpo $(DEPDIR)/nm-dhcp-dhcpcd.Po diff --git a/src/NetworkManager.ver b/src/NetworkManager.ver index b4397b9c..c91affcb 100644 --- a/src/NetworkManager.ver +++ b/src/NetworkManager.ver @@ -1,6 +1,7 @@ { global: - nm*; + nm_*; + nmp_*; _nm*; NM*; _NM*; diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 9894872b..7eb6cf16 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -529,8 +529,8 @@ check_connection_mac_address (NMConnection *orig, static gboolean check_connection_cloned_mac_address (NMConnection *orig, - NMConnection *candidate, - GHashTable *settings) + NMConnection *candidate, + GHashTable *settings) { GHashTable *props; const char *orig_mac = NULL, *cand_mac = NULL; @@ -551,6 +551,12 @@ check_connection_cloned_mac_address (NMConnection *orig, if (s_wired_cand) cand_mac = nm_setting_wired_get_cloned_mac_address (s_wired_cand); + /* special cloned mac address entires are accepted. */ + if (NM_CLONED_MAC_IS_SPECIAL (orig_mac)) + orig_mac = NULL; + if (NM_CLONED_MAC_IS_SPECIAL (cand_mac)) + cand_mac = NULL; + if (!orig_mac || !cand_mac) { remove_from_hash (settings, props, NM_SETTING_WIRED_SETTING_NAME, diff --git a/src/devices/Makefile.in b/src/devices/Makefile.in index d6848e53..4791015d 100644 --- a/src/devices/Makefile.in +++ b/src/devices/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/devices ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -225,6 +226,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -281,13 +283,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -299,6 +302,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -359,6 +364,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -394,6 +401,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/devices/adsl/Makefile.am b/src/devices/adsl/Makefile.am index 5f981740..9075021c 100644 --- a/src/devices/adsl/Makefile.am +++ b/src/devices/adsl/Makefile.am @@ -40,6 +40,7 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-adsl.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-adsl.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/adsl/Makefile.in b/src/devices/adsl/Makefile.in index b6805537..f3fbad4c 100644 --- a/src/devices/adsl/Makefile.in +++ b/src/devices/adsl/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/devices/adsl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -252,6 +253,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -308,13 +310,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -326,6 +329,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -386,6 +391,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -421,6 +428,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -838,6 +846,7 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-adsl.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-adsl.so $(top_builddir)/src/NetworkManager --version >/dev/null # 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/adsl/nm-atm-manager.h b/src/devices/adsl/nm-atm-manager.h index fe0bc14c..bcbc6c77 100644 --- a/src/devices/adsl/nm-atm-manager.h +++ b/src/devices/adsl/nm-atm-manager.h @@ -22,10 +22,6 @@ #ifndef __NETWORKMANAGER_ATM_MANAGER_H__ #define __NETWORKMANAGER_ATM_MANAGER_H__ -#include "nm-default.h" - -G_BEGIN_DECLS - #define NM_TYPE_ATM_MANAGER (nm_atm_manager_get_type ()) #define NM_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ATM_MANAGER, NMAtmManager)) diff --git a/src/devices/adsl/nm-device-adsl.h b/src/devices/adsl/nm-device-adsl.h index efcdaf69..cfde2b35 100644 --- a/src/devices/adsl/nm-device-adsl.h +++ b/src/devices/adsl/nm-device-adsl.h @@ -23,11 +23,8 @@ #define __NETWORKMANAGER_DEVICE_ADSL_H__ // Parent class -#include "nm-default.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_ADSL (nm_device_adsl_get_type ()) #define NM_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdsl)) #define NM_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) @@ -52,6 +49,4 @@ NMDevice *nm_device_adsl_new (const char *udi, const char *driver, int atm_index); -G_END_DECLS - -#endif /* NM_DEVICE_ADSL_H */ +#endif /* NM_DEVICE_ADSL_H */ diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am index 2ff9a572..8454702e 100644 --- a/src/devices/bluetooth/Makefile.am +++ b/src/devices/bluetooth/Makefile.am @@ -76,6 +76,7 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-bluetooth.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-bluetooth.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in index d2b0b865..c010f4c7 100644 --- a/src/devices/bluetooth/Makefile.in +++ b/src/devices/bluetooth/Makefile.in @@ -96,8 +96,9 @@ host_triplet = @host@ @WITH_BLUEZ5_DUN_TRUE@am__append_3 = $(BLUEZ5_LIBS) subdir = src/devices/bluetooth ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -273,6 +274,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -329,13 +331,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -347,6 +350,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -407,6 +412,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -442,6 +449,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -872,6 +880,7 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-bluetooth.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-bluetooth.so $(top_builddir)/src/NetworkManager --version >/dev/null # 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/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index dcfa5eec..3463da6b 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -28,6 +28,7 @@ #include "nm-bt-error.h" #include "nm-bluez-common.h" #include "nm-bluez-device.h" +#include "nm-settings.h" #include "nm-settings-connection.h" #include "NetworkManagerUtils.h" @@ -67,7 +68,7 @@ typedef struct { NMBluez5DunContext *b5_dun_context; #endif - NMConnectionProvider *provider; + NMSettings *settings; GSList *connections; NMConnection *pan_connection; @@ -96,7 +97,7 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static void cp_connection_added (NMConnectionProvider *provider, +static void cp_connection_added (NMSettings *settings, NMConnection *connection, NMBluezDevice *self); static gboolean connection_compatible (NMBluezDevice *self, NMConnection *connection); @@ -233,9 +234,9 @@ pan_connection_check_create (NMBluezDevice *self) /* Adding a new connection raises a signal which eventually calls check_emit_usable (again) * which then already finds the suitable connection in priv->connections. This is confusing, * so block the signal. check_emit_usable will succeed after this function call returns. */ - g_signal_handlers_block_by_func (priv->provider, cp_connection_added, self); - added = nm_connection_provider_add_connection (priv->provider, connection, FALSE, &error); - g_signal_handlers_unblock_by_func (priv->provider, cp_connection_added, self); + g_signal_handlers_block_by_func (priv->settings, cp_connection_added, self); + added = NM_CONNECTION (nm_settings_add_connection (priv->settings, connection, FALSE, &error)); + g_signal_handlers_unblock_by_func (priv->settings, cp_connection_added, self); if (added) { g_assert (!g_slist_find (priv->connections, added)); @@ -367,7 +368,7 @@ _internal_track_connection (NMBluezDevice *self, NMConnection *connection, gbool } static void -cp_connection_added (NMConnectionProvider *provider, +cp_connection_added (NMSettings *settings, NMConnection *connection, NMBluezDevice *self) { @@ -378,7 +379,7 @@ cp_connection_added (NMConnectionProvider *provider, } static void -cp_connection_removed (NMConnectionProvider *provider, +cp_connection_removed (NMSettings *settings, NMConnection *connection, NMBluezDevice *self) { @@ -387,8 +388,9 @@ cp_connection_removed (NMConnectionProvider *provider, } static void -cp_connection_updated (NMConnectionProvider *provider, +cp_connection_updated (NMSettings *settings, NMConnection *connection, + gboolean by_user, NMBluezDevice *self) { if (_internal_track_connection (self, connection, @@ -400,12 +402,13 @@ static void load_connections (NMBluezDevice *self) { NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - const GSList *connections, *iter; + NMSettingsConnection *const*connections; + guint i; gboolean changed = FALSE; - connections = nm_connection_provider_get_connections (priv->provider); - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMConnection *connection = iter->data; + connections = nm_settings_get_connections (priv->settings, NULL); + for (i = 0; connections[i]; i++) { + NMConnection *connection = (NMConnection *) connections[i]; if (connection_compatible (self, connection)) changed |= _internal_track_connection (self, connection, TRUE); @@ -1029,7 +1032,7 @@ on_bus_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) NMBluezDevice * nm_bluez_device_new (const char *path, const char *adapter_address, - NMConnectionProvider *provider, + NMSettings *settings, int bluez_version) { NMBluezDevice *self; @@ -1037,7 +1040,7 @@ nm_bluez_device_new (const char *path, const char *interface_name = NULL; g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (provider), NULL); + g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL); g_return_val_if_fail (bluez_version == 4 || bluez_version == 5, NULL); self = (NMBluezDevice *) g_object_new (NM_TYPE_BLUEZ_DEVICE, @@ -1051,14 +1054,14 @@ nm_bluez_device_new (const char *path, priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); priv->bluez_version = bluez_version; - priv->provider = g_object_ref (provider); + priv->settings = g_object_ref (settings); g_return_val_if_fail (bluez_version == 5 || (bluez_version == 4 && adapter_address), NULL); if (adapter_address) set_adapter_address (self, adapter_address); - g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), self); - g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), self); - g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), self); + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), self); + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), self); + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), self); g_bus_get (G_BUS_TYPE_SYSTEM, NULL, @@ -1116,10 +1119,10 @@ dispose (GObject *object) } #endif - if (priv->provider) { - g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self); - g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self); - g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self); + if (priv->settings) { + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self); + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self); + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self); } g_slist_free_full (priv->connections, g_object_unref); @@ -1137,7 +1140,7 @@ dispose (GObject *object) g_object_unref (to_delete); } - g_clear_object (&priv->provider); + g_clear_object (&priv->settings); } static void diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h index c9560540..66a349e0 100644 --- a/src/devices/bluetooth/nm-bluez-device.h +++ b/src/devices/bluetooth/nm-bluez-device.h @@ -22,7 +22,6 @@ #define __NETWORKMANAGER_BLUEZ_DEVICE_H__ #include "nm-connection.h" -#include "nm-connection-provider.h" #define NM_TYPE_BLUEZ_DEVICE (nm_bluez_device_get_type ()) #define NM_BLUEZ_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDevice)) @@ -59,7 +58,7 @@ GType nm_bluez_device_get_type (void); NMBluezDevice *nm_bluez_device_new (const char *path, const char *adapter_address, - NMConnectionProvider *provider, + NMSettings *settings, int bluez_version); const char *nm_bluez_device_get_path (NMBluezDevice *self); diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 766ecc0a..0d2e302c 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -20,19 +20,20 @@ #include "nm-default.h" +#include "nm-bluez-manager.h" + #include <signal.h> #include <string.h> #include <stdlib.h> #include <gmodule.h> -#include "nm-bluez-manager.h" #include "nm-device-factory.h" #include "nm-setting-bluetooth.h" +#include "nm-settings.h" #include "nm-bluez4-manager.h" #include "nm-bluez5-manager.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" -#include "nm-connection-provider.h" #include "nm-device-bt.h" #include "nm-core-internal.h" #include "nm-platform.h" @@ -51,7 +52,7 @@ typedef struct { int bluez_version; - NMConnectionProvider *provider; + NMSettings *settings; NMBluez4Manager *manager4; NMBluez5Manager *manager5; @@ -190,7 +191,7 @@ setup_bluez4 (NMBluezManager *self) g_return_if_fail (!priv->manager4 && !priv->manager5 && !priv->bluez_version); setup_version_number (self, 4); - priv->manager4 = manager = nm_bluez4_manager_new (priv->provider); + priv->manager4 = manager = nm_bluez4_manager_new (priv->settings); g_signal_connect (manager, NM_BLUEZ_MANAGER_BDADDR_ADDED, @@ -209,7 +210,7 @@ setup_bluez5 (NMBluezManager *self) g_return_if_fail (!priv->manager4 && !priv->manager5 && !priv->bluez_version); setup_version_number (self, 5); - priv->manager5 = manager = nm_bluez5_manager_new (priv->provider); + priv->manager5 = manager = nm_bluez5_manager_new (priv->settings); g_signal_connect (manager, NM_BLUEZ_MANAGER_BDADDR_ADDED, @@ -407,9 +408,9 @@ dispose (GObject *object) priv->bluez_version = 0; - g_clear_object (&priv->provider); - G_OBJECT_CLASS (nm_bluez_manager_parent_class)->dispose (object); + + g_clear_object (&priv->settings); } static void @@ -417,7 +418,7 @@ nm_bluez_manager_init (NMBluezManager *self) { NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - priv->provider = g_object_ref (nm_connection_provider_get ()); + priv->settings = g_object_ref (NM_SETTINGS_GET); } static NMDevice * diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h index 1f5597d8..d23b33a7 100644 --- a/src/devices/bluetooth/nm-bluez-manager.h +++ b/src/devices/bluetooth/nm-bluez-manager.h @@ -22,10 +22,6 @@ #ifndef __NETWORKMANAGER_BLUEZ_MANAGER_H__ #define __NETWORKMANAGER_BLUEZ_MANAGER_H__ -#include "nm-default.h" - -G_BEGIN_DECLS - #define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ()) #define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager)) diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c index 9d8fd210..2ef071a8 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.c +++ b/src/devices/bluetooth/nm-bluez4-adapter.c @@ -20,13 +20,15 @@ #include "nm-default.h" +#include "nm-bluez4-adapter.h" + #include <string.h> #include "nm-dbus-interface.h" -#include "nm-bluez4-adapter.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" #include "nm-core-internal.h" +#include "nm-settings.h" G_DEFINE_TYPE (NMBluez4Adapter, nm_bluez4_adapter, G_TYPE_OBJECT) @@ -41,7 +43,7 @@ typedef struct { GHashTable *devices; /* Cached for devices */ - NMConnectionProvider *provider; + NMSettings *settings; } NMBluez4AdapterPrivate; @@ -160,7 +162,7 @@ device_created (GDBusProxy *proxy, const char *path, gpointer user_data) NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self); NMBluezDevice *device; - device = nm_bluez_device_new (path, priv->address, priv->provider, 4); + device = nm_bluez_device_new (path, priv->address, priv->settings, 4); g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self); g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self); g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device); @@ -234,17 +236,19 @@ query_properties (NMBluez4Adapter *self) /***********************************************************/ NMBluez4Adapter * -nm_bluez4_adapter_new (const char *path, NMConnectionProvider *provider) +nm_bluez4_adapter_new (const char *path, NMSettings *settings) { NMBluez4Adapter *self; NMBluez4AdapterPrivate *priv; + g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL); + self = (NMBluez4Adapter *) g_object_new (NM_TYPE_BLUEZ4_ADAPTER, NM_BLUEZ4_ADAPTER_PATH, path, NULL); priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self); - priv->provider = provider; + priv->settings = g_object_ref (settings); priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, @@ -301,6 +305,8 @@ finalize (GObject *object) g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_bluez4_adapter_parent_class)->finalize (object); + + g_object_unref (priv->settings); } static void diff --git a/src/devices/bluetooth/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h index a8a2bfb4..ee61112f 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.h +++ b/src/devices/bluetooth/nm-bluez4-adapter.h @@ -21,10 +21,7 @@ #ifndef __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ #define __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ - -#include "nm-default.h" #include "nm-bluez-device.h" -#include "nm-connection-provider.h" #define NM_TYPE_BLUEZ4_ADAPTER (nm_bluez4_adapter_get_type ()) #define NM_BLUEZ4_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ4_ADAPTER, NMBluez4Adapter)) @@ -54,7 +51,7 @@ typedef struct { GType nm_bluez4_adapter_get_type (void); NMBluez4Adapter *nm_bluez4_adapter_new (const char *path, - NMConnectionProvider *provider); + NMSettings *settings); const char *nm_bluez4_adapter_get_path (NMBluez4Adapter *self); diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c index 146612a8..36bc30e5 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -21,20 +21,22 @@ #include "nm-default.h" +#include "nm-bluez4-manager.h" + #include <signal.h> #include <string.h> #include <stdlib.h> -#include "nm-bluez-manager.h" -#include "nm-bluez4-manager.h" #include "nm-bluez4-adapter.h" +#include "nm-bluez-manager.h" #include "nm-bluez-common.h" #include "nm-core-internal.h" +#include "nm-settings.h" typedef struct { gulong name_owner_changed_id; - NMConnectionProvider *provider; + NMSettings *settings; GDBusProxy *proxy; @@ -155,7 +157,7 @@ default_adapter_changed (GDBusProxy *proxy, const char *path, NMBluez4Manager *s /* Add the new default adapter */ if (path) { - priv->adapter = nm_bluez4_adapter_new (path, priv->provider); + priv->adapter = nm_bluez4_adapter_new (path, priv->settings); g_signal_connect (priv->adapter, "initialized", G_CALLBACK (adapter_initialized), self); } } @@ -223,12 +225,14 @@ name_owner_changed_cb (GObject *object, /****************************************************************/ NMBluez4Manager * -nm_bluez4_manager_new (NMConnectionProvider *provider) +nm_bluez4_manager_new (NMSettings *settings) { NMBluez4Manager *instance; + g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL); + instance = g_object_new (NM_TYPE_BLUEZ4_MANAGER, NULL); - NM_BLUEZ4_MANAGER_GET_PRIVATE (instance)->provider = provider; + NM_BLUEZ4_MANAGER_GET_PRIVATE (instance)->settings = g_object_ref (settings); return instance; } @@ -264,6 +268,8 @@ dispose (GObject *object) g_clear_object (&priv->adapter); G_OBJECT_CLASS (nm_bluez4_manager_parent_class)->dispose (object); + + g_clear_object (&priv->settings); } static void diff --git a/src/devices/bluetooth/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h index f6bf7658..8afe6924 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.h +++ b/src/devices/bluetooth/nm-bluez4-manager.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify @@ -22,11 +21,6 @@ #ifndef __NETWORKMANAGER_BLUEZ4_MANAGER_H__ #define __NETWORKMANAGER_BLUEZ4_MANAGER_H__ -#include "nm-default.h" -#include "nm-connection-provider.h" - -G_BEGIN_DECLS - #define NM_TYPE_BLUEZ4_MANAGER (nm_bluez4_manager_get_type ()) #define NM_BLUEZ4_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ4_MANAGER, NMBluez4Manager)) #define NM_BLUEZ4_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ4_MANAGER, NMBluez4ManagerClass)) @@ -51,7 +45,7 @@ typedef struct { GType nm_bluez4_manager_get_type (void); -NMBluez4Manager *nm_bluez4_manager_new (NMConnectionProvider *provider); +NMBluez4Manager *nm_bluez4_manager_new (NMSettings *settings); void nm_bluez4_manager_query_devices (NMBluez4Manager *manager); diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h index c59cbb80..124c1a05 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.h +++ b/src/devices/bluetooth/nm-bluez5-dun.h @@ -21,8 +21,6 @@ #ifndef _NM_BLUEZ5_UTILS_H_ #define _NM_BLUEZ5_UTILS_H_ -#include "nm-default.h" - typedef struct _NMBluez5DunContext NMBluez5DunContext; typedef void (*NMBluez5DunFunc) (NMBluez5DunContext *context, diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 66d171bf..a014d0c1 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -22,19 +22,21 @@ #include "nm-default.h" +#include "nm-bluez5-manager.h" + #include <signal.h> #include <string.h> #include <stdlib.h> +#include "nm-core-internal.h" + #include "nm-bluez-manager.h" -#include "nm-bluez5-manager.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" - -#include "nm-core-internal.h" +#include "nm-settings.h" typedef struct { - NMConnectionProvider *provider; + NMSettings *settings; GDBusProxy *proxy; @@ -140,7 +142,7 @@ device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NMBluezDevice *device; - device = nm_bluez_device_new (path, NULL, priv->provider, 5); + device = nm_bluez_device_new (path, NULL, priv->settings, 5); g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self); g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self); g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device); @@ -180,7 +182,7 @@ object_manager_interfaces_removed (GDBusProxy *proxy, const char **ifaces, NMBluez5Manager *self) { - if (_nm_utils_string_in_list (BLUEZ5_DEVICE_INTERFACE, ifaces)) + if (ifaces && g_strv_contains (ifaces, BLUEZ5_DEVICE_INTERFACE)) device_removed (proxy, path, self); } @@ -309,12 +311,14 @@ bluez_cleanup (NMBluez5Manager *self, gboolean do_signal) /****************************************************************/ NMBluez5Manager * -nm_bluez5_manager_new (NMConnectionProvider *provider) +nm_bluez5_manager_new (NMSettings *settings) { NMBluez5Manager *instance = NULL; + g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL); + instance = g_object_new (NM_TYPE_BLUEZ5_MANAGER, NULL); - NM_BLUEZ5_MANAGER_GET_PRIVATE (instance)->provider = provider; + NM_BLUEZ5_MANAGER_GET_PRIVATE (instance)->settings = g_object_ref (settings); return instance; } @@ -347,6 +351,8 @@ finalize (GObject *object) g_hash_table_destroy (priv->devices); G_OBJECT_CLASS (nm_bluez5_manager_parent_class)->finalize (object); + + g_object_unref (priv->settings); } static void diff --git a/src/devices/bluetooth/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h index 1c531090..0e309d33 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.h +++ b/src/devices/bluetooth/nm-bluez5-manager.h @@ -22,11 +22,6 @@ #ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__ #define __NETWORKMANAGER_BLUEZ5_MANAGER_H__ -#include "nm-default.h" -#include "nm-connection-provider.h" - -G_BEGIN_DECLS - #define NM_TYPE_BLUEZ5_MANAGER (nm_bluez5_manager_get_type ()) #define NM_BLUEZ5_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ5_MANAGER, NMBluez5Manager)) #define NM_BLUEZ5_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ5_MANAGER, NMBluez5ManagerClass)) @@ -51,7 +46,7 @@ typedef struct { GType nm_bluez5_manager_get_type (void); -NMBluez5Manager *nm_bluez5_manager_new (NMConnectionProvider *provider); +NMBluez5Manager *nm_bluez5_manager_new (NMSettings *settings); void nm_bluez5_manager_query_devices (NMBluez5Manager *manager); diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index eef4ed0a..67ae15bc 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -362,6 +362,7 @@ static void ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDeviceBt *self = NM_DEVICE_BT (user_data); switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: @@ -375,7 +376,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) case NM_DEVICE_STATE_ACTIVATED: if (nm_device_activate_ip4_state_in_conf (device)) nm_device_activate_schedule_ip4_config_timeout (device); - else { + else if (nm_device_activate_ip6_state_in_conf (device)) + nm_device_activate_schedule_ip6_config_timeout (device); + else if (nm_device_activate_ip4_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else if (nm_device_activate_ip6_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device)); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -502,8 +514,9 @@ modem_ip4_config_result (NMModem *modem, _LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT, "retrieving IP4 configuration failed: %s", error->message); - - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else nm_device_activate_schedule_ip4_config_result (device, config); } @@ -989,7 +1002,7 @@ nm_device_bt_new (NMBluezDevice *bt_device, NM_DEVICE_UDI, udi, NM_DEVICE_IFACE, bdaddr, NM_DEVICE_DRIVER, "bluez", - NM_DEVICE_HW_ADDRESS, bdaddr, + NM_DEVICE_PERM_HW_ADDRESS, bdaddr, NM_DEVICE_BT_DEVICE, bt_device, NM_DEVICE_BT_NAME, name, NM_DEVICE_BT_CAPABILITIES, capabilities, diff --git a/src/devices/bluetooth/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h index c565745f..c97cca01 100644 --- a/src/devices/bluetooth/nm-device-bt.h +++ b/src/devices/bluetooth/nm-device-bt.h @@ -25,8 +25,6 @@ #include "nm-bluez-device.h" #include "nm-modem.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_BT (nm_device_bt_get_type ()) #define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BT, NMDeviceBt)) #define NM_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) @@ -63,6 +61,4 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device, NMModem *modem, const char *driver); -G_END_DECLS - #endif /* __NETWORKMANAGER_DEVICE_BT_H__ */ diff --git a/src/devices/nm-arping-manager.h b/src/devices/nm-arping-manager.h index 4a4f8d4b..78965a0d 100644 --- a/src/devices/nm-arping-manager.h +++ b/src/devices/nm-arping-manager.h @@ -19,8 +19,6 @@ #include <netinet/in.h> -G_BEGIN_DECLS - #define NM_TYPE_ARPING_MANAGER (nm_arping_manager_get_type ()) #define NM_ARPING_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ARPING_MANAGER, NMArpingManager)) #define NM_ARPING_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ARPING_MANAGER, NMArpingManagerClass)) @@ -48,6 +46,4 @@ gboolean nm_arping_manager_check_address (NMArpingManager *self, in_addr_t addre void nm_arping_manager_announce_addresses (NMArpingManager *self); void nm_arping_manager_reset (NMArpingManager *self); -G_END_DECLS - #endif /* __NM_ARPING_MANAGER__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 9c98c8ea..3f17849b 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2011 - 2016 Red Hat, Inc. */ #include "nm-default.h" @@ -118,12 +118,15 @@ complete_connection (NMDevice *device, /******************************************************************/ static gboolean -set_bond_attr (NMDevice *device, const char *attr, const char *value) +set_bond_attr (NMDevice *device, NMBondMode mode, const char *attr, const char *value) { NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean ret; int ifindex = nm_device_get_ifindex (device); + if (!_nm_setting_bond_option_supported (attr, mode)) + return FALSE; + ret = nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, attr, value); if (!ret) _LOGW (LOGD_HW, "failed to set bonding attribute '%s' to '%s'", attr, value); @@ -134,10 +137,10 @@ set_bond_attr (NMDevice *device, const char *attr, const char *value) static gboolean ignore_if_zero (const char *option, const char *value) { - if (strcmp (option, "arp_interval") && - strcmp (option, "miimon") && - strcmp (option, "downdelay") && - strcmp (option, "updelay")) + if (!NM_IN_STRSET (option, NM_SETTING_BOND_OPTION_ARP_INTERVAL, + NM_SETTING_BOND_OPTION_DOWNDELAY, + NM_SETTING_BOND_OPTION_MIIMON, + NM_SETTING_BOND_OPTION_UPDELAY)) return FALSE; return g_strcmp0 (value, "0") == 0 ? TRUE : FALSE; @@ -173,7 +176,7 @@ update_connection (NMDevice *device, NMConnection *connection) && !ignore_if_zero (*options, value) && !nm_streq0 (value, defvalue)) { /* Replace " " with "," for arp_ip_targets from the kernel */ - if (strcmp (*options, "arp_ip_target") == 0) { + if (strcmp (*options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) == 0) { for (p = value; *p; p++) { if (*p == ' ') *p = ','; @@ -201,6 +204,7 @@ master_update_slave_connection (NMDevice *self, static void set_arp_targets (NMDevice *device, + NMBondMode mode, const char *value, const char *delim, const char *prefix) @@ -214,7 +218,7 @@ set_arp_targets (NMDevice *device, for (iter = items; iter && *iter; iter++) { if (*iter[0]) { tmp = g_strdup_printf ("%s%s", prefix, *iter); - set_bond_attr (device, "arp_ip_target", tmp); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, tmp); g_free (tmp); } } @@ -223,7 +227,7 @@ set_arp_targets (NMDevice *device, static void set_simple_option (NMDevice *device, - const char *attr, + NMBondMode mode, NMSettingBond *s_bond, const char *opt) { @@ -232,18 +236,20 @@ set_simple_option (NMDevice *device, value = nm_setting_bond_get_option_by_name (s_bond, opt); if (!value) value = nm_setting_bond_get_option_default (s_bond, opt); - set_bond_attr (device, attr, value); + set_bond_attr (device, mode, opt, value); } static NMActStageReturn apply_bonding_config (NMDevice *device) { + NMDeviceBond *self = NM_DEVICE_BOND (device); NMConnection *connection; NMSettingBond *s_bond; int ifindex = nm_device_get_ifindex (device); - const char *mode, *value; + const char *mode_str, *value; char *contents; gboolean set_arp_interval = TRUE; + NMBondMode mode; /* Option restrictions: * @@ -263,98 +269,90 @@ apply_bonding_config (NMDevice *device) s_bond = nm_connection_get_setting_bond (connection); g_assert (s_bond); - mode = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE); - if (mode == NULL) - mode = "balance-rr"; + mode_str = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE); + if (!mode_str) + mode_str = "balance-rr"; + + mode = _nm_setting_bond_mode_from_string (mode_str); + if (mode == NM_BOND_MODE_UNKNOWN) { + _LOGW (LOGD_BOND, "unknown bond mode '%s'", mode_str); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + /* Set mode first, as some other options (e.g. arp_interval) are valid + * only for certain modes. + */ + + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_MODE, mode_str); value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON); if (value && atoi (value)) { /* clear arp interval */ - set_bond_attr (device, "arp_interval", "0"); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_INTERVAL, "0"); set_arp_interval = FALSE; - set_bond_attr (device, "miimon", value); - set_simple_option (device, "updelay", s_bond, NM_SETTING_BOND_OPTION_UPDELAY); - set_simple_option (device, "downdelay", s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_MIIMON, value); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_UPDELAY); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY); } else if (!value) { - /* If not given, and arp_interval is not given, default to 100 */ - long int val_int; - char *end; - + /* If not given, and arp_interval is not given or disabled, default to 100 */ value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL); - errno = 0; - val_int = strtol (value ? value : "0", &end, 10); - if (!value || (val_int == 0 && errno == 0 && *end == '\0')) - set_bond_attr (device, "miimon", "100"); + if (_nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, 0) == 0) + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_MIIMON, "100"); } - /* The stuff after 'mode' requires the given mode or doesn't care */ - set_bond_attr (device, "mode", mode); - - /* arp_interval not compatible with ALB, TLB */ - if (NM_IN_STRSET (mode, "balance-alb", "balance-tlb")) - set_arp_interval = FALSE; - if (set_arp_interval) { - set_simple_option (device, "arp_interval", s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL); - + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL); /* Just let miimon get cleared automatically; even setting miimon to * 0 (disabled) clears arp_interval. */ } + /* ARP validate: value > 0 only valid in active-backup mode */ value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_VALIDATE); - /* arp_validate > 0 only valid in active-backup mode */ if ( value && !nm_streq (value, "0") && !nm_streq (value, "none") - && nm_streq (mode, "active-backup")) - set_bond_attr (device, "arp_validate", value); + && mode == NM_BOND_MODE_ACTIVEBACKUP) + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_VALIDATE, value); else - set_bond_attr (device, "arp_validate", "0"); - - if (NM_IN_STRSET (mode, "active-backup", "balance-alb", "balance-tlb")) { - value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY); - set_bond_attr (device, "primary", value ? value : ""); - set_simple_option (device, "lp_interval", s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL); - } + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_VALIDATE, "0"); - /* Clear ARP targets */ - contents = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, "arp_ip_target"); - set_arp_targets (device, contents, " \n", "-"); - g_free (contents); + /* Primary */ + value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_PRIMARY, value ? value : ""); - /* Add new ARP targets */ + /* ARP targets: clear and initialize the list */ + contents = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, + NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + set_arp_targets (device, mode, contents, " \n", "-"); value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); - set_arp_targets (device, value, ",", "+"); - - set_simple_option (device, "primary_reselect", s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT); - set_simple_option (device, "fail_over_mac", s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC); - set_simple_option (device, "use_carrier", s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER); - set_simple_option (device, "ad_select", s_bond, NM_SETTING_BOND_OPTION_AD_SELECT); - set_simple_option (device, "xmit_hash_policy", s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY); - set_simple_option (device, "resend_igmp", s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP); - set_simple_option (device, "active_slave", s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); - set_simple_option (device, "all_slaves_active", s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE); - set_simple_option (device, "num_grat_arp", s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); - set_simple_option (device, "num_unsol_na", s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); - - if (nm_streq (mode, "802.3ad")) { - set_simple_option (device, "lacp_rate", s_bond, NM_SETTING_BOND_OPTION_LACP_RATE); - set_simple_option (device, "ad_actor_sys_prio", s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO); - set_simple_option (device, "ad_actor_system", s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM); - set_simple_option (device, "ad_user_port_key", s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY); - set_simple_option (device, "min_links", s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS); - } - - if (nm_streq (mode, "active-backup")) - set_simple_option (device, "arp_all_targets", s_bond, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS); - - if (nm_streq (mode, "balance-rr")) - set_simple_option (device, "packets_per_slave", s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE); + set_arp_targets (device, mode, value, ",", "+"); + g_free (contents); - if (nm_streq (mode, "balance-tlb")) - set_simple_option (device, "tlb_dynamic_lb", s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB); + /* AD actor system: don't set if empty */ + value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM); + if (value) + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, value); + + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_AD_SELECT); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_LACP_RATE); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER); + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY); return NM_ACT_STAGE_RETURN_SUCCESS; } diff --git a/src/devices/nm-device-bond.h b/src/devices/nm-device-bond.h index 9e86719e..02b6c8e5 100644 --- a/src/devices/nm-device-bond.h +++ b/src/devices/nm-device-bond.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type ()) #define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) #define NM_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) @@ -37,6 +35,4 @@ typedef NMDeviceClass NMDeviceBondClass; GType nm_device_bond_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_BOND_H */ +#endif /* NM_DEVICE_BOND_H */ diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index 46482675..05da9ed7 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -21,11 +21,8 @@ #ifndef __NETWORKMANAGER_DEVICE_BRIDGE_H__ #define __NETWORKMANAGER_DEVICE_BRIDGE_H__ -#include "nm-default.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_BRIDGE (nm_device_bridge_get_type ()) #define NM_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridge)) #define NM_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) @@ -38,6 +35,4 @@ typedef NMDeviceClass NMDeviceBridgeClass; GType nm_device_bridge_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_BRIDGE_H */ +#endif /* __NETWORKMANAGER_DEVICE_BRIDGE_H__ */ diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c index d034ddfc..298e6dff 100644 --- a/src/devices/nm-device-ethernet-utils.c +++ b/src/devices/nm-device-ethernet-utils.c @@ -25,30 +25,26 @@ #include "nm-device-ethernet-utils.h" char * -nm_device_ethernet_utils_get_default_wired_name (const GSList *connections) +nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections) { - const GSList *iter; - char *cname = NULL; - int i = 0; + char *temp; + guint j; + int i; /* Find the next available unique connection name */ - while (!cname && (i++ < 10000)) { - char *temp; - gboolean found = FALSE; - + for (i = 1; i <= 10000; i++) { temp = g_strdup_printf (_("Wired connection %d"), i); - for (iter = connections; iter; iter = iter->next) { - if (g_strcmp0 (nm_connection_get_id (NM_CONNECTION (iter->data)), temp) == 0) { - found = TRUE; + for (j = 0; connections[j]; j++) { + if (nm_streq0 (nm_connection_get_id (connections[j]), temp)) { g_free (temp); - break; + goto next; } } - - if (found == FALSE) - cname = temp; + return temp; +next: + ; } - return cname; + return NULL; } diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h index 31d645d8..197d0a9e 100644 --- a/src/devices/nm-device-ethernet-utils.h +++ b/src/devices/nm-device-ethernet-utils.h @@ -19,8 +19,6 @@ #ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ #define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ -#include "nm-default.h" - -char *nm_device_ethernet_utils_get_default_wired_name (const GSList *connections); +char *nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections); #endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index d27f7dca..90d472da 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -21,6 +21,8 @@ #include "nm-default.h" +#include "nm-device-ethernet.h" + #include <netinet/in.h> #include <string.h> #include <stdlib.h> @@ -29,7 +31,6 @@ #include <gudev/gudev.h> -#include "nm-device-ethernet.h" #include "nm-device-private.h" #include "nm-activation-request.h" #include "NetworkManagerUtils.h" @@ -44,7 +45,7 @@ #include "nm-settings-connection.h" #include "nm-config.h" #include "nm-device-ethernet-utils.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-device-factory.h" #include "nm-core-internal.h" #include "NetworkManagerUtils.h" @@ -54,15 +55,15 @@ #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceEthernet); -G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) - -#define NM_DEVICE_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate)) +/*****************************************************************************/ #define WIRED_SECRETS_TRIES "wired-secrets-tries" #define PPPOE_RECONNECT_DELAY 7 #define PPPOE_ENCAP_OVERHEAD 8 /* 2 bytes for PPP, 6 for PPPoE */ +/*****************************************************************************/ + typedef struct Supplicant { NMSupplicantManager *mgr; NMSupplicantInterface *iface; @@ -90,7 +91,7 @@ typedef enum { DCB_WAIT_CARRIER_POSTCONFIG_UP, } DcbWait; -typedef struct { +typedef struct _NMDeviceEthernetPrivate { guint32 speed; Supplicant supplicant; @@ -117,15 +118,29 @@ typedef struct { gulong dcb_carrier_id; } NMDeviceEthernetPrivate; -enum { - PROP_0, - PROP_PERM_HW_ADDRESS, +NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceEthernet, PROP_SPEED, PROP_S390_SUBCHANNELS, +); - LAST_PROP -}; +/*****************************************************************************/ + +G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) + +#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMDeviceEthernet *_self2 = (_self); \ + \ + nm_assert (NM_IS_DEVICE_ETHERNET (_self)); \ + _self->_priv; \ + }) +/*****************************************************************************/ static char * get_link_basename (const char *parent_path, const char *name, GError **error) @@ -147,21 +162,29 @@ static void _update_s390_subchannels (NMDeviceEthernet *self) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - GUdevDevice *dev; - GUdevDevice *parent = NULL; - const char *parent_path, *item, *driver; + gs_unref_object GUdevDevice *dev = NULL; + gs_unref_object GUdevDevice *parent = NULL; + const char *parent_path, *item; int ifindex; GDir *dir; GError *error = NULL; - ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - dev = (GUdevDevice *) nm_platform_link_get_udev_device (NM_PLATFORM_GET, ifindex); + if (priv->subchannels) { + /* only read the subchannels once. For one, we don't expect them to change + * on multiple invocations. Second, we didn't implement proper reloading. + * Proper reloading might also be complicated, because the subchannels are + * used to match on devices based on a device-spec. Thus, it's not clear + * what it means to change afterwards. */ + return; + } + + ifindex = nm_device_get_ifindex ((NMDevice *) self); + dev = (GUdevDevice *) nm_g_object_ref (nm_platform_link_get_udev_device (NM_PLATFORM_GET, ifindex)); if (!dev) { - _LOGW (LOGD_DEVICE | LOGD_HW, "failed to find device %d '%s' with udev", - ifindex, nm_device_get_iface (NM_DEVICE (self)) ?: "(null)"); - goto out; + /* we only call _update_s390_subchannels() when platform claims the device to be initialized. + * Thus, we expect to successfully lookup a GUdevDevice. */ + g_return_if_reached (); } - g_object_ref (dev); /* Try for the "ccwgroup" parent */ parent = g_udev_device_get_parent_with_subsystem (dev, "ccwgroup", NULL); @@ -169,17 +192,17 @@ _update_s390_subchannels (NMDeviceEthernet *self) /* FIXME: whatever 'lcs' devices' subsystem is here... */ if (!parent) { /* Not an s390 device */ - goto out; + return; } } parent_path = g_udev_device_get_sysfs_path (parent); dir = g_dir_open (parent_path, 0, &error); if (!dir) { - _LOGW (LOGD_DEVICE | LOGD_HW, "failed to open directory '%s': %s", + _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: failed to open directory '%s': %s", parent_path, error->message); g_clear_error (&error); - goto out; + return; } while ((item = g_dir_read_name (dir))) { @@ -206,11 +229,11 @@ _update_s390_subchannels (NMDeviceEthernet *self) g_hash_table_insert (priv->s390_options, g_strdup (item), value); value = NULL; } else - _LOGW (LOGD_DEVICE | LOGD_HW, "error reading %s", path); + _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: error reading %s", path); } if (error) { - _LOGW (LOGD_DEVICE | LOGD_HW, "%s", error->message); + _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: failed reading sysfs for %s (%s)", item, error->message); g_clear_error (&error); } } @@ -235,42 +258,23 @@ _update_s390_subchannels (NMDeviceEthernet *self) priv->subchannels_dbus[2] = g_strdup (priv->subchan3); priv->subchannels_dbus[3] = NULL; - driver = nm_device_get_driver (NM_DEVICE (self)); - _LOGI (LOGD_DEVICE | LOGD_HW, "found s390 '%s' subchannels [%s]", - driver ? driver : "(unknown driver)", priv->subchannels); + _LOGI (LOGD_DEVICE | LOGD_HW, "update-s390: found s390 '%s' subchannels [%s]", + nm_device_get_driver ((NMDevice *) self) ?: "(unknown driver)", + priv->subchannels); -out: - if (parent) - g_object_unref (parent); - if (dev) - g_object_unref (dev); + _notify (self, PROP_S390_SUBCHANNELS); } -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) +static void +constructed (GObject *object) { - GObject *object; - - object = G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (object) { -#ifndef G_DISABLE_ASSERT - int ifindex = nm_device_get_ifindex (NM_DEVICE (object)); - NMLinkType link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex); - - g_assert ( link_type == NM_LINK_TYPE_ETHERNET - || link_type == NM_LINK_TYPE_VETH - || link_type == NM_LINK_TYPE_NONE); -#endif - - /* s390 stuff */ - _update_s390_subchannels (NM_DEVICE_ETHERNET (object)); - } + const NMPlatformLink *pllink; + + G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructed (object); - return object; + pllink = nm_platform_link_get (NM_PLATFORM_GET, nm_device_get_ifindex ((NMDevice *) object)); + if (pllink && pllink->initialized) + _update_s390_subchannels ((NMDeviceEthernet *) object); } static void @@ -302,16 +306,12 @@ device_state_changed (NMDevice *device, static void nm_device_ethernet_init (NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); -} + NMDeviceEthernetPrivate *priv; -static void -realize_start_notify (NMDevice *device, const NMPlatformLink *plink) -{ - NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->realize_start_notify (device, plink); + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); + self->_priv = priv; - g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); + priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static NMDeviceCapabilities @@ -407,7 +407,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!match_subchans (self, s_wired, &try_mac)) return FALSE; - perm_hw_addr = nm_device_get_permanent_hw_address (device); + perm_hw_addr = nm_device_get_permanent_hw_address (device, TRUE); mac = nm_setting_wired_get_mac_address (s_wired); if (perm_hw_addr) { if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) @@ -812,21 +812,17 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingWired *s_wired; - const char *cloned_mac; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage1_prepare (dev, reason); if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED); - if (s_wired) { - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_ETHER); - } + if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE)) + ret = NM_ACT_STAGE_RETURN_FAILURE; + } + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { /* If we're re-activating a PPPoE connection a short while after * a previous PPPoE connection was torn down, wait a bit to allow the * remote side to handle the disconnection. Otherwise the peer may @@ -946,7 +942,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas req = nm_device_get_act_request (NM_DEVICE (self)); g_assert (req); - s_pppoe = (NMSettingPppoe *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_PPPOE); + s_pppoe = (NMSettingPppoe *) nm_device_get_applied_setting ((NMDevice *) self, NM_TYPE_SETTING_PPPOE); g_assert (s_pppoe); priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE (self))); @@ -972,22 +968,6 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas /****************************************************************/ -static void -dcb_timeout_cleanup (NMDevice *device) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - - nm_clear_g_source (&priv->dcb_timeout_id); -} - -static void -dcb_carrier_cleanup (NMDevice *device) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - - nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); -} - static void dcb_state (NMDevice *device, gboolean timeout); static gboolean @@ -1011,12 +991,12 @@ dcb_carrier_timeout (gpointer user_data) static gboolean dcb_configure (NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = (NMDeviceEthernet *) device; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMSettingDcb *s_dcb; GError *error = NULL; - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); s_dcb = (NMSettingDcb *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); g_assert (s_dcb); @@ -1043,7 +1023,7 @@ dcb_enable (NMDevice *device) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); GError *error = NULL; - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); if (!nm_dcb_enable (nm_device_get_iface (device), TRUE, &error)) { _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", error->message); @@ -1081,9 +1061,9 @@ dcb_state (NMDevice *device, gboolean timeout) case DCB_WAIT_CARRIER_PREENABLE_UP: if (timeout || carrier) { _LOGD (LOGD_DCB, "dcb_state() enabling DCB"); - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); if (!dcb_enable (device)) { - dcb_carrier_cleanup (device); + nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); @@ -1091,7 +1071,7 @@ dcb_state (NMDevice *device, gboolean timeout) } break; case DCB_WAIT_CARRIER_PRECONFIG_DOWN: - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_UP; if (!carrier) { @@ -1105,9 +1085,9 @@ dcb_state (NMDevice *device, gboolean timeout) case DCB_WAIT_CARRIER_PRECONFIG_UP: if (timeout || carrier) { _LOGD (LOGD_DCB, "dcb_state() preconfig up configuring DCB"); - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); if (!dcb_configure (device)) { - dcb_carrier_cleanup (device); + nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); @@ -1115,7 +1095,7 @@ dcb_state (NMDevice *device, gboolean timeout) } break; case DCB_WAIT_CARRIER_POSTCONFIG_DOWN: - dcb_timeout_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_UP; if (!carrier) { @@ -1129,8 +1109,8 @@ dcb_state (NMDevice *device, gboolean timeout) case DCB_WAIT_CARRIER_POSTCONFIG_UP: if (timeout || carrier) { _LOGD (LOGD_DCB, "dcb_state() postconfig up starting IP"); - dcb_timeout_cleanup (device); - dcb_carrier_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); + nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); priv->dcb_wait = DCB_WAIT_UNKNOWN; nm_device_activate_schedule_stage3_ip_config_start (device); } @@ -1200,7 +1180,7 @@ found: static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernet *self = (NMDeviceEthernet *) device; NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMSettingConnection *s_con; const char *connection_type; @@ -1213,8 +1193,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); - dcb_timeout_cleanup (device); - dcb_carrier_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); + nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); /* 802.1x has to run before any IP configuration since the 802.1x auth * process opens the port up for normal traffic. @@ -1311,7 +1291,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) guint32 mtu; /* MTU only set for plain ethernet */ - if (NM_DEVICE_ETHERNET_GET_PRIVATE (device)->ppp_manager) + if (NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device)->ppp_manager) return; connection = nm_device_get_applied_connection (device); @@ -1348,8 +1328,8 @@ deactivate (NMDevice *device) supplicant_interface_release (self); priv->dcb_wait = DCB_WAIT_UNKNOWN; - dcb_timeout_cleanup (device); - dcb_carrier_cleanup (device); + nm_clear_g_source (&priv->dcb_timeout_id); + nm_clear_g_signal_handler (device, &priv->dcb_carrier_id); /* Tear down DCB/FCoE if it was enabled */ s_dcb = (NMSettingDcb *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); @@ -1363,11 +1343,7 @@ deactivate (NMDevice *device) /* Set last PPPoE connection time */ if (nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE)) - NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s (); - - /* Reset MAC address back to initial address */ - if (nm_device_get_initial_hw_address (device)) - nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_ETHER); + priv->last_pppoe_time = nm_utils_get_monotonic_timestamp_s (); } static gboolean @@ -1408,7 +1384,7 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } - perm_hw_addr = nm_device_get_permanent_hw_address (device); + perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); if (perm_hw_addr) { setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { @@ -1435,9 +1411,9 @@ static NMConnection * new_default_connection (NMDevice *self) { NMConnection *connection; - const GSList *connections; + NMSettingsConnection *const*connections; NMSetting *setting; - const char *hw_address; + const char *perm_hw_addr; gs_free char *defname = NULL; gs_free char *uuid = NULL; gs_free char *machine_id = NULL; @@ -1445,16 +1421,16 @@ new_default_connection (NMDevice *self) if (nm_config_get_no_auto_default_for_device (nm_config_get (), self)) return NULL; - hw_address = nm_device_get_hw_address (self); - if (!hw_address) + perm_hw_addr = nm_device_get_permanent_hw_address (self, TRUE); + if (!perm_hw_addr) return NULL; connection = nm_simple_connection_new (); setting = nm_setting_connection_new (); nm_connection_add_setting (connection, setting); - connections = nm_connection_provider_get_connections (nm_connection_provider_get ()); - defname = nm_device_ethernet_utils_get_default_wired_name (connections); + connections = nm_settings_get_connections (nm_device_get_settings (self), NULL); + defname = nm_device_ethernet_utils_get_default_wired_name ((NMConnection *const*) connections); if (!defname) return NULL; @@ -1465,7 +1441,7 @@ new_default_connection (NMDevice *self) uuid = _nm_utils_uuid_generate_from_strings ("default-wired", machine_id ?: "", defname, - hw_address, + perm_hw_addr, NULL); g_object_set (setting, @@ -1479,7 +1455,7 @@ new_default_connection (NMDevice *self) /* Lock the connection to the device */ setting = nm_setting_wired_new (); - g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, hw_address, NULL); + g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL); nm_connection_add_setting (connection, setting); return connection; @@ -1489,7 +1465,7 @@ static NMMatchSpecMatchType spec_match_list (NMDevice *device, const GSList *specs) { NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m; - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device); if (priv->subchannels) matched = nm_match_spec_s390_subchannels (specs, priv->subchannels); @@ -1503,9 +1479,9 @@ spec_match_list (NMDevice *device, const GSList *specs) static void update_connection (NMDevice *device, NMConnection *connection) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device); NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); - const char *perm_hw_addr = nm_device_get_permanent_hw_address (device); + const char *perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); const char *mac = nm_device_get_hw_address (device); const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GHashTableIter iter; @@ -1562,7 +1538,7 @@ get_link_speed (NMDevice *device) return; priv->speed = speed; - g_object_notify (G_OBJECT (device), "speed"); + _notify (self, PROP_SPEED); _LOGD (LOGD_HW | LOGD_ETHER, "speed is now %d Mb/s", speed); } @@ -1579,37 +1555,9 @@ carrier_changed (NMDevice *device, gboolean carrier) static void link_changed (NMDevice *device, NMPlatformLink *info) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - static const guint8 zero_hwaddr[ETH_ALEN]; - const guint8 *hwaddr; - gsize hwaddrlen = 0; - NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->link_changed (device, info); - if (!priv->subchan1 && info->initialized) - _update_s390_subchannels (self); - - if (!nm_device_get_initial_hw_address (device)) { - hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, - nm_device_get_ifindex (self), - &hwaddrlen); - if (!nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, ETH_ALEN)) { - _LOGD (LOGD_DEVICE, "device got a valid hw address"); - nm_device_update_hw_address (self); - nm_device_update_initial_hw_address (self); - if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) { - /* - * If the device is UNAVAILABLE, any previous try to - * bring it up probably has failed because of the - * invalid hardware address; try again. - */ - nm_device_bring_up (self, TRUE, NULL); - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_NONE); - } - } - } + if (info->initialized) + _update_s390_subchannels ((NMDeviceEthernet *) device); } static gboolean @@ -1631,8 +1579,8 @@ dispose (GObject *object) nm_clear_g_source (&priv->pppoe_wait_id); - dcb_timeout_cleanup (NM_DEVICE (self)); - dcb_carrier_cleanup (NM_DEVICE (self)); + nm_clear_g_source (&priv->dcb_timeout_id); + nm_clear_g_signal_handler (self, &priv->dcb_carrier_id); G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); } @@ -1663,9 +1611,6 @@ get_property (GObject *object, guint prop_id, NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); switch (prop_id) { - case PROP_PERM_HW_ADDRESS: - g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (object))); - break; case PROP_SPEED: g_value_set_uint (value, priv->speed); break; @@ -1700,14 +1645,13 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRED_SETTING_NAME, NM_LINK_TYPE_ETHERNET) /* virtual methods */ - object_class->constructor = constructor; + object_class->constructed = constructed; object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; parent_class->get_generic_capabilities = get_generic_capabilities; - parent_class->realize_start_notify = realize_start_notify; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; parent_class->new_default_connection = new_default_connection; @@ -1725,27 +1669,19 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->state_changed = device_state_changed; - /* properties */ - g_object_class_install_property - (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_SPEED, - g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_S390_SUBCHANNELS, - g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_SPEED] = + g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_S390_SUBCHANNELS] = + g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_ETHERNET_SKELETON, diff --git a/src/devices/nm-device-ethernet.h b/src/devices/nm-device-ethernet.h index 2d284822..3ce6f0ca 100644 --- a/src/devices/nm-device-ethernet.h +++ b/src/devices/nm-device-ethernet.h @@ -24,8 +24,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_ETHERNET (nm_device_ethernet_get_type ()) #define NM_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernet)) #define NM_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) @@ -33,15 +31,20 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) #define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) -#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels" -typedef NMDevice NMDeviceEthernet; -typedef NMDeviceClass NMDeviceEthernetClass; +struct _NMDeviceEthernetPrivate; -GType nm_device_ethernet_get_type (void); +typedef struct { + NMDevice parent; + struct _NMDeviceEthernetPrivate *_priv; +} NMDeviceEthernet; -G_END_DECLS +typedef struct { + NMDeviceClass parent_class; +} NMDeviceEthernetClass; + +GType nm_device_ethernet_get_type (void); -#endif /* NM_DEVICE_ETHERNET_H */ +#endif /* __NETWORKMANAGER_DEVICE_ETHERNET_H__ */ diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index ae78968a..4a62468c 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -92,10 +92,10 @@ typedef struct { * @connection: the #NMConnection to return the parent name for, if supported * * Given a connection, returns the a parent interface name, parent connection - * UUID, or parent device hardware address for @connection. + * UUID, or parent device permanent hardware address for @connection. * * Returns: the parent interface name, parent connection UUID, parent - * device hardware address, or %NULL + * device permenent hardware address, or %NULL */ const char * (*get_connection_parent) (NMDeviceFactory *factory, NMConnection *connection); diff --git a/src/devices/nm-device-generic.h b/src/devices/nm-device-generic.h index 9303a278..9a5ff091 100644 --- a/src/devices/nm-device-generic.h +++ b/src/devices/nm-device-generic.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) #define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) #define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) @@ -47,6 +45,4 @@ GType nm_device_generic_get_type (void); NMDevice *nm_device_generic_new (const NMPlatformLink *plink); -G_END_DECLS - -#endif /* NM_DEVICE_GENERIC_H */ +#endif /* __NETWORKMANAGER_DEVICE_GENERIC_H__ */ diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index ae9543e4..17f50ba2 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -147,10 +147,15 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (nm_device_is_real (device)) { const char *mac; + const char *hw_addr; mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1)) - return FALSE; + if (mac) { + hw_addr = nm_device_get_permanent_hw_address (device, TRUE); + if ( !hw_addr + || !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) + return FALSE; + } } return TRUE; @@ -183,7 +188,7 @@ complete_connection (NMDevice *device, } setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband); - hw_address = nm_device_get_hw_address (device); + hw_address = nm_device_get_permanent_hw_address (device, TRUE); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's MAC */ if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { @@ -209,7 +214,7 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); - const char *mac = nm_device_get_hw_address (device); + const char *mac = nm_device_get_permanent_hw_address (device, TRUE); const char *transport_mode = "datagram"; int ifindex; diff --git a/src/devices/nm-device-infiniband.h b/src/devices/nm-device-infiniband.h index cac9a79d..a74d07a5 100644 --- a/src/devices/nm-device-infiniband.h +++ b/src/devices/nm-device-infiniband.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type ()) #define NM_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) #define NM_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) @@ -37,6 +35,4 @@ typedef NMDeviceClass NMDeviceInfinibandClass; GType nm_device_infiniband_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_INFINIBAND_H */ +#endif /* __NETWORKMANAGER_DEVICE_INFINIBAND_H__ */ diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 089b1035..785010eb 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -20,19 +20,20 @@ #include "nm-default.h" +#include "nm-device-ip-tunnel.h" + #include <string.h> #include <netinet/in.h> #include <linux/if.h> #include <linux/ip.h> #include <linux/if_tunnel.h> -#include "nm-device-ip-tunnel.h" #include "nm-device-private.h" #include "nm-manager.h" #include "nm-platform.h" #include "nm-device-factory.h" #include "nm-core-internal.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-activation-request.h" #include "nm-ip4-config.h" @@ -385,8 +386,8 @@ update_connection (NMDevice *device, NMConnection *connection) NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), - setting_parent); + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), + setting_parent); if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection)) new_parent = NULL; } diff --git a/src/devices/nm-device-ip-tunnel.h b/src/devices/nm-device-ip-tunnel.h index 11cb5bce..94cc7375 100644 --- a/src/devices/nm-device-ip-tunnel.h +++ b/src/devices/nm-device-ip-tunnel.h @@ -24,8 +24,6 @@ #include "nm-core-types.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type ()) #define NM_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) #define NM_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) @@ -55,6 +53,4 @@ typedef struct { GType nm_device_ip_tunnel_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_IP_TUNNEL_H */ +#endif /* __NETWORKMANAGER_DEVICE_IP_TUNNEL_H__ */ diff --git a/src/devices/nm-device-logging.h b/src/devices/nm-device-logging.h index 1be17073..fac92eac 100644 --- a/src/devices/nm-device-logging.h +++ b/src/devices/nm-device-logging.h @@ -21,7 +21,6 @@ #ifndef __NETWORKMANAGER_DEVICE_LOGGING_H__ #define __NETWORKMANAGER_DEVICE_LOGGING_H__ -#include "nm-default.h" #include "nm-device.h" #define _LOG_DECLARE_SELF(t) \ diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index c431fe89..2bfc65cb 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -20,11 +20,12 @@ #include "nm-default.h" +#include "nm-device-macvlan.h" + #include <string.h> -#include "nm-device-macvlan.h" #include "nm-device-private.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-activation-request.h" #include "nm-manager.h" #include "nm-platform.h" @@ -372,9 +373,8 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw if (!priv->parent) return !fail_if_no_hwaddr; - parent_mac = nm_device_get_hw_address (priv->parent); - - return nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); + parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE); + return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); } static gboolean @@ -488,7 +488,7 @@ update_connection (NMDevice *device, NMConnection *connection) NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent); + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent); if (parent_connection && nm_device_check_connection_compatible (priv->parent, parent_connection)) new_parent = NULL; } @@ -502,8 +502,6 @@ update_connection (NMDevice *device, NMConnection *connection) static NMActStageReturn act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { - NMSettingWired *s_wired; - const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -512,14 +510,9 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED); - if (s_wired) { - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_HW); - } - - return TRUE; + if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE)) + return NM_ACT_STAGE_RETURN_FAILURE; + return NM_ACT_STAGE_RETURN_SUCCESS; } static void @@ -548,16 +541,6 @@ realize_start_notify (NMDevice *device, const NMPlatformLink *plink) update_properties (device); } -static void -deactivate (NMDevice *device) -{ - /* Reset MAC address back to initial address */ - if (nm_device_get_initial_hw_address (device)) { - nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), - "reset", LOGD_DEVICE); - } -} - /******************************************************************/ static void @@ -638,7 +621,6 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) device_class->complete_connection = complete_connection; device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME; device_class->create_and_realize = create_and_realize; - device_class->deactivate = deactivate; device_class->get_generic_capabilities = get_generic_capabilities; device_class->ip4_config_pre_commit = ip4_config_pre_commit; device_class->is_available = is_available; diff --git a/src/devices/nm-device-macvlan.h b/src/devices/nm-device-macvlan.h index 89f670bd..5756f696 100644 --- a/src/devices/nm-device-macvlan.h +++ b/src/devices/nm-device-macvlan.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type ()) #define NM_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) #define NM_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) @@ -42,6 +40,4 @@ typedef NMDeviceClass NMDeviceMacvlanClass; GType nm_device_macvlan_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_MACVLAN_H */ +#endif /* __NETWORKMANAGER_DEVICE_MACVLAN_H__ */ diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 602c2c85..c85cb969 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -24,8 +24,6 @@ #include "nm-device.h" -#include "nm-default.h" - /* This file should only be used by subclasses of NMDevice */ enum NMActStageReturn { @@ -42,6 +40,8 @@ enum NMActStageReturn { #define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000 +NMSettings *nm_device_get_settings (NMDevice *self); + void nm_device_set_ip_iface (NMDevice *self, const char *iface); void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device); @@ -54,8 +54,9 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar void nm_device_take_down (NMDevice *self, gboolean block); -gboolean nm_device_set_hw_addr (NMDevice *device, const char *addr, - const char *detail, guint64 hw_log_domain); +gboolean nm_device_hw_addr_set (NMDevice *device, const char *addr, const char *detail); +gboolean nm_device_hw_addr_set_cloned (NMDevice *device, NMConnection *connection, gboolean is_wifi); +gboolean nm_device_hw_addr_reset (NMDevice *device, const char *detail); void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); @@ -70,9 +71,11 @@ void nm_device_activate_schedule_ip6_config_timeout (NMDevice *device); gboolean nm_device_activate_ip4_state_in_conf (NMDevice *device); gboolean nm_device_activate_ip4_state_in_wait (NMDevice *device); +gboolean nm_device_activate_ip4_state_done (NMDevice *device); gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device); gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device); +gboolean nm_device_activate_ip6_state_done (NMDevice *device); void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr); @@ -103,6 +106,10 @@ void nm_device_queue_recheck_available (NMDevice *device, void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config); void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config); +gboolean nm_device_hw_addr_is_explict (NMDevice *device); + +void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason); + gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value); #define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 01cd8ea6..1f42d060 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -291,8 +291,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - NMSettingWired *s_wired; - const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -305,12 +303,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) if (g_strcmp0 (priv->mode, "tap")) return NM_ACT_STAGE_RETURN_SUCCESS; - s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); - if (s_wired) { - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE); - } + if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE)) + return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_SUCCESS; } diff --git a/src/devices/nm-device-tun.h b/src/devices/nm-device-tun.h index 32dcfd47..d62b0c37 100644 --- a/src/devices/nm-device-tun.h +++ b/src/devices/nm-device-tun.h @@ -23,8 +23,6 @@ #include "nm-device-generic.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type ()) #define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) #define NM_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) @@ -44,6 +42,4 @@ typedef NMDeviceClass NMDeviceTunClass; GType nm_device_tun_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_TUN_H */ +#endif /* __NETWORKMANAGER_DEVICE_TUN_H__ */ diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index ff198a7d..cca86fbe 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -38,23 +38,44 @@ #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceVeth); -G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) - -#define NM_DEVICE_VETH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VETH, NMDeviceVethPrivate)) +/*****************************************************************************/ typedef struct { NMDevice *peer; gboolean ever_had_peer; } NMDeviceVethPrivate; -enum { - PROP_0, - PROP_PEER, +struct _NMDeviceVeth { + NMDeviceEthernet parent; + NMDeviceVethPrivate _priv; +}; - LAST_PROP +struct _NMDeviceVethClass { + NMDeviceEthernetClass parent_class; }; -/**************************************************************/ +NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVeth, + PROP_PEER, +); + +/*****************************************************************************/ + +G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) + +#define NM_DEVICE_VETH_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMDeviceVeth *_self2 = (_self); \ + \ + nm_assert (NM_IS_DEVICE_VETH (_self)); \ + &_self->_priv; \ + }) + +/*****************************************************************************/ static void set_peer (NMDeviceVeth *self, NMDevice *peer) @@ -66,7 +87,7 @@ set_peer (NMDeviceVeth *self, NMDevice *peer) priv->peer = peer; g_object_add_weak_pointer (G_OBJECT (peer), (gpointer *) &priv->peer); - g_object_notify (G_OBJECT (self), NM_DEVICE_VETH_PEER); + _notify (self, PROP_PEER); } } @@ -150,8 +171,6 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - g_type_class_add_private (klass, sizeof (NMDeviceVethPrivate)); - NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VETH) object_class->get_property = get_property; @@ -159,13 +178,13 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) device_class->can_unmanaged_external_down = can_unmanaged_external_down; - /* properties */ - g_object_class_install_property - (object_class, PROP_PEER, - g_param_spec_string (NM_DEVICE_VETH_PEER, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_PEER] = + g_param_spec_string (NM_DEVICE_VETH_PEER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_VETH_SKELETON, diff --git a/src/devices/nm-device-veth.h b/src/devices/nm-device-veth.h index c7b8ec3a..53ccf925 100644 --- a/src/devices/nm-device-veth.h +++ b/src/devices/nm-device-veth.h @@ -23,8 +23,6 @@ #include "nm-device-ethernet.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_VETH (nm_device_veth_get_type ()) #define NM_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VETH, NMDeviceVeth)) #define NM_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) @@ -34,11 +32,9 @@ G_BEGIN_DECLS #define NM_DEVICE_VETH_PEER "peer" -typedef NMDeviceEthernet NMDeviceVeth; -typedef NMDeviceEthernetClass NMDeviceVethClass; +typedef struct _NMDeviceVeth NMDeviceVeth; +typedef struct _NMDeviceVethClass NMDeviceVethClass; GType nm_device_veth_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_VETH_H */ +#endif /* __NETWORKMANAGER_DEVICE_VETH_H__ */ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index eb6527de..16edc0d2 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -20,15 +20,16 @@ #include "nm-default.h" +#include "nm-device-vlan.h" + #include <sys/socket.h> -#include "nm-device-vlan.h" #include "nm-manager.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-enum-types.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-activation-request.h" #include "nm-ip4-config.h" #include "nm-platform.h" @@ -86,7 +87,6 @@ parent_hwaddr_maybe_changed (NMDevice *parent, { NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); NMConnection *connection; - NMSettingWired *s_wired; const char *new_mac, *old_mac; NMSettingIPConfig *s_ip6; @@ -99,11 +99,8 @@ parent_hwaddr_maybe_changed (NMDevice *parent, return; /* Update the VLAN MAC only if configuration does not specify one */ - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) { - if (nm_setting_wired_get_cloned_mac_address (s_wired)) - return; - } + if (nm_device_hw_addr_is_explict (self)) + return; old_mac = nm_device_get_hw_address (self); new_mac = nm_device_get_hw_address (parent); @@ -113,7 +110,7 @@ parent_hwaddr_maybe_changed (NMDevice *parent, _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", NM_PRINT_FMT_QUOTE_STRING (new_mac)); if (new_mac) { - nm_device_set_hw_addr (self, new_mac, "set", LOGD_VLAN); + nm_device_hw_addr_set (self, new_mac, "vlan-parent"); /* When changing the hw address the interface is taken down, * removing the IPv6 configuration; reapply it. */ @@ -377,21 +374,25 @@ match_parent (NMDeviceVlan *self, const char *parent) static gboolean match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) { - NMSettingWired *s_wired; - const char *setting_mac; - const char *device_mac; + NMDeviceVlanPrivate *priv; + NMSettingWired *s_wired; + const char *setting_mac; + const char *parent_mac; - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired) - return !fail_if_no_hwaddr; + s_wired = nm_connection_get_setting_wired (connection); + if (!s_wired) + return !fail_if_no_hwaddr; - setting_mac = nm_setting_wired_get_mac_address (s_wired); - if (!setting_mac) - return !fail_if_no_hwaddr; + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (!setting_mac) + return !fail_if_no_hwaddr; - device_mac = nm_device_get_hw_address (device); + priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + if (!priv->parent) + return !fail_if_no_hwaddr; - return nm_utils_hwaddr_matches (setting_mac, -1, device_mac, -1); + parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE); + return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); } static gboolean @@ -515,7 +516,7 @@ update_connection (NMDevice *device, NMConnection *connection) NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent); + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent); if (parent_connection && nm_device_check_connection_compatible (priv->parent, parent_connection)) new_parent = NULL; } @@ -549,8 +550,6 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (dev); NMSettingVlan *s_vlan; - NMSettingWired *s_wired; - const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -559,12 +558,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED); - if (s_wired) { - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN); - } + if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE)) + return NM_ACT_STAGE_RETURN_FAILURE; /* Change MAC address to parent's one if needed */ if (priv->parent) @@ -618,14 +613,6 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) } } -static void -deactivate (NMDevice *device) -{ - /* Reset MAC address back to initial address */ - if (nm_device_get_initial_hw_address (device)) - nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_VLAN); -} - /******************************************************************/ static void @@ -689,7 +676,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) parent_class->bring_up = bring_up; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->ip4_config_pre_commit = ip4_config_pre_commit; - parent_class->deactivate = deactivate; parent_class->is_available = is_available; parent_class->notify_new_device_added = notify_new_device_added; diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h index e31e171d..71ca8030 100644 --- a/src/devices/nm-device-vlan.h +++ b/src/devices/nm-device-vlan.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type ()) #define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) #define NM_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) @@ -47,6 +45,4 @@ typedef NMDeviceClass NMDeviceVlanClass; GType nm_device_vlan_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_VLAN_H */ +#endif /* __NETWORKMANAGER_DEVICE_VLAN_H__ */ diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 45f33bdd..674c2a78 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -20,9 +20,10 @@ #include "nm-default.h" +#include "nm-device-vxlan.h" + #include <string.h> -#include "nm-device-vxlan.h" #include "nm-device-private.h" #include "nm-manager.h" #include "nm-platform.h" @@ -30,7 +31,7 @@ #include "nm-device-factory.h" #include "nm-setting-vxlan.h" #include "nm-setting-wired.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-activation-request.h" #include "nm-ip4-config.h" @@ -417,8 +418,8 @@ update_connection (NMDevice *device, NMConnection *connection) NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), - setting_parent); + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), + setting_parent); if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection)) new_parent = NULL; } @@ -510,8 +511,6 @@ update_connection (NMDevice *device, NMConnection *connection) static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { - NMSettingWired *s_wired; - const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -520,12 +519,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); - if (s_wired) { - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE); - } + if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE)) + return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_SUCCESS; } diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index 7de04a12..71204d3b 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -23,8 +23,6 @@ #include "nm-device-generic.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type ()) #define NM_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) #define NM_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) @@ -54,6 +52,4 @@ typedef NMDeviceClass NMDeviceVxlanClass; GType nm_device_vxlan_get_type (void); -G_END_DECLS - -#endif /* NM_DEVICE_VXLAN_H */ +#endif /* __NETWORKMANAGER_DEVICE_VXLAN_H__ */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 62259bc4..199acc66 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -21,6 +21,8 @@ #include "nm-default.h" +#include "nm-device.h" + #include <netinet/in.h> #include <string.h> #include <unistd.h> @@ -52,7 +54,7 @@ #include "nm-firewall-manager.h" #include "nm-enum-types.h" #include "nm-settings-connection.h" -#include "nm-connection-provider.h" +#include "nm-settings.h" #include "nm-auth-utils.h" #include "nm-dispatcher.h" #include "nm-config.h" @@ -69,10 +71,22 @@ _LOG_DECLARE_SELF (NMDevice); #include "nmdbus-device.h" +#include "nmdbus-device-statistics.h" G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT) -#define NM_DEVICE_GET_PRIVATE(o) ((o)->priv) +#define NM_DEVICE_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMDevice *_self2 = (_self); \ + \ + nm_assert (NM_IS_DEVICE (_self)); \ + _self->priv; \ + }) enum { STATE_CHANGED, @@ -119,11 +133,15 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice, PROP_IS_MASTER, PROP_MASTER, PROP_HW_ADDRESS, + PROP_PERM_HW_ADDRESS, PROP_HAS_PENDING_ACTION, PROP_METERED, PROP_LLDP_NEIGHBORS, PROP_REAL, PROP_SLAVES, + PROP_REFRESH_RATE_MS, + PROP_TX_BYTES, + PROP_RX_BYTES, ); #define DEFAULT_AUTOCONNECT TRUE @@ -134,6 +152,9 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice, #define PENDING_ACTION_DHCP6 "dhcp6" #define PENDING_ACTION_AUTOCONF6 "autoconf6" +#define DHCP_RESTART_TIMEOUT 120 +#define DHCP_NUM_TRIES_MAX 3 + typedef void (*ActivationHandleFunc) (NMDevice *self); typedef struct { @@ -142,9 +163,9 @@ typedef struct { } ActivationHandleData; typedef enum { - CLEANUP_TYPE_DECONFIGURE, CLEANUP_TYPE_KEEP, CLEANUP_TYPE_REMOVED, + CLEANUP_TYPE_DECONFIGURE, } CleanupType; typedef enum { @@ -163,9 +184,9 @@ typedef struct { typedef struct { NMDevice *slave; - gboolean slave_is_enslaved; - gboolean configure; gulong watch_id; + bool slave_is_enslaved; + bool configure; } SlaveInfo; typedef struct { @@ -192,8 +213,15 @@ typedef struct { NMIP4Config **configs; } ArpingData; +typedef enum { + HW_ADDR_TYPE_UNSET = 0, + HW_ADDR_TYPE_PERMANENT, + HW_ADDR_TYPE_EXPLICIT, + HW_ADDR_TYPE_GENERATED, +} HwAddrType; + typedef struct _NMDevicePrivate { - gboolean in_state_changed; + bool in_state_changed; guint device_link_changed_id; guint device_ip_link_changed_id; @@ -209,7 +237,12 @@ typedef struct _NMDevicePrivate { char * udi; char * iface; /* may change, could be renamed by user */ int ifindex; - gboolean real; + + guint hw_addr_len; + guint8 /*HwAddrType*/ hw_addr_type; + + bool real; + char * ip_iface; int ip_ifindex; NMDeviceType type; @@ -221,19 +254,19 @@ typedef struct _NMDevicePrivate { char * driver_version; char * firmware_version; RfKillType rfkill_type; - gboolean firmware_missing; - gboolean nm_plugin_missing; + bool firmware_missing:1; + bool nm_plugin_missing:1; + bool hw_addr_perm_fake:1; /* whether the permanent HW address could not be read and is a fake */ GHashTable * available_connections; char * hw_addr; - guint hw_addr_len; - char * perm_hw_addr; - char * initial_hw_addr; + char * hw_addr_perm; + char * hw_addr_initial; char * physical_port_id; guint dev_id; NMUnmanagedFlags unmanaged_mask; NMUnmanagedFlags unmanaged_flags; - gboolean is_nm_owned; /* whether the device is a device owned and created by NM */ + bool 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; @@ -241,7 +274,7 @@ typedef struct _NMDevicePrivate { guint32 ip4_address; NMActRequest * queued_act_request; - gboolean queued_act_request_is_waiting_for_carrier; + bool queued_act_request_is_waiting_for_carrier; NMActRequest * act_request; ActivationHandleData act_handle4; /* for layer2 and IPv4. */ ActivationHandleData act_handle6; @@ -261,11 +294,12 @@ typedef struct _NMDevicePrivate { guint link_connected_id; guint link_disconnected_id; guint carrier_defer_id; - gboolean carrier; + bool carrier; guint carrier_wait_id; - gboolean ignore_carrier; + bool ignore_carrier; + gulong ignore_carrier_id; guint32 mtu; - gboolean up; /* IFF_UP */ + bool up; /* IFF_UP */ /* Generic DHCP stuff */ guint32 dhcp_timeout; @@ -288,14 +322,17 @@ typedef struct _NMDevicePrivate { NMPlatformIP6Route v6; } default_route; - gboolean v4_commit_first_time; - gboolean v6_commit_first_time; + bool v4_commit_first_time; + bool v6_commit_first_time; /* DHCPv4 tracking */ - NMDhcpClient * dhcp4_client; - gulong dhcp4_state_sigid; - NMDhcp4Config * dhcp4_config; - guint dhcp4_restart_id; + struct { + NMDhcpClient * client; + gulong state_sigid; + NMDhcp4Config * config; + guint restart_id; + guint num_tries_left; + } dhcp4; PingInfo gw_ping; @@ -304,7 +341,7 @@ typedef struct _NMDevicePrivate { gulong dnsmasq_state_id; /* Firewall */ - gboolean fw_ready; + bool fw_ready; NMFirewallManagerCallId fw_call; /* IPv4LL stuff */ @@ -325,8 +362,9 @@ typedef struct _NMDevicePrivate { NMIP6Config * ext_ip6_config; /* Stuff added outside NM */ NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */ GSList * vpn6_configs; /* VPNs which use this device */ - gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */ + bool nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */ guint32 ip6_mtu; + NMIP6Config * dad6_ip6_config; NMRDisc * rdisc; gulong rdisc_changed_id; @@ -340,35 +378,47 @@ typedef struct _NMDevicePrivate { GHashTable * ip6_saved_properties; - NMDhcpClient * dhcp6_client; - NMRDiscDHCPLevel dhcp6_mode; - gulong dhcp6_state_sigid; - NMDhcp6Config * dhcp6_config; - /* IP6 config from DHCP */ - NMIP6Config * dhcp6_ip6_config; - /* Event ID of the current IP6 config from DHCP */ - char * dhcp6_event_id; - guint dhcp6_restart_id; + struct { + NMDhcpClient * client; + NMRDiscDHCPLevel mode; + gulong state_sigid; + NMDhcp6Config * config; + /* IP6 config from DHCP */ + NMIP6Config * ip6_config; + /* Event ID of the current IP6 config from DHCP */ + char * event_id; + guint restart_id; + guint num_tries_left; + } dhcp6; /* allow autoconnect feature */ - gboolean autoconnect; + bool autoconnect; /* master interface for bridge/bond/team slave */ NMDevice * master; - gboolean is_enslaved; - gboolean master_ready_handled; + bool is_enslaved; + bool master_ready_handled; gulong master_ready_id; /* slave management */ - gboolean is_master; + bool is_master; GSList * slaves; /* list of SlaveInfo */ NMMetered metered; - NMConnectionProvider *con_provider; + NMSettings *settings; + NMLldpListener *lldp_listener; guint check_delete_unrealized_id; + + struct { + guint timeout_id; + guint refresh_rate_ms; + guint64 tx_bytes; + guint64 rx_bytes; + } stats; + } NMDevicePrivate; static gboolean nm_device_set_ip4_config (NMDevice *self, @@ -417,6 +467,8 @@ static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceState static void nm_device_start_ip_check (NMDevice *self); static void realize_start_setup (NMDevice *self, const NMPlatformLink *plink); static void nm_device_set_mtu (NMDevice *self, guint32 mtu); +static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason); +static void _cancel_activation (NMDevice *self); /***********************************************************/ @@ -524,6 +576,12 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason, /***********************************************************/ +NMSettings * +nm_device_get_settings (NMDevice *self) +{ + return NM_DEVICE_GET_PRIVATE (self)->settings; +} + static void init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config) { @@ -570,6 +628,41 @@ nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps) return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->capabilities, caps); } +static void +_add_capabilities (NMDevice *self, NMDeviceCapabilities capabilities) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (!NM_FLAGS_ALL (priv->capabilities, capabilities)) { + priv->capabilities |= capabilities; + _notify (self, PROP_CAPABILITIES); + } +} + +/***********************************************************/ + +static const char * +_get_stable_id (NMConnection *connection, NMUtilsStableType *out_stable_type) +{ + NMSettingConnection *s_con; + const char *stable_id; + + nm_assert (NM_IS_CONNECTION (connection)); + nm_assert (out_stable_type); + + s_con = nm_connection_get_setting_connection (connection); + g_return_val_if_fail (s_con, NULL); + + stable_id = nm_setting_connection_get_stable_id (s_con); + if (!stable_id) { + *out_stable_type = NM_UTILS_STABLE_TYPE_UUID; + return nm_connection_get_uuid (connection); + } + + *out_stable_type = NM_UTILS_STABLE_TYPE_STABLE_ID; + return stable_id; +} + /***********************************************************/ const char * @@ -688,43 +781,175 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) g_free (old_ip_iface); } +/*****************************************************************************/ + +static void +_stats_update_counters (NMDevice *self, + guint64 tx_bytes, + guint64 rx_bytes) +{ + NMDevicePrivate *priv; + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->stats.tx_bytes != tx_bytes) { + priv->stats.tx_bytes = tx_bytes; + _notify (self, PROP_TX_BYTES); + } + if (priv->stats.rx_bytes != rx_bytes) { + priv->stats.rx_bytes = rx_bytes; + _notify (self, PROP_RX_BYTES); + } +} + +static void +_stats_update_counters_from_pllink (NMDevice *self, const NMPlatformLink *pllink) +{ + _stats_update_counters (self, pllink->tx_bytes, pllink->rx_bytes); +} + +static gboolean +_stats_timeout_cb (gpointer user_data) +{ + NMDevice *self = user_data; + int ifindex; + + ifindex = nm_device_get_ip_ifindex (self); + + _LOGT (LOGD_DEVICE, "stats: refresh %d", ifindex); + + if (ifindex > 0) + nm_platform_link_refresh (NM_PLATFORM_GET, ifindex); + + return G_SOURCE_CONTINUE; +} + +static guint +_stats_refresh_rate_real (guint refresh_rate_ms) +{ + const guint STATS_REFRESH_RATE_MS_MIN = 200; + + if (refresh_rate_ms == 0) + return 0; + + if (refresh_rate_ms < STATS_REFRESH_RATE_MS_MIN) { + /* you cannot set the refresh-rate arbitrarly small. E.g. + * setting to 1ms is just killing. Have a lowest number. */ + return STATS_REFRESH_RATE_MS_MIN; + } + + return refresh_rate_ms; +} + +static void +_stats_set_refresh_rate (NMDevice *self, guint refresh_rate_ms) +{ + NMDevicePrivate *priv; + int ifindex; + guint old_rate; + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->stats.refresh_rate_ms == refresh_rate_ms) + return; + + old_rate = priv->stats.refresh_rate_ms; + priv->stats.refresh_rate_ms = refresh_rate_ms; + _notify (self, PROP_REFRESH_RATE_MS); + + _LOGD (LOGD_DEVICE, "stats: set refresh to %u ms", priv->stats.refresh_rate_ms); + + if (!nm_device_is_real (self)) + return; + + refresh_rate_ms = _stats_refresh_rate_real (refresh_rate_ms); + if (_stats_refresh_rate_real (old_rate) == refresh_rate_ms) + return; + + nm_clear_g_source (&priv->stats.timeout_id); + + if (!refresh_rate_ms) + return; + + /* trigger an inital refresh of the data whenever the refresh-rate changes. + * As we process the result in an idle handler with device_link_changed(), + * we don't get the result right away. */ + ifindex = nm_device_get_ip_ifindex (self); + if (ifindex > 0) + nm_platform_link_refresh (NM_PLATFORM_GET, ifindex); + + priv->stats.timeout_id = g_timeout_add (refresh_rate_ms, _stats_timeout_cb, self); +} + +/*****************************************************************************/ + 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; + const NMPlatformLink *pllink; int ifindex; gboolean success; /* If we get here, we *must* have a kernel netdev, which implies an ifindex */ ifindex = nm_device_get_ip_ifindex (self); - g_assert (ifindex); + g_return_val_if_fail (ifindex > 0, FALSE); - link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex); - g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0); + pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); + if ( !pllink + || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN)) + return FALSE; - hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len); - if (!hwaddr_len) + if (pllink->addr.len <= 0) return FALSE; + if (pllink->addr.len > NM_UTILS_HWADDR_LEN_MAX) + g_return_val_if_reached (FALSE); - success = nm_utils_get_ipv6_interface_identifier (link_type, - hwaddr, - hwaddr_len, + success = nm_utils_get_ipv6_interface_identifier (pllink->type, + pllink->addr.data, + pllink->addr.len, priv->dev_id, out_iid); if (!success) { _LOGW (LOGD_HW, "failed to generate interface identifier " - "for link type %u hwaddr_len %zu", link_type, hwaddr_len); + "for link type %u hwaddr_len %u", pllink->type, (unsigned) pllink->addr.len); } return success; } +/** + * nm_device_get_ip_iface_identifier: + * @self: an #NMDevice + * @iid: where to place the interface identifier + * @ignore_token: force creation of a non-tokenized address + * + * Return the interface's identifier for the EUI64 address generation mode. + * It's either a manually set token or and identifier generated in a + * hardware-specific way. + * + * Unless @ignore_token is set the token is preferred. That is the case + * for link-local addresses (to mimic kernel behavior). + * + * Returns: #TRUE if the @iid could be set + */ static gboolean -nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid) +nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token) { - return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); + NMSettingIP6Config *s_ip6; + const char *token = NULL; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + if (!ignore_token) { + s_ip6 = (NMSettingIP6Config *) + nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG); + g_return_val_if_fail (s_ip6, FALSE); + token = nm_setting_ip6_config_get_token (s_ip6); + } + if (token) + return nm_utils_ipv6_interface_identifier_get_from_token (iid, token); + else + return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); } const char * @@ -1029,7 +1254,11 @@ nm_device_get_settings_connection (NMDevice *self) NMConnection * nm_device_get_applied_connection (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL; } @@ -1046,23 +1275,12 @@ nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFla } NMSetting * -nm_device_get_applied_setting (NMDevice *device, GType setting_type) +nm_device_get_applied_setting (NMDevice *self, GType setting_type) { - NMActRequest *req; - NMSetting *setting = NULL; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - req = nm_device_get_act_request (device); - if (req) { - NMConnection *connection; - - connection = nm_act_request_get_applied_connection (req); - if (connection) - setting = nm_connection_get_setting (connection, setting_type); - } + NMConnection *connection; - return setting; + connection = nm_device_get_applied_connection (self); + return connection ? nm_connection_get_setting (connection, setting_type) : NULL; } RfKillType @@ -1355,7 +1573,7 @@ nm_device_update_dynamic_ip_setup (NMDevice *self) g_hash_table_remove_all (priv->ip6_saved_properties); - if (priv->dhcp4_client) { + if (priv->dhcp4.client) { if (!nm_device_dhcp4_renew (self, FALSE)) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, @@ -1363,7 +1581,7 @@ nm_device_update_dynamic_ip_setup (NMDevice *self) return; } } - if (priv->dhcp6_client) { + if (priv->dhcp6.client) { if (!nm_device_dhcp6_renew (self, FALSE)) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, @@ -1467,8 +1685,6 @@ link_disconnect_action_cb (gpointer user_data) priv->carrier_defer_id = 0; - _LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)"); - NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE); return FALSE; @@ -1508,11 +1724,11 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier) 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"); + } else if ( state <= NM_DEVICE_STATE_DISCONNECTED + && !priv->queued_act_request) { + _LOGD (LOGD_DEVICE, "link disconnected"); klass->carrier_changed (self, FALSE); } else { - _LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY); priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY, link_disconnect_action_cb, self); _LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)", @@ -1563,13 +1779,14 @@ device_link_changed (NMDevice *self) { NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMUtilsIPv6IfaceId token_iid; gboolean ip_ifname_changed = FALSE; const char *udi; NMPlatformLink info; const NMPlatformLink *pllink; int ifindex; gboolean was_up; + gboolean update_unmanaged_specs = FALSE; + gboolean got_hw_addr = FALSE, had_hw_addr; priv->device_link_changed_id = 0; @@ -1607,6 +1824,14 @@ device_link_changed (NMDevice *self) _notify (self, PROP_DRIVER); } + if (ifindex == nm_device_get_ip_ifindex (self)) + _stats_update_counters_from_pllink (self, &info); + + had_hw_addr = (priv->hw_addr != NULL); + nm_device_update_hw_address (self); + got_hw_addr = (!had_hw_addr && priv->hw_addr); + nm_device_update_permanent_hw_address (self); + if (info.name[0] && strcmp (priv->iface, info.name) != 0) { _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'", priv->ifindex, priv->iface, info.name); @@ -1616,6 +1841,11 @@ device_link_changed (NMDevice *self) /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */ ip_ifname_changed = !priv->ip_iface; + if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) + nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings)); + else + update_unmanaged_specs = TRUE; + _notify (self, PROP_IFACE); if (ip_ifname_changed) _notify (self, PROP_IP_IFACE); @@ -1629,10 +1859,11 @@ device_link_changed (NMDevice *self) nm_device_emit_recheck_auto_activate (self); } - if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) { - _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); - if (nm_rdisc_set_iid (priv->rdisc, token_iid)) + if (priv->rdisc && info.inet6_token.id) { + if (nm_rdisc_set_iid (priv->rdisc, info.inet6_token)) { + _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); nm_rdisc_start (priv->rdisc); + } } if (klass->link_changed) @@ -1651,18 +1882,23 @@ device_link_changed (NMDevice *self) nm_device_set_unmanaged_by_user_udev (self); + reason = NM_DEVICE_STATE_REASON_NOW_MANAGED; + /* If the device is a external-down candidated but no longer has external * down set, we must clear the platform-unmanaged flag with reason * "assumed". */ if ( nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN) && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) { - /* Ensure the assume check is queued before any queued state changes - * from the transition to UNAVAILABLE. - */ - nm_device_queue_recheck_assume (self); - reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; - } else - reason = NM_DEVICE_STATE_REASON_NOW_MANAGED; + /* actually, user-udev overwrites external-down. So we only assume the device, + * when it is a external-down candidate, which is not managed via udev. */ + if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_UDEV)) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume (self); + reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; + } + } nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason); } @@ -1684,6 +1920,23 @@ device_link_changed (NMDevice *self) } } + if (update_unmanaged_specs) + nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings)); + + if ( got_hw_addr + && !priv->up + && nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE) { + /* + * If the device is UNAVAILABLE, any previous try to + * bring it up probably has failed because of the + * invalid hardware address; try again. + */ + nm_device_bring_up (self, TRUE, NULL); + nm_device_queue_recheck_available (self, + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_NONE); + } + return G_SOURCE_REMOVE; } @@ -1702,6 +1955,8 @@ device_ip_link_changed (NMDevice *self) if (!pllink) return G_SOURCE_REMOVE; + _stats_update_counters_from_pllink (self, pllink); + if (pllink->name[0] && g_strcmp0 (priv->ip_iface, pllink->name)) { _LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'", priv->ifindex, nm_device_get_ip_ifindex (self), @@ -1712,6 +1967,7 @@ device_ip_link_changed (NMDevice *self) _notify (self, PROP_IP_IFACE); nm_device_update_dynamic_ip_setup (self); } + return G_SOURCE_REMOVE; } @@ -1817,6 +2073,8 @@ nm_device_realize_start (NMDevice *self, gboolean *out_compatible, GError **error) { + NMPlatformLink plink_copy; + NM_SET_OUT (out_compatible, TRUE); if (plink) { @@ -1831,6 +2089,10 @@ nm_device_realize_start (NMDevice *self, return FALSE; } + if (plink) { + plink_copy = *plink; + plink = &plink_copy; + } realize_start_setup (self, plink); return TRUE; @@ -1962,6 +2224,9 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) NMDevicePrivate *priv; NMDeviceClass *klass; static guint32 id = 0; + NMDeviceCapabilities capabilities = 0; + NMConfig *config; + guint real_rate; g_return_if_fail (NM_IS_DEVICE (self)); @@ -1985,6 +2250,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) if (plink) { g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL)); update_device_from_platform_link (self, plink); + _stats_update_counters_from_pllink (self, plink); } if (priv->ifindex > 0) { @@ -1994,7 +2260,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex); if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex)) - priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; + capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex); _notify (self, PROP_MTU); @@ -2014,7 +2280,9 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) } if (klass->get_generic_capabilities) - priv->capabilities |= klass->get_generic_capabilities (self); + capabilities |= klass->get_generic_capabilities (self); + + _add_capabilities (self, capabilities); if (!priv->udi) { /* Use a placeholder UDI until we get a real one */ @@ -2028,17 +2296,19 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) nm_device_update_hw_address (self); nm_device_update_initial_hw_address (self); + nm_device_update_permanent_hw_address (self); /* Note: initial hardware address must be read before calling get_ignore_carrier() */ - if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - NMConfig *config = nm_config_get (); - - priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self); - g_signal_connect (G_OBJECT (config), - NM_CONFIG_SIGNAL_CONFIG_CHANGED, - G_CALLBACK (config_changed_update_ignore_carrier), - self); + config = nm_config_get (); + priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self); + if (!priv->ignore_carrier_id) { + priv->ignore_carrier_id = g_signal_connect (config, + NM_CONFIG_SIGNAL_CONFIG_CHANGED, + G_CALLBACK (config_changed_update_ignore_carrier), + self); + } + if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { check_carrier (self); _LOGD (LOGD_HW, "carrier is %s%s", @@ -2049,7 +2319,10 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) priv->carrier = TRUE; } - _notify (self, PROP_CAPABILITIES); + nm_assert (!priv->stats.timeout_id); + real_rate = _stats_refresh_rate_real (priv->stats.refresh_rate_ms); + if (real_rate) + priv->stats.timeout_id = g_timeout_add (real_rate, _stats_timeout_cb, self); klass->realize_start_notify (self, plink); @@ -2214,6 +2487,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) _notify (self, PROP_UDI); } if (priv->hw_addr) { + priv->hw_addr_len = 0; g_clear_pointer (&priv->hw_addr, g_free); _notify (self, PROP_HW_ADDRESS); } @@ -2222,14 +2496,21 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) _notify (self, PROP_PHYSICAL_PORT_ID); } - g_clear_pointer (&priv->perm_hw_addr, g_free); - g_clear_pointer (&priv->initial_hw_addr, g_free); + nm_clear_g_source (&priv->stats.timeout_id); + _stats_update_counters (self, 0, 0); + + priv->hw_addr_type = HW_ADDR_TYPE_UNSET; + g_clear_pointer (&priv->hw_addr_perm, g_free); + _notify (self, PROP_PERM_HW_ADDRESS); + g_clear_pointer (&priv->hw_addr_initial, g_free); priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); _notify (self, PROP_CAPABILITIES); + nm_clear_g_signal_handler (nm_config_get (), &priv->ignore_carrier_id); + priv->real = FALSE; _notify (self, PROP_REAL); @@ -2660,6 +2941,8 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) nm_connection_get_id (connection), master_status); + /* Cancel any pending activation sources */ + _cancel_activation (self); nm_device_queue_state (self, new_state, reason); } else _LOGI (LOGD_DEVICE, "released from master device %s", nm_device_get_iface (priv->master)); @@ -2999,6 +3282,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) gs_free char *uuid = NULL; const char *ip4_method, *ip6_method; GError *error = NULL; + const NMPlatformLink *pllink; /* If update_connection() is not implemented, just fail. */ if (!klass->update_connection) @@ -3045,6 +3329,15 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) s_ip6 = nm_ip6_config_create_setting (priv->ip6_config); nm_connection_add_setting (connection, s_ip6); + + pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex); + if (pllink && pllink->inet6_token.id) { + _LOGD (LOGD_IP6, "IPv6 tokenized identifier present"); + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP6_CONFIG_TOKEN, nm_utils_inet6_interface_identifier_to_token (pllink->inet6_token, NULL), + NULL); + } } klass->update_connection (self, connection); @@ -3202,7 +3495,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave static gboolean nm_device_can_assume_connections (NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (self)->update_connection; + return !!NM_DEVICE_GET_CLASS (self)->update_connection; } /** @@ -3218,7 +3511,7 @@ nm_device_can_assume_connections (NMDevice *self) * if there is no active connection or the active connection cannot be * assumed. */ -gboolean +static gboolean nm_device_can_assume_active_connection (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -3255,16 +3548,55 @@ nm_device_can_assume_active_connection (NMDevice *self) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (!_nm_utils_string_in_list (method, assumable_ip6_methods)) + if (!g_strv_contains (assumable_ip6_methods, method)) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!_nm_utils_string_in_list (method, assumable_ip4_methods)) + if (!g_strv_contains (assumable_ip4_methods, method)) + return FALSE; + + return TRUE; +} + +static gboolean +unmanaged_on_quit (NMDevice *self) +{ + /* Leave certain devices alone when quitting so their configuration + * can be taken over when NM restarts. This ensures connectivity while + * NM is stopped. + */ + if (nm_device_uses_assumed_connection (self)) { + /* An assume connection must be left alone */ + return FALSE; + } + + if (!nm_device_get_act_request (self)) { + /* a device without any active connection is either UNAVAILABLE or DISCONNECTED + * state. Since we don't know whether the device was upped by NetworkManager, + * we must leave it up on exit. + */ + return FALSE; + } + + if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (self))) { + /* The device has no layer 3 configuration. Leave it up. */ + return FALSE; + } + + if (nm_device_can_assume_active_connection (self)) return FALSE; return TRUE; } +gboolean +nm_device_unmanage_on_quit (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self); +} + static gboolean nm_device_emit_recheck_assume (gpointer user_data) { @@ -3351,7 +3683,7 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us switch (status) { case NM_DNSMASQ_STATUS_DEAD: - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); break; default: break; @@ -3753,15 +4085,21 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) if (!priv->master_ready_handled) { NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); + NMActiveConnection *master; + + master = nm_active_connection_get_master (active); - if (!nm_active_connection_get_master (active)) { + if (!master) { g_warn_if_fail (!priv->master_ready_id); priv->master_ready_handled = TRUE; } else { /* If the master connection is ready for slaves, attach ourselves */ if (nm_active_connection_get_master_ready (active)) master_ready (self, active); - else { + else if (nm_active_connection_get_state (master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { + _LOGD (LOGD_DEVICE, "master connection is deactivating"); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + } else { _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); if (priv->master_ready_id == 0) { @@ -3815,6 +4153,26 @@ check_ip_failed (NMDevice *self, gboolean may_fail) NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } +void +nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail (family == AF_INET || family == AF_INET6); + priv = NM_DEVICE_GET_PRIVATE (self); + + if (family == AF_INET) + priv->ip4_state = IP_FAIL; + else + priv->ip6_state = IP_FAIL; + + if (get_ip_config_may_fail (self, family)) + check_ip_failed (self, FALSE); + else + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); +} + /* * check_ip_done * @@ -4050,14 +4408,14 @@ ipv4ll_get_ip4_config (NMDevice *self, guint32 lla) memset (&address, 0, sizeof (address)); nm_platform_ip4_address_set_addr (&address, lla, 16); - address.source = NM_IP_CONFIG_SOURCE_IP4LL; + address.addr_source = NM_IP_CONFIG_SOURCE_IP4LL; nm_ip4_config_add_address (config, &address); /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */ memset (&route, 0, sizeof (route)); route.network = htonl (0xE0000000L); route.plen = 4; - route.source = NM_IP_CONFIG_SOURCE_IP4LL; + route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL; route.metric = nm_device_get_ip4_route_metric (self); nm_ip4_config_add_route (config, &route); @@ -4094,23 +4452,20 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) r = sd_ipv4ll_get_address (ll, &address); if (r < 0) { _LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r); - priv->ip4_state = IP_FAIL; - check_ip_failed (self, FALSE); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); return; } if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) { _LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr); - priv->ip4_state = IP_FAIL; - check_ip_failed (self, FALSE); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } config = ipv4ll_get_ip4_config (self, address.s_addr); if (config == NULL) { _LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config"); - priv->ip4_state = IP_FAIL; - check_ip_failed (self, FALSE); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); return; } @@ -4120,8 +4475,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) } else if (priv->ip4_state == IP_DONE) { if (!ip4_config_merge_and_apply (self, config, TRUE, NULL)) { _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); - priv->ip4_state = IP_FAIL; - check_ip_failed (self, FALSE); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); } } else g_assert_not_reached (); @@ -4130,8 +4484,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) break; default: _LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event); - priv->ip4_state = IP_FAIL; - check_ip_failed (self, FALSE); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); } } @@ -4188,9 +4541,9 @@ ipv4ll_start (NMDevice *self, NMDeviceStateReason *reason) goto fail; } - r = sd_ipv4ll_set_index (priv->ipv4ll, ifindex); + r = sd_ipv4ll_set_ifindex (priv->ipv4ll, ifindex); if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: set_index() failed with error %d", r); + _LOGE (LOGD_AUTOIP4, "IPv4LL: set_ifindex() failed with error %d", r); goto fail; } @@ -4325,23 +4678,23 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - nm_clear_g_source (&priv->dhcp4_restart_id); + nm_clear_g_source (&priv->dhcp4.restart_id); - if (priv->dhcp4_client) { + if (priv->dhcp4.client) { /* Stop any ongoing DHCP transaction on this device */ - nm_clear_g_signal_handler (priv->dhcp4_client, &priv->dhcp4_state_sigid); + nm_clear_g_signal_handler (priv->dhcp4.client, &priv->dhcp4.state_sigid); nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) - nm_dhcp_client_stop (priv->dhcp4_client, release); + nm_dhcp_client_stop (priv->dhcp4.client, release); - g_clear_object (&priv->dhcp4_client); + g_clear_object (&priv->dhcp4.client); } - if (priv->dhcp4_config) { - nm_exported_object_clear_and_unexport (&priv->dhcp4_config); + if (priv->dhcp4.config) { + nm_exported_object_clear_and_unexport (&priv->dhcp4.config); _notify (self, PROP_DHCP4_CONFIG); } } @@ -4495,7 +4848,7 @@ ip4_config_merge_and_apply (NMDevice *self, priv->default_route.v4_has = TRUE; memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4)); - priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER; + priv->default_route.v4.rt_source = NM_IP_CONFIG_SOURCE_USER; priv->default_route.v4.gateway = gateway; priv->default_route.v4.metric = default_route_metric; priv->default_route.v4.mss = nm_ip4_config_get_mss (composite); @@ -4541,28 +4894,30 @@ END_ADD_DEFAULT_ROUTE: return success; } -static void +static gboolean dhcp4_lease_change (NMDevice *self, NMIP4Config *config) { NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - g_return_if_fail (config != NULL); + g_return_val_if_fail (config != NULL, FALSE); if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) { _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change."); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - } else { - /* Notify dispatcher scripts of new DHCP4 config */ - nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, - nm_device_get_settings_connection (self), - nm_device_get_applied_connection (self), - self, - NULL, - NULL, - NULL); - - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); + return FALSE; } + + /* Notify dispatcher scripts of new DHCP4 config */ + nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, + nm_device_get_settings_connection (self), + nm_device_get_applied_connection (self), + self, + NULL, + NULL, + NULL); + + nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); + + return TRUE; } static gboolean @@ -4576,11 +4931,11 @@ dhcp4_restart_cb (gpointer user_data) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); - priv->dhcp4_restart_id = 0; + priv->dhcp4.restart_id = 0; connection = nm_device_get_applied_connection (self); if (dhcp4_start (self, connection, &reason) == NM_ACT_STAGE_RETURN_FAILURE) - priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self); + dhcp_schedule_restart (self, AF_INET, NULL); return FALSE; } @@ -4590,6 +4945,9 @@ dhcp4_fail (NMDevice *self, gboolean timeout) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + _LOGD (LOGD_DHCP4, "DHCPv4 failed: timeout %d, num tries left %u", + timeout, priv->dhcp4.num_tries_left); + dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE); /* Don't fail if there are static addresses configured on @@ -4598,8 +4956,7 @@ dhcp4_fail (NMDevice *self, gboolean timeout) if ( priv->ip4_state == IP_DONE && priv->con_ip4_config && nm_ip4_config_get_num_addresses (priv->con_ip4_config) > 0) { - _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because device has IP addresses"); - priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self); + dhcp_schedule_restart (self, AF_INET, "device has IP addresses"); return; } @@ -4608,16 +4965,23 @@ dhcp4_fail (NMDevice *self, gboolean timeout) * retry DHCP again. */ if (nm_device_uses_assumed_connection (self)) { - _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because the connection is assumed"); - priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self); + dhcp_schedule_restart (self, AF_INET, "connection is assumed"); return; } - if (timeout || (priv->ip4_state == IP_CONF)) + if ( priv->dhcp4.num_tries_left == DHCP_NUM_TRIES_MAX + && (timeout || (priv->ip4_state == IP_CONF))) nm_device_activate_schedule_ip4_config_timeout (self); - else if (priv->ip4_state == IP_DONE) - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - else + else if (priv->ip4_state == IP_DONE) { + /* Don't fail immediately when the lease expires but try to + * restart DHCP for a predefined number of times. + */ + if (priv->dhcp4.num_tries_left) { + priv->dhcp4.num_tries_left--; + dhcp_schedule_restart (self, AF_INET, "lease expired"); + } else + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + } else g_warn_if_reached (); } @@ -4654,14 +5018,13 @@ dhcp4_state_changed (NMDhcpClient *client, case NM_DHCP_STATE_BOUND: if (!ip4_config) { _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event."); - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + dhcp4_fail (self, FALSE); break; } - nm_dhcp4_config_set_options (priv->dhcp4_config, options); + nm_dhcp4_config_set_options (priv->dhcp4.config, options); _notify (self, PROP_DHCP4_CONFIG); + priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX; if (priv->ip4_state == IP_CONF) { connection = nm_device_get_applied_connection (self); @@ -4678,8 +5041,10 @@ dhcp4_state_changed (NMDhcpClient *client, ipv4_dad_start (self, configs, dhcp4_dad_cb); } else if (priv->ip4_state == IP_DONE) { - dhcp4_lease_change (self, ip4_config); - nm_device_update_metered (self); + if (dhcp4_lease_change (self, ip4_config)) + nm_device_update_metered (self); + else + dhcp4_fail (self, FALSE); } break; case NM_DHCP_STATE_TIMEOUT: @@ -4735,8 +5100,8 @@ dhcp4_start (NMDevice *self, s_ip4 = nm_connection_get_setting_ip4_config (connection); /* Clear old exported DHCP options */ - nm_exported_object_clear_and_unexport (&priv->dhcp4_config); - priv->dhcp4_config = nm_dhcp4_config_new (); + nm_exported_object_clear_and_unexport (&priv->dhcp4.config); + priv->dhcp4.config = nm_dhcp4_config_new (); hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len); if (hw_addr_len) { @@ -4745,8 +5110,8 @@ dhcp4_start (NMDevice *self, } /* Begin DHCP on the interface */ - g_warn_if_fail (priv->dhcp4_client == NULL); - priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), + g_warn_if_fail (priv->dhcp4.client == NULL); + priv->dhcp4.client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), nm_device_get_ip_iface (self), nm_device_get_ip_ifindex (self), tmp, @@ -4763,12 +5128,12 @@ dhcp4_start (NMDevice *self, if (tmp) g_byte_array_free (tmp, TRUE); - if (!priv->dhcp4_client) { + if (!priv->dhcp4.client) { *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } - priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client, + priv->dhcp4.state_sigid = g_signal_connect (priv->dhcp4.client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp4_state_changed), self); @@ -4787,7 +5152,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) NMDeviceStateReason reason; NMConnection *connection; - g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); + g_return_val_if_fail (priv->dhcp4.client != NULL, FALSE); _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested"); @@ -4862,7 +5227,7 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso } config = nm_ip4_config_new (nm_device_get_ip_ifindex (self)); - address.source = NM_IP_CONFIG_SOURCE_SHARED; + address.addr_source = NM_IP_CONFIG_SOURCE_SHARED; nm_ip4_config_add_address (config, &address); /* Remove the address lock when the object gets disposed */ @@ -4888,7 +5253,7 @@ connection_ip4_method_requires_carrier (NMConnection *connection, if (out_ip4_enabled) *out_ip4_enabled = !!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - return _nm_utils_string_in_list (method, ip4_carrier_methods); + return g_strv_contains (ip4_carrier_methods, method); } static gboolean @@ -4905,7 +5270,7 @@ connection_ip6_method_requires_carrier (NMConnection *connection, if (out_ip6_enabled) *out_ip6_enabled = !!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - return _nm_utils_string_in_list (method, ip6_carrier_methods); + return g_strv_contains (ip6_carrier_methods, method); } static gboolean @@ -5013,6 +5378,7 @@ act_stage3_ip4_config_start (NMDevice *self, } method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX; /* Start IPv4 addressing based on the method requested */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) @@ -5056,25 +5422,25 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE; - g_clear_object (&priv->dhcp6_ip6_config); - g_clear_pointer (&priv->dhcp6_event_id, g_free); - nm_clear_g_source (&priv->dhcp6_restart_id); + priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE; + g_clear_object (&priv->dhcp6.ip6_config); + g_clear_pointer (&priv->dhcp6.event_id, g_free); + nm_clear_g_source (&priv->dhcp6.restart_id); - if (priv->dhcp6_client) { - nm_clear_g_signal_handler (priv->dhcp6_client, &priv->dhcp6_state_sigid); + if (priv->dhcp6.client) { + nm_clear_g_signal_handler (priv->dhcp6.client, &priv->dhcp6.state_sigid); if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) - nm_dhcp_client_stop (priv->dhcp6_client, release); + nm_dhcp_client_stop (priv->dhcp6.client, release); - g_clear_object (&priv->dhcp6_client); + g_clear_object (&priv->dhcp6.client); } nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); - if (priv->dhcp6_config) { - nm_exported_object_clear_and_unexport (&priv->dhcp6_config); + if (priv->dhcp6.config) { + nm_exported_object_clear_and_unexport (&priv->dhcp6.config); _notify (self, PROP_DHCP6_CONFIG); } } @@ -5104,6 +5470,7 @@ ip6_config_merge_and_apply (NMDevice *self, gboolean ignore_auto_routes = FALSE; gboolean ignore_auto_dns = FALSE; gboolean auto_method = FALSE; + const char *token = NULL; /* Apply ignore-auto-routes and ignore-auto-dns settings */ connection = nm_device_get_applied_connection (self); @@ -5111,9 +5478,14 @@ ip6_config_merge_and_apply (NMDevice *self, NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) { + NMSettingIP6Config *ip6 = NM_SETTING_IP6_CONFIG (s_ip6); + ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6); ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6); + if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) + token = nm_setting_ip6_config_get_token (ip6); + if (NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) @@ -5136,8 +5508,8 @@ ip6_config_merge_and_apply (NMDevice *self, (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0)); } - if (priv->dhcp6_ip6_config) { - nm_ip6_config_merge (composite, priv->dhcp6_ip6_config, + if (priv->dhcp6.ip6_config) { + nm_ip6_config_merge (composite, priv->dhcp6.ip6_config, (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0)); } @@ -5230,7 +5602,7 @@ ip6_config_merge_and_apply (NMDevice *self, priv->default_route.v6_has = TRUE; memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6)); - priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER; + priv->default_route.v6.rt_source = NM_IP_CONFIG_SOURCE_USER; priv->default_route.v6.gateway = *gateway; priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self); priv->default_route.v6.mss = nm_ip6_config_get_mss (composite); @@ -5261,6 +5633,14 @@ END_ADD_DEFAULT_ROUTE: /* Allow setting MTU etc */ if (commit) { + NMUtilsIPv6IfaceId iid; + + if (token && nm_utils_ipv6_interface_identifier_get_from_token (&iid, token)) { + nm_platform_link_set_ipv6_token (NM_PLATFORM_GET, + nm_device_get_ip_ifindex (self), + iid); + } + if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite); } @@ -5276,37 +5656,38 @@ END_ADD_DEFAULT_ROUTE: return success; } -static void +static gboolean dhcp6_lease_change (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingsConnection *settings_connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - if (priv->dhcp6_ip6_config == NULL) { + if (priv->dhcp6.ip6_config == NULL) { _LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind"); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - return; + return FALSE; } - g_assert (priv->dhcp6_client); /* sanity check */ + g_assert (priv->dhcp6.client); /* sanity check */ settings_connection = nm_device_get_settings_connection (self); g_assert (settings_connection); /* Apply the updated config */ - if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) { - _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event."); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - } else { - /* Notify dispatcher scripts of new DHCPv6 config */ - nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, - settings_connection, - nm_device_get_applied_connection (self), - self, NULL, NULL, NULL); - - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + if (!ip6_config_merge_and_apply (self, TRUE, &reason)) { + _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event"); + return FALSE; } + + /* Notify dispatcher scripts of new DHCPv6 config */ + nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, + settings_connection, + nm_device_get_applied_connection (self), + self, NULL, NULL, NULL); + + nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + + return TRUE; } static gboolean @@ -5319,30 +5700,63 @@ dhcp6_restart_cb (gpointer user_data) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); - priv->dhcp6_restart_id = 0; + priv->dhcp6.restart_id = 0; if (!dhcp6_start (self, FALSE, &reason)) - priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self); + dhcp_schedule_restart (self, AF_INET6, NULL); return FALSE; } static void +dhcp_schedule_restart (NMDevice *self, int family, const char *reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean inet4; + guint tries_left; + gs_free char *tries_str = NULL; + + g_return_if_fail (family == AF_INET || family == AF_INET6); + inet4 = family == AF_INET; + + tries_left = inet4 ? priv->dhcp4.num_tries_left : priv->dhcp6.num_tries_left; + if (tries_left != DHCP_NUM_TRIES_MAX) + tries_str = g_strdup_printf (", %u tries left", tries_left + 1); + + _LOGI (inet4 ? LOGD_DHCP4 : LOGD_DHCP6, + "scheduling DHCPv%c restart in %u seconds%s%s%s%s", + inet4 ? '4' : '6', + DHCP_RESTART_TIMEOUT, + tries_str ? tries_str : "", + NM_PRINT_FMT_QUOTED (reason, " (reason: ", reason, ")", "")); + + if (inet4) { + priv->dhcp4.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT, + dhcp4_restart_cb, self); + } else { + priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT, + dhcp6_restart_cb, self); + } +} + +static void dhcp6_fail (NMDevice *self, gboolean timeout) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + _LOGD (LOGD_DHCP6, "DHCPv6 failed: timeout %d, num tries left %u", + timeout, priv->dhcp6.num_tries_left); + dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE); - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) { /* Don't fail if there are static addresses configured on * the device, instead retry after some time. */ if ( priv->ip6_state == IP_DONE && priv->con_ip6_config && nm_ip6_config_get_num_addresses (priv->con_ip6_config)) { - _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because device has IP addresses"); - priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self); + dhcp_schedule_restart (self, AF_INET6, "device has IP addresses"); return; } @@ -5351,16 +5765,23 @@ dhcp6_fail (NMDevice *self, gboolean timeout) * retry DHCP again. */ if (nm_device_uses_assumed_connection (self)) { - _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed"); - priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self); + dhcp_schedule_restart (self, AF_INET6, "connection is assumed"); return; } - if (timeout || (priv->ip6_state == IP_CONF)) + if ( priv->dhcp6.num_tries_left == DHCP_NUM_TRIES_MAX + && (timeout || (priv->ip6_state == IP_CONF))) nm_device_activate_schedule_ip6_config_timeout (self); - else if (priv->ip6_state == IP_DONE) - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - else + else if (priv->ip6_state == IP_DONE) { + /* Don't fail immediately when the lease expires but try to + * restart DHCP for a predefined number of times. + */ + if (priv->dhcp6.num_tries_left) { + priv->dhcp6.num_tries_left--; + dhcp_schedule_restart (self, AF_INET6, "lease expired"); + } else + nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + } else g_warn_if_reached (); } else { /* not a hard failure; just live with the RA info */ @@ -5374,7 +5795,7 @@ dhcp6_timeout (NMDevice *self, NMDhcpClient *client) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) + if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) dhcp6_fail (self, TRUE); else { /* not a hard failure; just live with the RA info */ @@ -5409,32 +5830,34 @@ dhcp6_state_changed (NMDhcpClient *client, */ if ( ip6_config && event_id - && priv->dhcp6_event_id - && !strcmp (event_id, priv->dhcp6_event_id)) { + && priv->dhcp6.event_id + && !strcmp (event_id, priv->dhcp6.event_id)) { for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) { - nm_ip6_config_add_address (priv->dhcp6_ip6_config, + nm_ip6_config_add_address (priv->dhcp6.ip6_config, nm_ip6_config_get_address (ip6_config, i)); } } else { - g_clear_object (&priv->dhcp6_ip6_config); - g_clear_pointer (&priv->dhcp6_event_id, g_free); + g_clear_object (&priv->dhcp6.ip6_config); + g_clear_pointer (&priv->dhcp6.event_id, g_free); if (ip6_config) { - priv->dhcp6_ip6_config = g_object_ref (ip6_config); - priv->dhcp6_event_id = g_strdup (event_id); - nm_dhcp6_config_set_options (priv->dhcp6_config, options); + priv->dhcp6.ip6_config = g_object_ref (ip6_config); + priv->dhcp6.event_id = g_strdup (event_id); + nm_dhcp6_config_set_options (priv->dhcp6.config, options); _notify (self, PROP_DHCP6_CONFIG); } } + priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX; + if (priv->ip6_state == IP_CONF) { - if (priv->dhcp6_ip6_config == NULL) { - /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */ - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); + if (priv->dhcp6.ip6_config == NULL) { + nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED); break; } nm_device_activate_schedule_ip6_config_result (self); } else if (priv->ip6_state == IP_DONE) - dhcp6_lease_change (self); + if (!dhcp6_lease_change (self)) + dhcp6_fail (self, FALSE); break; case NM_DHCP_STATE_TIMEOUT: dhcp6_timeout (self, client); @@ -5449,7 +5872,7 @@ dhcp6_state_changed (NMDhcpClient *client, * may exit right after getting a response from the server. That's * normal. In that case we just ignore the exit. */ - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) + if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) break; /* Otherwise, fall through */ case NM_DHCP_STATE_FAIL: @@ -5485,7 +5908,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) g_return_val_if_fail (ll_addr, FALSE); - priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (), + priv->dhcp6.client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (), nm_device_get_ip_iface (self), nm_device_get_ip_ifindex (self), tmp, @@ -5496,19 +5919,19 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) nm_setting_ip_config_get_dhcp_hostname (s_ip6), priv->dhcp_timeout, priv->dhcp_anycast_address, - (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, + (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))); if (tmp) g_byte_array_free (tmp, TRUE); - if (priv->dhcp6_client) { - priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client, + if (priv->dhcp6.client) { + priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp6_state_changed), self); } - return !!priv->dhcp6_client; + return !!priv->dhcp6.client; } static gboolean @@ -5518,12 +5941,12 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) NMConnection *connection; NMSettingIPConfig *s_ip6; - nm_exported_object_clear_and_unexport (&priv->dhcp6_config); - priv->dhcp6_config = nm_dhcp6_config_new (); + nm_exported_object_clear_and_unexport (&priv->dhcp6.config); + priv->dhcp6.config = nm_dhcp6_config_new (); - g_warn_if_fail (priv->dhcp6_ip6_config == NULL); - g_clear_object (&priv->dhcp6_ip6_config); - g_clear_pointer (&priv->dhcp6_event_id, g_free); + g_warn_if_fail (priv->dhcp6.ip6_config == NULL); + g_clear_object (&priv->dhcp6.ip6_config); + g_clear_pointer (&priv->dhcp6.event_id, g_free); connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -5559,7 +5982,7 @@ nm_device_dhcp6_renew (NMDevice *self, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE); + g_return_val_if_fail (priv->dhcp6.client != NULL, FALSE); _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested"); @@ -5668,11 +6091,17 @@ check_and_add_ipv6ll_addr (NMDevice *self) s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { - if (!nm_utils_ipv6_addr_set_stable_privacy (&lladdr, - nm_device_get_iface (self), - nm_connection_get_uuid (connection), - priv->linklocal6_dad_counter++, - &error)) { + NMUtilsStableType stable_type; + const char *stable_id; + + stable_id = _get_stable_id (connection, &stable_type); + if ( !stable_id + || !nm_utils_ipv6_addr_set_stable_privacy (stable_type, + &lladdr, + nm_device_get_iface (self), + stable_id, + priv->linklocal6_dad_counter++, + &error)) { _LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message); g_clear_error (&error); linklocal6_failed (self); @@ -5690,13 +6119,13 @@ check_and_add_ipv6ll_addr (NMDevice *self) return; } - if (!nm_device_get_ip_iface_identifier (self, &iid)) { + if (!nm_device_get_ip_iface_identifier (self, &iid, TRUE)) { _LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); return; } _LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address"); - nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid); + nm_utils_ipv6_addr_set_interface_identifier (&lladdr, iid); } _LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL)); @@ -5799,8 +6228,9 @@ nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu) } static void -rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) +rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, NMDevice *self) { + NMRDiscConfigMap changed = changed_int; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int i; int system_support; @@ -5830,11 +6260,9 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) if (changed & NM_RDISC_CONFIG_GATEWAYS) { /* Use the first gateway as ordered in router discovery cache. */ - if (rdisc->gateways->len) { - NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0); - - nm_ip6_config_set_gateway (priv->ac_ip6_config, &gateway->address); - } else + if (rdata->gateways_n) + nm_ip6_config_set_gateway (priv->ac_ip6_config, &rdata->gateways[0].address); + else nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL); } @@ -5847,8 +6275,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) * also counts static and temporary addresses when checking * max_addresses. **/ - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + for (i = 0; i < rdata->addresses_n; i++) { + const NMRDiscAddress *discovered_address = &rdata->addresses[i]; NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); @@ -5859,7 +6287,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.source = NM_IP_CONFIG_SOURCE_RDISC; + address.addr_source = NM_IP_CONFIG_SOURCE_RDISC; address.n_ifa_flags = ifa_flags; nm_ip6_config_add_address (priv->ac_ip6_config, &address); @@ -5870,25 +6298,17 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) /* Rebuild route list from router discovery cache. */ nm_ip6_config_reset_routes (priv->ac_ip6_config); - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i); - NMPlatformIP6Route route; - - /* Only accept non-default routes. The router has no idea what the - * local configuration or user preferences are, so sending routes - * with a prefix length of 0 is quite rude and thus ignored. - */ - if (discovered_route->plen > 0) { - memset (&route, 0, sizeof (route)); - route.network = discovered_route->network; - nm_assert (discovered_route->plen <= 128); - route.plen = discovered_route->plen; - route.gateway = discovered_route->gateway; - route.source = NM_IP_CONFIG_SOURCE_RDISC; - route.metric = nm_device_get_ip6_route_metric (self); - - nm_ip6_config_add_route (priv->ac_ip6_config, &route); - } + for (i = 0; i < rdata->routes_n; i++) { + const NMRDiscRoute *discovered_route = &rdata->routes[i]; + const NMPlatformIP6Route route = { + .network = discovered_route->network, + .plen = discovered_route->plen, + .gateway = discovered_route->gateway, + .rt_source = NM_IP_CONFIG_SOURCE_RDISC, + .metric = nm_device_get_ip6_route_metric (self), + }; + + nm_ip6_config_add_route (priv->ac_ip6_config, &route); } } @@ -5896,36 +6316,30 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) /* Rebuild DNS server list from router discovery cache. */ nm_ip6_config_reset_nameservers (priv->ac_ip6_config); - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); - - nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address); - } + for (i = 0; i < rdata->dns_servers_n; i++) + nm_ip6_config_add_nameserver (priv->ac_ip6_config, &rdata->dns_servers[i].address); } if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) { /* Rebuild domain list from router discovery cache. */ nm_ip6_config_reset_domains (priv->ac_ip6_config); - for (i = 0; i < rdisc->dns_domains->len; i++) { - NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); - - nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain); - } + for (i = 0; i < rdata->dns_domains_n; i++) + nm_ip6_config_add_domain (priv->ac_ip6_config, rdata->dns_domains[i].domain); } if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE); - priv->dhcp6_mode = rdisc->dhcp_level; - if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) { + priv->dhcp6.mode = rdata->dhcp_level; + if (priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE) { NMDeviceStateReason reason; _LOGD (LOGD_DEVICE | LOGD_DHCP6, "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6" " as requested by IPv6 router..."); if (!dhcp6_start (self, FALSE, &reason)) { - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); return; } @@ -5934,10 +6348,10 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) } if (changed & NM_RDISC_CONFIG_HOP_LIMIT) - nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdisc->hop_limit); + nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdata->hop_limit); if (changed & NM_RDISC_CONFIG_MTU) - priv->ip6_mtu = rdisc->mtu; + priv->ip6_mtu = rdata->mtu; nm_device_activate_schedule_ip6_config_result (self); } @@ -5975,10 +6389,7 @@ addrconf6_start_with_link_ready (NMDevice *self) g_assert (priv->rdisc); - if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) { - _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present"); - nm_rdisc_set_iid (priv->rdisc, iid); - } else if (nm_device_get_ip_iface_identifier (self, &iid)) { + if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier"); nm_rdisc_set_iid (priv->rdisc, iid); } else { @@ -6017,6 +6428,8 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) NMActStageReturn ret; NMSettingIP6Config *s_ip6 = NULL; GError *error = NULL; + NMUtilsStableType stable_type; + const char *stable_id; connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -6030,12 +6443,16 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); g_assert (s_ip6); - priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, - nm_device_get_ip_ifindex (self), - nm_device_get_ip_iface (self), - nm_connection_get_uuid (connection), - nm_setting_ip6_config_get_addr_gen_mode (s_ip6), - &error); + stable_id = _get_stable_id (connection, &stable_type); + if (stable_id) { + priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, + nm_device_get_ip_ifindex (self), + nm_device_get_ip_iface (self), + stable_type, + stable_id, + nm_setting_ip6_config_get_addr_gen_mode (s_ip6), + &error); + } if (!priv->rdisc) { _LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message); g_error_free (error); @@ -6147,11 +6564,18 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) priv->nm_ipv6ll = enable; if (ifindex > 0) { + NMPlatformError plerr; const char *detail = enable ? "enable" : "disable"; _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail); - if (!nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, enable)) - _LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail); + plerr = nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, enable); + if (plerr != NM_PLATFORM_ERROR_SUCCESS) { + _NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : LOGL_WARN, + LOGD_IP6, + "failed to %s userspace IPv6LL address handling (%s)", + detail, + nm_platform_error_to_string (plerr)); + } if (enable) { /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ @@ -6286,7 +6710,8 @@ act_stage3_ip6_config_start (NMDevice *self, } } - priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE; + priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE; + priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -6334,7 +6759,7 @@ act_stage3_ip6_config_start (NMDevice *self, } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { ret = linklocal6_start (self); } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { - priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED; + priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_MANAGED; if (!dhcp6_start (self, TRUE, reason)) { /* IPv6 might be disabled; allow IPv4 to proceed */ ret = NM_ACT_STAGE_RETURN_STOP; @@ -6611,7 +7036,6 @@ act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_SUCCESS; } - /* * nm_device_activate_stage4_ip4_config_timeout * @@ -6639,7 +7063,6 @@ activate_stage4_ip4_config_timeout (NMDevice *self) check_ip_failed (self, FALSE); } - /* * nm_device_activate_schedule_ip4_config_timeout * @@ -6659,7 +7082,6 @@ nm_device_activate_schedule_ip4_config_timeout (NMDevice *self) activation_source_schedule (self, activate_stage4_ip4_config_timeout, AF_INET); } - static NMActStageReturn act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { @@ -6671,7 +7093,6 @@ act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_SUCCESS; } - /* * activate_stage4_ip6_config_timeout * @@ -6699,7 +7120,6 @@ activate_stage4_ip6_config_timeout (NMDevice *self) check_ip_failed (self, FALSE); } - /* * nm_device_activate_schedule_ip6_config_timeout * @@ -6747,19 +7167,12 @@ share_init (void) return TRUE; } -static void -add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...) -{ - va_list args; - char *cmd; - - va_start (args, fmt); - cmd = g_strdup_vprintf (fmt, args); - va_end (args); - - nm_act_request_add_share_rule (req, table, cmd); - g_free (cmd); -} +#define add_share_rule(req, table, ...) \ + G_STMT_START { \ + char *_cmd = g_strdup_printf (__VA_ARGS__); \ + nm_act_request_add_share_rule (req, table, _cmd); \ + g_free (_cmd); \ + } G_STMT_END static gboolean start_sharing (NMDevice *self, NMIP4Config *config) @@ -6906,7 +7319,7 @@ activate_stage5_ip4_config_commit (NMDevice *self) /* NULL to use the existing priv->dev_ip4_config */ if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) { _LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed"); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + nm_device_ip_method_failed (self, AF_INET, reason); return; } @@ -6924,7 +7337,7 @@ activate_stage5_ip4_config_commit (NMDevice *self) /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure * dispatcher scripts get the DHCP lease information. */ - if ( priv->dhcp4_client + if ( priv->dhcp4.client && nm_device_activate_ip4_state_in_conf (self) && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) { /* Notify dispatcher scripts of new DHCP4 config */ @@ -6975,6 +7388,64 @@ nm_device_activate_ip4_state_in_wait (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT; } +gboolean +nm_device_activate_ip4_state_done (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_DONE; +} + +/* + * Returns a NMIP6Config containing NM-configured addresses which + * have the tentative flag, or NULL if none is present. + */ +static NMIP6Config * +dad6_get_pending_addresses (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMIP6Config *confs[] = { priv->ac_ip6_config, + priv->dhcp6.ip6_config, + priv->con_ip6_config, + priv->wwan_ip6_config }; + const NMPlatformIP6Address *addr, *pl_addr; + NMIP6Config *dad6_config = NULL; + guint i, j, num; + int ifindex; + + ifindex = nm_device_get_ip_ifindex (self); + g_return_val_if_fail (ifindex > 0, NULL); + + /* We are interested only in addresses that we have explicitly configured, + * not in externally added ones. + */ + for (i = 0; i < G_N_ELEMENTS (confs); i++) { + if (confs[i]) { + num = nm_ip6_config_get_num_addresses (confs[i]); + for (j = 0; j < num; j++) { + addr = nm_ip6_config_get_address (confs[i], j); + pl_addr = nm_platform_ip6_address_get (NM_PLATFORM_GET, + ifindex, + addr->address, + addr->plen); + if ( pl_addr + && NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_DADFAILED) + && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + _LOGt (LOGD_DEVICE, "IPv6 DAD: pending address %s", + nm_platform_ip6_address_to_string (pl_addr, NULL, 0)); + + if (!dad6_config) + dad6_config = nm_ip6_config_new (ifindex); + + nm_ip6_config_add_address (dad6_config, pl_addr); + } + } + } + } + + return dad6_config; +} + static void activate_stage5_ip6_config_commit (NMDevice *self) { @@ -6998,9 +7469,9 @@ activate_stage5_ip6_config_commit (NMDevice *self) } if (ip6_config_merge_and_apply (self, TRUE, &reason)) { - if ( priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE + if ( priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE && priv->ip6_state == IP_CONF) { - if (priv->dhcp6_ip6_config) { + if (priv->dhcp6.ip6_config) { /* If IPv6 wasn't the first IP to complete, and DHCP was used, * then ensure dispatcher scripts get the DHCP lease information. */ @@ -7016,16 +7487,23 @@ activate_stage5_ip6_config_commit (NMDevice *self) return; } } - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); - /* Enter the IP_CHECK state if this is the first method to complete */ - priv->ip6_state = IP_DONE; - check_ip_done (self); + /* Check if we have to wait for DAD */ + if (priv->ip6_state == IP_CONF && !priv->dad6_ip6_config) { + priv->dad6_ip6_config = dad6_get_pending_addresses (self); + if (priv->dad6_ip6_config) { + _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: waiting termination"); + } else { + /* No tentative addresses, proceed right away */ + priv->ip6_state = IP_DONE; + check_ip_done (self); + } + } } else { _LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed"); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + nm_device_ip_method_failed (self, AF_INET6, reason); } } @@ -7059,6 +7537,13 @@ nm_device_activate_ip6_state_in_wait (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT; } +gboolean +nm_device_activate_ip6_state_done (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_DONE; +} + static void clear_act_request (NMDevice *self) { @@ -7223,6 +7708,7 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type) if (nm_clear_g_source (&priv->queued_ip6_config_id)) _LOGD (LOGD_DEVICE, "clearing queued IP6 config change"); + g_clear_object (&priv->dad6_ip6_config); dhcp6_cleanup (self, cleanup_type, FALSE); linklocal6_cleanup (self); addrconf6_cleanup (self); @@ -7891,7 +8377,7 @@ nm_device_steal_connection (NMDevice *self, NMSettingsConnection *connection) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - _LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.", + _LOGI (LOGD_DEVICE, "disconnecting connection '%s' for new activation request", nm_settings_connection_get_id (connection)); if ( priv->queued_act_request @@ -7970,7 +8456,7 @@ nm_device_get_dhcp4_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->dhcp4_config; + return NM_DEVICE_GET_PRIVATE (self)->dhcp4.config; } NMIP4Config * @@ -8287,7 +8773,7 @@ nm_device_get_dhcp6_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->dhcp6_config; + return NM_DEVICE_GET_PRIVATE (self)->dhcp6.config; } NMIP6Config * @@ -8595,6 +9081,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean device_is_up = FALSE; + NMDeviceCapabilities capabilities; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); @@ -8605,6 +9092,10 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) return FALSE; } + /* Store carrier immediately. */ + if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) + check_carrier (self); + device_is_up = nm_device_is_up (self); if (block && !device_is_up) { int ifindex = nm_device_get_ip_ifindex (self); @@ -8626,6 +9117,13 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) return FALSE; } + /* some ethernet devices fail to report capabilities unless the device + * is up. Re-read the capabilities. */ + capabilities = 0; + if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) + capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); + _add_capabilities (self, capabilities); + /* Devices that support carrier detect must be IFF_UP to report carrier * changes; so after setting the device IFF_UP we must suppress startup * complete (via a pending action) until either the carrier turns on, or @@ -8669,10 +9167,6 @@ bring_up (NMDevice *self, gboolean *no_firmware) result = nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, no_firmware); - /* Store carrier immediately. */ - if (result && nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) - check_carrier (self); - return result; } @@ -8808,7 +9302,7 @@ capture_lease_config (NMDevice *self, NMIP6Config **out_ip6_config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const GSList *connections, *citer; + NMSettingsConnection *const*connections; guint i; gboolean dhcp_used = FALSE; @@ -8841,9 +9335,9 @@ capture_lease_config (NMDevice *self, if (!dhcp_used) return; - connections = nm_connection_provider_get_connections (priv->con_provider); - for (citer = connections; citer; citer = citer->next) { - NMConnection *candidate = citer->data; + connections = nm_settings_get_connections (priv->settings, NULL); + for (i = 0; connections[i]; i++) { + NMConnection *candidate = (NMConnection *) connections[i]; const char *method; if (!nm_device_check_connection_compatible (self, candidate)) @@ -9016,8 +9510,8 @@ update_ip6_config (NMDevice *self, gboolean initial) nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config); if (priv->ac_ip6_config) nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config); - if (priv->dhcp6_ip6_config) - nm_ip6_config_intersect (priv->dhcp6_ip6_config, priv->ext_ip6_config); + if (priv->dhcp6.ip6_config) + nm_ip6_config_intersect (priv->dhcp6.ip6_config, priv->ext_ip6_config); if (priv->wwan_ip6_config) nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config); g_slist_foreach (priv->vpn6_configs, _ip6_config_intersect, priv->ext_ip6_config); @@ -9029,8 +9523,8 @@ update_ip6_config (NMDevice *self, gboolean initial) nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config); if (priv->ac_ip6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config); - if (priv->dhcp6_ip6_config) - nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config); + if (priv->dhcp6.ip6_config) + nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6.ip6_config); if (priv->wwan_ip6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config); g_slist_foreach (priv->vpn6_configs, _ip6_config_subtract, priv->ext_ip6_config); @@ -9070,9 +9564,7 @@ queued_ip4_config_change (gpointer user_data) return TRUE; priv->queued_ip4_config_id = 0; - g_object_ref (self); update_ip4_config (self, FALSE); - g_object_unref (self); set_unmanaged_external_down (self, TRUE); @@ -9096,16 +9588,15 @@ queued_ip6_config_change (gpointer user_data) return TRUE; priv->queued_ip6_config_id = 0; - g_object_ref (self); update_ip6_config (self, FALSE); - if ( priv->state < NM_DEVICE_STATE_DEACTIVATING + if (priv->state < NM_DEVICE_STATE_DEACTIVATING && nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex)) { /* Handle DAD failures */ for (iter = priv->dad6_failed_addrs; iter; iter = g_slist_next (iter)) { NMPlatformIP6Address *addr = iter->data; - if (addr->source >= NM_IP_CONFIG_SOURCE_USER) + if (addr->addr_source >= NM_IP_CONFIG_SOURCE_USER) continue; _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address", @@ -9132,7 +9623,18 @@ queued_ip6_config_change (gpointer user_data) g_slist_free_full (priv->dad6_failed_addrs, g_free); priv->dad6_failed_addrs = NULL; - g_object_unref (self); + /* Check if DAD is still pending */ + if ( priv->ip6_state == IP_CONF + && priv->dad6_ip6_config + && priv->ext_ip6_config_captured) { + if (!nm_ip6_config_has_any_dad_pending (priv->ext_ip6_config_captured, + priv->dad6_ip6_config)) { + _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated"); + g_clear_object (&priv->dad6_ip6_config); + priv->ip6_state = IP_DONE; + check_ip_done (self); + } + } set_unmanaged_external_down (self, TRUE); @@ -9256,7 +9758,7 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo * Some flags are authoritative, meaning they always cause * the device to be unmanaged (e.g. @NM_UNMANAGED_PLATFORM_INIT). * - * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_SETTINGS + * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_UDEV * is ignored once NM_UNMANAGED_USER_EXPLICIT is set. The idea is that * the flag from the configuration has no effect once the user explicitly * touches the unmanaged flags. */ @@ -9290,6 +9792,9 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo /* configuration from udev or nm-config overwrites the by-default flag * which is based on the device type. */ flags &= ~NM_UNMANAGED_BY_DEFAULT; + + /* configuration from udev overwrites external-down */ + flags &= ~NM_UNMANAGED_EXTERNAL_DOWN; } if ( NM_FLAGS_HAS (mask, NM_UNMANAGED_IS_SLAVE) @@ -9528,7 +10033,7 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self, } void -nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs) +nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs) { NMDevicePrivate *priv; gboolean unmanaged; @@ -9880,50 +10385,45 @@ void nm_device_recheck_available_connections (NMDevice *self) { NMDevicePrivate *priv; - const GSList *connections, *iter; + NMSettingsConnection *const*connections; gboolean changed = FALSE; GHashTableIter h_iter; NMConnection *connection; + guint i; + gs_unref_hashtable GHashTable *prune_list = NULL; g_return_if_fail (NM_IS_DEVICE (self)); priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->con_provider) { - gs_unref_hashtable GHashTable *prune_list = NULL; - - if (g_hash_table_size (priv->available_connections) > 0) { - prune_list = g_hash_table_new (g_direct_hash, g_direct_equal); - g_hash_table_iter_init (&h_iter, priv->available_connections); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) - g_hash_table_add (prune_list, connection); - } - - connections = nm_connection_provider_get_connections (priv->con_provider); - for (iter = connections; iter; iter = g_slist_next (iter)) { - connection = NM_CONNECTION (iter->data); - - if (nm_device_check_connection_available (self, - connection, - NM_DEVICE_CHECK_CON_AVAILABLE_NONE, - NULL)) { - if (available_connections_add (self, connection)) - changed = TRUE; - if (prune_list) - g_hash_table_remove (prune_list, connection); - } + if (g_hash_table_size (priv->available_connections) > 0) { + prune_list = g_hash_table_new (g_direct_hash, g_direct_equal); + g_hash_table_iter_init (&h_iter, priv->available_connections); + while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) + g_hash_table_add (prune_list, connection); + } + + connections = nm_settings_get_connections (priv->settings, NULL); + for (i = 0; connections[i]; i++) { + connection = (NMConnection *) connections[i]; + + if (nm_device_check_connection_available (self, + connection, + NM_DEVICE_CHECK_CON_AVAILABLE_NONE, + NULL)) { + if (available_connections_add (self, connection)) + changed = TRUE; + if (prune_list) + g_hash_table_remove (prune_list, connection); } + } - if (prune_list) { - g_hash_table_iter_init (&h_iter, prune_list); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) { - if (available_connections_del (self, connection)) - changed = TRUE; - } + if (prune_list) { + g_hash_table_iter_init (&h_iter, prune_list); + while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) { + if (available_connections_del (self, connection)) + changed = TRUE; } - } else { - if (available_connections_del_all (self)) - changed = TRUE; } if (changed) @@ -9984,10 +10484,9 @@ nm_device_get_best_connection (NMDevice *self, } static void -cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data) +cp_connection_added_or_updated (NMDevice *self, NMConnection *connection) { gboolean changed; - NMDevice *self = user_data; g_return_if_fail (NM_IS_DEVICE (self)); g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); @@ -10007,6 +10506,18 @@ cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connecti } static void +cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data) +{ + cp_connection_added_or_updated (user_data, connection); +} + +static void +cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gboolean by_user, gpointer user_data) +{ + cp_connection_added_or_updated (user_data, connection); +} + +static void cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data) { NMDevice *self = user_data; @@ -10213,6 +10724,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) g_clear_object (&priv->ext_ip6_config_captured); g_clear_object (&priv->wwan_ip6_config); g_clear_object (&priv->ip6_config); + g_clear_object (&priv->dad6_ip6_config); g_slist_free_full (priv->vpn4_configs, g_object_unref); priv->vpn4_configs = NULL; @@ -10276,44 +10788,48 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean if (NM_DEVICE_GET_CLASS (self)->deactivate) NM_DEVICE_GET_CLASS (self)->deactivate (self); - /* master: release slaves */ - nm_device_master_release_slaves (self); + if (cleanup_type != CLEANUP_TYPE_KEEP) { + /* master: release slaves */ + nm_device_master_release_slaves (self); - /* slave: mark no longer enslaved */ - if ( priv->master - && nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) <= 0) - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + /* slave: mark no longer enslaved */ + if ( priv->master + && nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) <= 0) + nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - /* Take out any entries in the routing table and any IP address the device had. */ - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex > 0) { - nm_route_manager_route_flush (nm_route_manager_get (), ifindex); - nm_platform_address_flush (NM_PLATFORM_GET, ifindex); + /* Take out any entries in the routing table and any IP address the device had. */ + ifindex = nm_device_get_ip_ifindex (self); + if (ifindex > 0) { + nm_route_manager_route_flush (nm_route_manager_get (), ifindex); + nm_platform_address_flush (NM_PLATFORM_GET, ifindex); + } } if (priv->lldp_listener) nm_lldp_listener_stop (priv->lldp_listener); nm_device_update_metered (self); + + /* during device cleanup, we want to reset the MAC address of the device + * to the initial state. + * + * We certainly want to do that when reaching the UNMANAGED state... */ + if (nm_device_get_state (self) <= NM_DEVICE_STATE_UNMANAGED) + nm_device_hw_addr_reset (self, "unmanage"); + else { + /* for other device states (UNAVAILABLE, DISCONNECTED), allow the + * device to overwrite the reset behavior, so that Wi-Fi can set + * a randomized MAC address used during scanning. */ + NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self); + } + _cleanup_generic_post (self, cleanup_type); } -static char * -bin2hexstr (const char *bytes, gsize len) +static void +deactivate_reset_hw_addr (NMDevice *self) { - GString *str; - int i; - - g_return_val_if_fail (bytes != NULL, NULL); - g_return_val_if_fail (len > 0, NULL); - - str = g_string_sized_new (len * 2 + 1); - for (i = 0; i < len; i++) { - if (str->len) - g_string_append_c (str, ':'); - g_string_append_printf (str, "%02x", (guint8) bytes[i]); - } - return g_string_free (str, FALSE); + nm_device_hw_addr_reset (self, "deactivate"); } static char * @@ -10329,7 +10845,7 @@ find_dhcp4_address (NMDevice *self) for (i = 0; i < n; i++) { const NMPlatformIP4Address *a = nm_ip4_config_get_address (priv->ip4_config, i); - if (a->source == NM_IP_CONFIG_SOURCE_DHCP) + if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP) return g_strdup (nm_utils_inet4_ntop (a->address, NULL)); } return NULL; @@ -10346,6 +10862,8 @@ nm_device_spawn_iface_helper (NMDevice *self) GPtrArray *argv; gs_free char *dhcp4_address = NULL; char *logging_backend; + NMUtilsStableType stable_type; + const char *stable_id; if (priv->state != NM_DEVICE_STATE_ACTIVATED) return; @@ -10364,6 +10882,12 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--uuid")); g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection))); + stable_id = _get_stable_id (connection, &stable_type); + if (stable_id && stable_type != NM_UTILS_STABLE_TYPE_UUID) { + g_ptr_array_add (argv, g_strdup ("--stable-id")); + g_ptr_array_add (argv, g_strdup_printf ("%d %s", (int) stable_type, stable_id)); + } + logging_backend = nm_config_get_is_debug (nm_config_get ()) ? g_strdup ("debug") : nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, @@ -10380,7 +10904,6 @@ nm_device_spawn_iface_helper (NMDevice *self) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { NMSettingIPConfig *s_ip4; - char *hex_client_id; s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); @@ -10393,25 +10916,26 @@ nm_device_spawn_iface_helper (NMDevice *self) if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE) g_ptr_array_add (argv, g_strdup ("--dhcp4-required")); - if (priv->dhcp4_client) { + if (priv->dhcp4.client) { const char *hostname, *fqdn; GBytes *client_id; - client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client); + client_id = nm_dhcp_client_get_client_id (priv->dhcp4.client); if (client_id) { g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid")); - hex_client_id = bin2hexstr (g_bytes_get_data (client_id, NULL), - g_bytes_get_size (client_id)); - g_ptr_array_add (argv, hex_client_id); + g_ptr_array_add (argv, + _nm_utils_bin2str (g_bytes_get_data (client_id, NULL), + g_bytes_get_size (client_id), + FALSE)); } - hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client); + hostname = nm_dhcp_client_get_hostname (priv->dhcp4.client); if (hostname) { g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); g_ptr_array_add (argv, g_strdup (hostname)); } - fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4_client); + fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4.client); if (fqdn) { g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn")); g_ptr_array_add (argv, g_strdup (fqdn)); @@ -10424,7 +10948,6 @@ nm_device_spawn_iface_helper (NMDevice *self) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { NMSettingIPConfig *s_ip6; - char *hex_iid; NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -10441,10 +10964,12 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr")); g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr)); - if (nm_device_get_ip_iface_identifier (self, &iid)) { + if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { g_ptr_array_add (argv, g_strdup ("--iid")); - hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId)); - g_ptr_array_add (argv, hex_iid); + g_ptr_array_add (argv, + _nm_utils_bin2str (iid.id_u8, + sizeof (NMUtilsIPv6IfaceId), + FALSE)); } g_ptr_array_add (argv, g_strdup ("--addr-gen-mode")); @@ -10654,11 +11179,14 @@ _set_state_full (NMDevice *self, if (old_state > NM_DEVICE_STATE_UNMANAGED) { if (reason == NM_DEVICE_STATE_REASON_REMOVED) { nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED); + } else if (reason == NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + nm_device_cleanup (self, reason, CLEANUP_TYPE_KEEP); } else { /* Clean up if the device is now unmanaged but was activated */ if (nm_device_get_act_request (self)) nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); nm_device_take_down (self, TRUE); + nm_device_hw_addr_reset (self, "unmanage"); set_nm_ipv6ll (self, FALSE); restore_ip6_properties (self); } @@ -10706,6 +11234,9 @@ _set_state_full (NMDevice *self, } } break; + case NM_DEVICE_STATE_PREPARE: + nm_device_update_initial_hw_address (self); + break; case NM_DEVICE_STATE_NEED_AUTH: if (old_state > NM_DEVICE_STATE_NEED_AUTH) { /* Clean up any half-done IP operations if the device's layer2 @@ -10726,7 +11257,7 @@ _set_state_full (NMDevice *self, _notify (self, PROP_STATE); _notify (self, PROP_STATE_REASON); - g_signal_emit_by_name (self, NM_DEVICE_STATE_CHANGED, state, old_state, reason); + g_signal_emit (self, signals[STATE_CHANGED], 0, state, old_state, reason); /* Post-process the event after internal notification */ @@ -10749,11 +11280,9 @@ _set_state_full (NMDevice *self, case NM_DEVICE_STATE_DEACTIVATING: _cancel_activation (self); - if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - /* We cache the ignore_carrier state to not react on config-reloads while the connection - * is active. But on deactivating, reset the ignore-carrier flag to the current state. */ - priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self); - } + /* We cache the ignore_carrier state to not react on config-reloads while the connection + * is active. But on deactivating, reset the ignore-carrier flag to the current state. */ + priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self); if (quitting) { nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN, @@ -11026,25 +11555,27 @@ nm_device_get_hw_address (NMDevice *self) g_return_val_if_fail (NM_IS_DEVICE (self), NULL); priv = NM_DEVICE_GET_PRIVATE (self); - return priv->hw_addr_len ? priv->hw_addr : NULL; + nm_assert ((!priv->hw_addr) ^ (priv->hw_addr_len > 0)); + + return priv->hw_addr; } void nm_device_update_hw_address (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (self); + NMDevicePrivate *priv; const guint8 *hwaddr; gsize hwaddrlen = 0; - static const guint8 zero_hwaddr[ETH_ALEN]; - if (ifindex <= 0) + priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->ifindex <= 0) return; - hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen); + hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &hwaddrlen); if ( priv->type == NM_DEVICE_TYPE_ETHERNET - && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, sizeof (zero_hwaddr))) + && hwaddr + && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth))) hwaddrlen = 0; if (hwaddrlen) { @@ -11053,17 +11584,28 @@ nm_device_update_hw_address (NMDevice *self) g_free (priv->hw_addr); priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - _LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr); + _LOGD (LOGD_HW | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); _notify (self, PROP_HW_ADDRESS); + + if ( !priv->hw_addr_initial + || ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET + && priv->state < NM_DEVICE_STATE_PREPARE + && !nm_device_is_activating (self))) { + /* when we get a hw_addr the first time or while the device + * is not activated (with no explict hw address set), always + * update our inital hw-address as well. */ + nm_device_update_initial_hw_address (self); + } } } else { /* Invalid or no hardware address */ if (priv->hw_addr_len != 0) { - g_clear_pointer (&priv->hw_addr, g_free); - priv->hw_addr_len = 0; _LOGD (LOGD_HW | LOGD_DEVICE, - "previous hardware address is no longer valid"); - _notify (self, PROP_HW_ADDRESS); + "hw-addr: failed reading current MAC address (stay with %s)", + priv->hw_addr); + } else { + _LOGD (LOGD_HW | LOGD_DEVICE, + "hw-addr: failed reading current MAC address"); } } } @@ -11073,84 +11615,365 @@ nm_device_update_initial_hw_address (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->hw_addr_len) { - priv->initial_hw_addr = g_strdup (priv->hw_addr); - _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr); + if ( priv->hw_addr + && !nm_streq0 (priv->hw_addr_initial, priv->hw_addr)) { + if ( priv->hw_addr_initial + && priv->hw_addr_type != HW_ADDR_TYPE_UNSET) { + /* once we have the initial hw address set, we only allow + * update if the currenty type is "unset". */ + return; + } + g_free (priv->hw_addr_initial); + priv->hw_addr_initial = g_strdup (priv->hw_addr); + _LOGD (LOGD_DEVICE, "hw-addr: update initial MAC address %s", + priv->hw_addr_initial); + } +} - if (priv->ifindex > 0) { - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; - size_t len = 0; +void +nm_device_update_permanent_hw_address (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + size_t len = 0; + gboolean success_read; - if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) { - g_warn_if_fail (len == priv->hw_addr_len); - priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len); - _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s", - priv->perm_hw_addr); - } else { - /* Fall back to current address */ - _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address"); - priv->perm_hw_addr = g_strdup (priv->hw_addr); + if (priv->hw_addr_perm) { + /* the permanent hardware address is only read once and not + * re-read later. + * + * Except during unrealize/realize cycles, where we clear the permanent + * hardware address during unrealization. */ + return; + } + + if (priv->ifindex <= 0) + return; + + if (!priv->hw_addr_len) { + nm_device_update_hw_address (self); + if (!priv->hw_addr_len) + return; + } + + success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len); + if (!success_read || len != priv->hw_addr_len) { + /* Fall back to current address. We use the fake address and keep it + * until the device unrealizes. + * + * In some cases it might be necessary to know whether this is a "real" or + * a temporary address (fake). */ + _LOGD (LOGD_HW | LOGD_ETHER, "hw-addr: %s (use current: %s)", + success_read + ? "read HW addr length of permanent MAC address differs" + : "unable to read permanent MAC address", + priv->hw_addr); + priv->hw_addr_perm_fake = TRUE; + priv->hw_addr_perm = g_strdup (priv->hw_addr); + } else { + priv->hw_addr_perm_fake = FALSE; + priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); + _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", + priv->hw_addr_perm); + } + _notify (self, PROP_PERM_HW_ADDRESS); +} + +static const char * +_get_cloned_mac_address_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_addr) +{ + NMSetting *setting; + const char *addr = NULL; + + nm_assert (out_addr && !*out_addr); + + setting = nm_connection_get_setting (connection, + is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); + if (setting) { + addr = is_wifi + ? nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) setting) + : nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) setting); + } + + if (!addr) { + gs_free char *a = NULL; + + a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + is_wifi ? "wifi.cloned-mac-address" : "ethernet.cloned-mac-address", + self); + /* default is permanent. */ + addr = NM_CLONED_MAC_PERMANENT; + + if (!a) { + if (is_wifi) { + NMSettingMacRandomization v; + + /* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */ + a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + self); + v = _nm_utils_ascii_str_to_int64 (a, 10, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT); + if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) + addr = NM_CLONED_MAC_RANDOM; } - } + } else if ( NM_CLONED_MAC_IS_SPECIAL (a) + || nm_utils_hwaddr_valid (a, ETH_ALEN)) + addr = *out_addr = g_steal_pointer (&a); } + + return addr; +} + +static const char * +_get_generate_mac_address_mask_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_value) +{ + NMSetting *setting; + const char *value = NULL; + char *a; + + nm_assert (out_value && !*out_value); + + setting = nm_connection_get_setting (connection, + is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); + if (setting) { + value = is_wifi + ? nm_setting_wireless_get_generate_mac_address_mask ((NMSettingWireless *) setting) + : nm_setting_wired_get_generate_mac_address_mask ((NMSettingWired *) setting); + if (value) + return value; + } + + a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + is_wifi ? "wifi.generate-mac-address-mask" : "ethernet.generate-mac-mac-address-mask", + self); + if (!a) + return NULL; + *out_value = a; + return a; } gboolean -nm_device_set_hw_addr (NMDevice *self, const char *addr, - const char *detail, guint64 hw_log_domain) +nm_device_hw_addr_is_explict (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); + return !NM_IN_SET (priv->hw_addr_type, HW_ADDR_TYPE_PERMANENT, HW_ADDR_TYPE_UNSET); +} + +static gboolean +_hw_addr_set (NMDevice *self, + const char *addr, + const char *operation, + const char *detail) +{ + NMDevicePrivate *priv; gboolean success = FALSE; - const char *cur_addr = nm_device_get_hw_address (self); + NMPlatformError plerr; + const char *cur_addr; guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; + guint hw_addr_len; + gboolean was_up; - /* Fall back to the permanent address */ - if (!addr) - addr = priv->perm_hw_addr; - if (!addr) - return FALSE; + nm_assert (NM_IS_DEVICE (self)); + nm_assert (addr); + nm_assert (operation); + + priv = NM_DEVICE_GET_PRIVATE (self); + + cur_addr = nm_device_get_hw_address (self); /* Do nothing if current MAC is same */ if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { - _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed"); + _LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed (%s)", cur_addr); return TRUE; } - if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) { - _LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr); - return FALSE; - } - /* Can't change MAC address while device is up */ - nm_device_take_down (self, FALSE); + hw_addr_len = priv->hw_addr_len; + if (!hw_addr_len) + hw_addr_len = _nm_utils_hwaddr_length (addr); + if ( !hw_addr_len + || !nm_utils_hwaddr_aton (addr, addr_bytes, hw_addr_len)) + g_return_val_if_reached (FALSE); - success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len); + _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail); + + was_up = nm_device_is_up (self); + if (was_up) { + /* Can't change MAC address while device is up */ + nm_device_take_down (self, FALSE); + } + + plerr = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, hw_addr_len); + success = (plerr == NM_PLATFORM_ERROR_SUCCESS); if (success) { /* MAC address succesfully changed; update the current MAC to match */ nm_device_update_hw_address (self); cur_addr = nm_device_get_hw_address (self); if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { - _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s", - detail, addr); + _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", + operation, addr, detail); } else { - _LOGW (LOGD_DEVICE | hw_log_domain, - "new MAC address %s not successfully set", addr); + _LOGW (LOGD_DEVICE, + "set-hw-addr: new MAC address %s not successfully set to %s (%s)", + addr, operation, detail); success = FALSE; } } else { - _LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s", - detail, addr); + _NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : LOGL_WARN, + LOGD_DEVICE, "set-hw-addr: failed to %s MAC address to %s (%s) (%s)", + operation, addr, detail, + nm_platform_error_to_string (plerr)); + } + + if (was_up) { + if (!nm_device_bring_up (self, TRUE, NULL)) + return FALSE; } - nm_device_bring_up (self, TRUE, NULL); return success; } +gboolean +nm_device_hw_addr_set (NMDevice *self, const char *addr, const char *detail) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (!addr) + g_return_val_if_reached (FALSE); + + /* this is called by NMDeviceVlan to take the MAC address from the parent + * and by NMDeviceWifi to set a random MAC address during scanning. + * In this case, it's like setting it to PERMANENT. */ + priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT; + + return _hw_addr_set (self, addr, "set", detail); +} + +gboolean +nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean is_wifi) +{ + NMDevicePrivate *priv; + gs_free char *hw_addr_tmp = NULL; + gs_free char *hw_addr_generated = NULL; + gs_free char *generate_mac_address_mask_tmp = NULL; + const char *addr, *addr_setting; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (!connection) + g_return_val_if_reached (FALSE); + + addr = addr_setting = _get_cloned_mac_address_setting (self, connection, is_wifi, &hw_addr_tmp); + + if (nm_streq (addr, NM_CLONED_MAC_PRESERVE)) { + /* "preserve" means to reset the initial MAC address. */ + return nm_device_hw_addr_reset (self, addr_setting); + } + + if (nm_streq (addr, NM_CLONED_MAC_PERMANENT)) { + addr = nm_device_get_permanent_hw_address (self, TRUE); + if (!addr) + return FALSE; + priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT; + } else if (NM_IN_STRSET (addr, NM_CLONED_MAC_RANDOM)) { + if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { + /* hm, we already use a generate MAC address. Most certainly, that is from the same + * activation request, so we should not create a new random address, instead keep + * the current. */ + return TRUE; + } + hw_addr_generated = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (self), + _get_generate_mac_address_mask_setting (self, connection, is_wifi, &generate_mac_address_mask_tmp)); + if (!hw_addr_generated) { + _LOGW (LOGD_DEVICE, "set-hw-addr: failed to generate %s MAC address", "random"); + return FALSE; + } + priv->hw_addr_type = HW_ADDR_TYPE_GENERATED; + addr = hw_addr_generated; + } else if (NM_IN_STRSET (addr, NM_CLONED_MAC_STABLE)) { + NMUtilsStableType stable_type; + const char *stable_id; + + if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { + /* hm, we already use a generate MAC address. Most certainly, that is from the same + * activation request, so let's skip creating the stable address anew. */ + return TRUE; + } + + stable_id = _get_stable_id (connection, &stable_type); + if (stable_id) { + hw_addr_generated = nm_utils_hw_addr_gen_stable_eth (stable_type, stable_id, + nm_device_get_ip_iface (self), + nm_device_get_initial_hw_address (self), + _get_generate_mac_address_mask_setting (self, connection, is_wifi, &generate_mac_address_mask_tmp)); + } + if (!hw_addr_generated) { + _LOGW (LOGD_DEVICE, "set-hw-addr: failed to generate %s MAC address", "stable"); + return FALSE; + } + priv->hw_addr_type = HW_ADDR_TYPE_GENERATED; + addr = hw_addr_generated; + } else { + /* this must be a valid address. Otherwise, we shouldn't come here. */ + if (_nm_utils_hwaddr_length (addr) <= 0) { + g_return_val_if_reached (FALSE); + } + priv->hw_addr_type = HW_ADDR_TYPE_EXPLICIT; + } + + return _hw_addr_set (self, addr, "set-cloned", addr_setting); +} + +gboolean +nm_device_hw_addr_reset (NMDevice *self, const char *detail) +{ + NMDevicePrivate *priv; + const char *addr; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->hw_addr_type == HW_ADDR_TYPE_UNSET) + return TRUE; + + priv->hw_addr_type = HW_ADDR_TYPE_UNSET; + addr = nm_device_get_initial_hw_address (self); + if (!addr) { + /* as hw_addr_type is not UNSET, we expect that we can get an + * initial address to which to reset. */ + g_return_val_if_reached (FALSE); + } + + return _hw_addr_set (self, addr, "reset", detail); +} + const char * -nm_device_get_permanent_hw_address (NMDevice *self) +nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_fake) { + NMDevicePrivate *priv; + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->perm_hw_addr; + priv = NM_DEVICE_GET_PRIVATE (self); + if (!priv->hw_addr_perm) + return NULL; + if ( priv->hw_addr_perm_fake + && !fallback_fake) + return NULL; + return priv->hw_addr_perm; } const char * @@ -11158,7 +11981,7 @@ nm_device_get_initial_hw_address (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr; + return NM_DEVICE_GET_PRIVATE (self)->hw_addr_initial; } /** @@ -11196,9 +12019,9 @@ nm_device_spec_match_list (NMDevice *self, const GSList *specs) static NMMatchSpecMatchType spec_match_list (NMDevice *self, const GSList *specs) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m; const GSList *iter; + const char *hw_addr_perm; for (iter = specs; iter; iter = g_slist_next (iter)) { if (!strcmp ((const char *) iter->data, "*")) { @@ -11206,8 +12029,10 @@ spec_match_list (NMDevice *self, const GSList *specs) break; } } - if (priv->hw_addr_len && priv->hw_addr) { - m = nm_match_spec_hwaddr (specs, priv->hw_addr); + + hw_addr_perm = nm_device_get_permanent_hw_address (self, FALSE); + if (hw_addr_perm) { + m = nm_match_spec_hwaddr (specs, hw_addr_perm); matched = MAX (matched, m); } if (matched != NM_MATCH_SPEC_NEG_MATCH) { @@ -11290,7 +12115,8 @@ constructor (GType type, self = NM_DEVICE (object); priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->iface) { + if ( priv->iface + && G_LIKELY (!nm_utils_get_testing ())) { pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface); if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) { @@ -11299,6 +12125,17 @@ constructor (GType type, } } + if (priv->hw_addr_perm) { + priv->hw_addr_len = _nm_utils_hwaddr_length (priv->hw_addr_perm); + if (!priv->hw_addr_len) { + g_clear_pointer (&priv->hw_addr_perm, g_free); + g_return_val_if_reached (object); + } + + priv->hw_addr = g_strdup (priv->hw_addr_perm); + _LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm); + } + return object; } @@ -11309,33 +12146,31 @@ constructed (GObject *object) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatform *platform; - platform = nm_platform_get (); - if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); /* Watch for external IP config changes */ + platform = NM_PLATFORM_GET; g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self); - priv->con_provider = nm_connection_provider_get (); - g_assert (priv->con_provider); - g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (cp_connection_added_or_updated), - self); + priv->settings = g_object_ref (NM_SETTINGS_GET); + g_assert (priv->settings); - g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_REMOVED, - G_CALLBACK (cp_connection_removed), + g_signal_connect (priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK (cp_connection_added), self); - - g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_UPDATED, - G_CALLBACK (cp_connection_added_or_updated), + g_signal_connect (priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + G_CALLBACK (cp_connection_updated), + self); + g_signal_connect (priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_CALLBACK (cp_connection_removed), self); G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); @@ -11352,7 +12187,7 @@ dispose (GObject *object) _LOGD (LOGD_DEVICE, "disposing"); - platform = nm_platform_get (); + platform = NM_PLATFORM_GET; g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self); g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self); @@ -11361,7 +12196,7 @@ dispose (GObject *object) arp_cleanup (self); - g_signal_handlers_disconnect_by_func (nm_config_get (), config_changed_update_ignore_carrier, self); + nm_clear_g_signal_handler (nm_config_get (), &priv->ignore_carrier_id); dispatcher_cleanup (self); @@ -11382,12 +12217,14 @@ dispose (GObject *object) nm_clear_g_source (&priv->check_delete_unrealized_id); + nm_clear_g_source (&priv->stats.timeout_id); + link_disconnect_action_cancel (self); - if (priv->con_provider) { - g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added_or_updated, self); - g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self); - priv->con_provider = NULL; + if (priv->settings) { + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self); + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self); + g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self); } available_connections_del_all (self); @@ -11426,8 +12263,8 @@ finalize (GObject *object) _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self)); g_free (priv->hw_addr); - g_free (priv->perm_hw_addr); - g_free (priv->initial_hw_addr); + g_free (priv->hw_addr_perm); + g_free (priv->hw_addr_initial); g_slist_free_full (priv->pending_actions, g_free); g_slist_free_full (priv->dad6_failed_addrs, g_free); g_clear_pointer (&priv->physical_port_id, g_free); @@ -11445,16 +12282,19 @@ finalize (GObject *object) g_hash_table_unref (priv->available_connections); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); + + /* for testing, NMDeviceTest does not invoke NMDevice::constructed, + * and thus @settings might be unset. */ + if (priv->settings) + g_object_unref (priv->settings); } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDevice *self = NM_DEVICE (object); + NMDevice *self = (NMDevice *) object; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *hw_addr, *p; - guint count; switch (prop_id) { case PROP_UDI: @@ -11476,11 +12316,11 @@ set_property (GObject *object, guint prop_id, break; case PROP_DRIVER_VERSION: g_free (priv->driver_version); - priv->driver_version = g_strdup (g_value_get_string (value)); + priv->driver_version = g_value_dup_string (value); break; case PROP_FIRMWARE_VERSION: g_free (priv->firmware_version); - priv->firmware_version = g_strdup (g_value_get_string (value)); + priv->firmware_version = g_value_dup_string (value); break; case PROP_MTU: priv->mtu = g_value_get_uint (value); @@ -11532,32 +12372,12 @@ set_property (GObject *object, guint prop_id, case PROP_IS_MASTER: priv->is_master = g_value_get_boolean (value); break; - case PROP_HW_ADDRESS: + case PROP_PERM_HW_ADDRESS: /* construct only */ - p = hw_addr = g_value_get_string (value); - - /* Hardware address length is the number of ':' plus 1 */ - count = 1; - while (p && *p) { - if (*p++ == ':') - count++; - } - if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) { - if (hw_addr && *hw_addr) { - _LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d", - hw_addr, count); - } - break; - } - - priv->hw_addr_len = count; - g_free (priv->hw_addr); - if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len)) - priv->hw_addr = g_strdup (hw_addr); - else { - _LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr); - priv->hw_addr = NULL; - } + priv->hw_addr_perm = g_value_dup_string (value); + break; + case PROP_REFRESH_RATE_MS: + _stats_set_refresh_rate (self, g_value_get_uint (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -11617,13 +12437,13 @@ get_property (GObject *object, guint prop_id, nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL); break; case PROP_DHCP4_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4_config : NULL); + nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4.config : NULL); break; case PROP_IP6_CONFIG: nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL); break; case PROP_DHCP6_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6_config : NULL); + nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6.config : NULL); break; case PROP_STATE: g_value_set_uint (value, priv->state); @@ -11680,6 +12500,10 @@ get_property (GObject *object, guint prop_id, case PROP_HW_ADDRESS: g_value_set_string (value, priv->hw_addr); break; + case PROP_PERM_HW_ADDRESS: + /* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */ + g_value_set_string (value, nm_device_get_permanent_hw_address (self, FALSE)); + break; case PROP_HAS_PENDING_ACTION: g_value_set_boolean (value, nm_device_has_pending_action (self)); break; @@ -11717,6 +12541,15 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, slave_list); break; } + case PROP_REFRESH_RATE_MS: + g_value_set_uint (value, priv->stats.refresh_rate_ms); + break; + case PROP_TX_BYTES: + g_value_set_uint64 (value, priv->stats.tx_bytes); + break; + case PROP_RX_BYTES: + g_value_set_uint64 (value, priv->stats.rx_bytes); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -11765,6 +12598,8 @@ nm_device_class_init (NMDeviceClass *klass) klass->take_down = take_down; klass->carrier_changed = carrier_changed; klass->get_ip_iface_identifier = get_ip_iface_identifier; + klass->unmanaged_on_quit = unmanaged_on_quit; + klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr; /* Properties */ obj_properties[PROP_UDI] = @@ -11923,6 +12758,11 @@ nm_device_class_init (NMDeviceClass *klass) obj_properties[PROP_HW_ADDRESS] = g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "", NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PERM_HW_ADDRESS] = + g_param_spec_string (NM_DEVICE_PERM_HW_ADDRESS, "", "", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_HAS_PENDING_ACTION] = @@ -11960,6 +12800,23 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /* Statistics */ + obj_properties[PROP_REFRESH_RATE_MS] = + g_param_spec_uint (NM_DEVICE_STATISTICS_REFRESH_RATE_MS, "", "", + 0, UINT32_MAX, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_TX_BYTES] = + g_param_spec_uint64 (NM_DEVICE_STATISTICS_TX_BYTES, "", "", + 0, UINT64_MAX, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_RX_BYTES] = + g_param_spec_uint64 (NM_DEVICE_STATISTICS_RX_BYTES, "", "", + 0, UINT64_MAX, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); /* Signals */ @@ -12030,4 +12887,8 @@ nm_device_class_init (NMDeviceClass *klass) "Disconnect", impl_device_disconnect, "Delete", impl_device_delete, NULL); + + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), + NMDBUS_TYPE_DEVICE_STATISTICS_SKELETON, + NULL); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 21804396..34d31cad 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -26,7 +26,6 @@ #include "nm-exported-object.h" #include "nm-dbus-interface.h" -#include "nm-default.h" #include "nm-connection.h" #include "nm-rfkill-manager.h" #include "NetworkManagerUtils.h" @@ -58,6 +57,11 @@ #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_MTU "mtu" #define NM_DEVICE_HW_ADDRESS "hw-address" + +/* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet + * and NMDeviceWifi. */ +#define NM_DEVICE_PERM_HW_ADDRESS "perm-hw-address" + #define NM_DEVICE_METERED "metered" #define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors" #define NM_DEVICE_REAL "real" @@ -84,7 +88,9 @@ #define NM_DEVICE_STATE_CHANGED "state-changed" #define NM_DEVICE_LINK_INITIALIZED "link-initialized" -G_BEGIN_DECLS +#define NM_DEVICE_STATISTICS_REFRESH_RATE_MS "refresh-rate-ms" +#define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes" +#define NM_DEVICE_STATISTICS_RX_BYTES "rx-bytes" #define NM_TYPE_DEVICE (nm_device_get_type ()) #define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE, NMDevice)) @@ -275,6 +281,8 @@ typedef struct { GAsyncResult *res, GError **error); + void (* deactivate_reset_hw_addr) (NMDevice *self); + /* Sync deactivating (in the DISCONNECTED phase) */ void (* deactivate) (NMDevice *self); @@ -324,6 +332,8 @@ typedef struct { gboolean (* owns_iface) (NMDevice *self, const char *iface); NMConnection * (* new_default_connection) (NMDevice *self); + + gboolean (* unmanaged_on_quit) (NMDevice *self); } NMDeviceClass; typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device, @@ -354,7 +364,8 @@ guint32 nm_device_get_ip4_route_metric (NMDevice *dev); guint32 nm_device_get_ip6_route_metric (NMDevice *dev); const char * nm_device_get_hw_address (NMDevice *dev); -const char * nm_device_get_permanent_hw_address (NMDevice *dev); +const char * nm_device_get_permanent_hw_address (NMDevice *dev, + gboolean fallback_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); @@ -412,7 +423,7 @@ gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnec gboolean nm_device_uses_assumed_connection (NMDevice *device); -gboolean nm_device_can_assume_active_connection (NMDevice *device); +gboolean nm_device_unmanage_on_quit (NMDevice *self); gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); @@ -440,7 +451,10 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device); * (e.g. via a D-Bus command) * @NM_UNMANAGED_USER_SETTINGS: %TRUE when unmanaged by user decision via * the settings plugin (for example keyfile.unmanaged-devices or ifcfg-rh's - * NM_CONTROLLED=no) + * NM_CONTROLLED=no). Although this is user-configuration (provided from + * the settings plugins, such as NM_CONTROLLED=no in ifcfg-rh), it cannot + * be overruled and is authorative. That is because users may depend on + * dropping a ifcfg-rh file to ensure the device is unmanaged. * @NM_UNMANAGED_BY_DEFAULT: %TRUE for certain device types where we unmanage * them by default * @NM_UNMANAGED_USER_UDEV: %TRUE when unmanaged by user decision (via UDev rule) @@ -493,7 +507,7 @@ void nm_device_set_unmanaged_by_flags_queue (NMDevice *self, NMUnmanagedFlags flags, NMUnmanFlagOp set_op, NMDeviceStateReason reason); -void nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs); +void nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs); void nm_device_set_unmanaged_by_user_udev (NMDevice *self); void nm_device_set_unmanaged_by_quitting (NMDevice *device); @@ -576,8 +590,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device, void nm_device_update_hw_address (NMDevice *self); void nm_device_update_initial_hw_address (NMDevice *self); +void nm_device_update_permanent_hw_address (NMDevice *self); void nm_device_update_dynamic_ip_setup (NMDevice *self); -G_END_DECLS - -#endif /* NM_DEVICE_H */ +#endif /* __NETWORKMANAGER_DEVICE_H__ */ diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index 9cc1d086..f4663405 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -725,13 +725,20 @@ nm_lldp_listener_start (NMLldpListener *self, int ifindex, GError **error) return FALSE; } - ret = sd_lldp_new (&priv->lldp_handle, ifindex); + ret = sd_lldp_new (&priv->lldp_handle); if (ret < 0) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "initialization failed"); return FALSE; } + ret = sd_lldp_set_ifindex (priv->lldp_handle, ifindex); + if (ret < 0) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "failed setting ifindex"); + goto err; + } + ret = sd_lldp_set_callback (priv->lldp_handle, lldp_event_handler, self); if (ret < 0) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, diff --git a/src/devices/nm-lldp-listener.h b/src/devices/nm-lldp-listener.h index df02fd63..870ca8a5 100644 --- a/src/devices/nm-lldp-listener.h +++ b/src/devices/nm-lldp-listener.h @@ -21,8 +21,6 @@ #ifndef __NM_LLDP_LISTENER__ #define __NM_LLDP_LISTENER__ -G_BEGIN_DECLS - #define NM_TYPE_LLDP_LISTENER (nm_lldp_listener_get_type ()) #define NM_LLDP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LLDP_LISTENER, NMLldpListener)) #define NM_LLDP_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) @@ -48,6 +46,4 @@ gboolean nm_lldp_listener_is_running (NMLldpListener *self); GVariant *nm_lldp_listener_get_neighbors (NMLldpListener *self); -G_END_DECLS - #endif /* __NM_LLDP_LISTENER__ */ diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am index 3609ace4..db756b4c 100644 --- a/src/devices/team/Makefile.am +++ b/src/devices/team/Makefile.am @@ -49,6 +49,7 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-team.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/team/Makefile.in b/src/devices/team/Makefile.in index 4ca3014f..922ec593 100644 --- a/src/devices/team/Makefile.in +++ b/src/devices/team/Makefile.in @@ -92,8 +92,9 @@ host_triplet = @host@ @WITH_TEAMDCTL_TRUE@am__append_2 = $(LIBTEAMDCTL_LIBS) subdir = src/devices/team ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -256,6 +257,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -312,13 +314,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -330,6 +333,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -390,6 +395,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -425,6 +432,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -835,6 +843,7 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-team.so $(top_builddir)/src/NetworkManager --version >/dev/null # 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/team/nm-device-team.c b/src/devices/team/nm-device-team.c index b4b522d8..09eefe70 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -45,12 +45,18 @@ 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)) +NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceTeam, + PROP_CONFIG, +); + typedef struct { struct teamdctl *tdc; GPid teamd_pid; guint teamd_process_watch; guint teamd_timeout; + guint teamd_read_timeout; guint teamd_dbus_watch; + char *config; } NMDeviceTeamPrivate; static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); @@ -147,39 +153,74 @@ ensure_teamd_connection (NMDevice *device) return !!priv->tdc; } +static gboolean +teamd_read_config (NMDevice *device) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + char *config = NULL; + int err; + + if (priv->tdc) { + err = teamdctl_config_actual_get_raw_direct (priv->tdc, &config); + if (err) + return FALSE; + } + + if (!nm_streq0 (config, priv->config)) { + g_free (priv->config); + priv->config = g_strdup (config); + _notify (self, PROP_CONFIG); + } + + return TRUE; +} + +static gboolean +teamd_read_timeout_cb (gpointer user_data) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (user_data); + + teamd_read_config ((NMDevice *) user_data); + priv->teamd_read_timeout = 0; + + return G_SOURCE_REMOVE; +} + static void 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); + struct teamdctl *tdc = priv->tdc; if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, (NMSetting *) s_team); } - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); - if (priv->tdc) { - const char *config = NULL; - int err; + /* Read the configuration only if not already set */ + if (!priv->config && ensure_teamd_connection (device)) + teamd_read_config (device); - err = teamdctl_config_get_raw_direct (NM_DEVICE_TEAM_GET_PRIVATE (device)->tdc, - (char **)&config); - if (err == 0) - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL); - else - _LOGE (LOGD_TEAM, "failed to read teamd config (err=%d)", err); + /* Restore previous tdc state */ + if (priv->tdc && !tdc) { + teamdctl_disconnect (priv->tdc); + teamdctl_free (priv->tdc); + priv->tdc = NULL; } + + g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, priv->config, NULL); } /******************************************************************/ static gboolean master_update_slave_connection (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - GError **error) + NMDevice *slave, + NMConnection *connection, + GError **error) { NMSettingTeamPort *s_port; char *port_config = NULL; @@ -249,6 +290,7 @@ teamd_cleanup (NMDevice *device, gboolean free_tdc) nm_clear_g_source (&priv->teamd_process_watch); nm_clear_g_source (&priv->teamd_timeout); + nm_clear_g_source (&priv->teamd_read_timeout); if (priv->teamd_pid > 0) { nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, "teamd", 2000, NULL, NULL); @@ -279,6 +321,14 @@ teamd_timeout_cb (gpointer user_data) 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); + } else { + /* Read again the configuration after the timeout since it might + * have changed. + */ + if (!teamd_read_config (device)) { + _LOGW (LOGD_TEAM, "failed to read teamd configuration"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } return G_SOURCE_REMOVE; @@ -339,6 +389,8 @@ teamd_dbus_appeared (GDBusConnection *connection, success = ensure_teamd_connection (device); if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) { if (success) + success = teamd_read_config (device); + 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); @@ -523,7 +575,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) * 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) { + if (cfg && nm_streq0 (cfg, nm_setting_team_get_config (s_team))) { _LOGD (LOGD_TEAM, "using existing matching teamd config"); return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -626,6 +678,11 @@ enslave_slave (NMDevice *device, if (!success) return FALSE; + nm_clear_g_source (&priv->teamd_read_timeout); + priv->teamd_read_timeout = g_timeout_add_seconds (5, + teamd_read_timeout_cb, + self); + _LOGI (LOGD_TEAM, "enslaved team port %s", slave_iface); } else _LOGI (LOGD_TEAM, "team port %s was enslaved", slave_iface); @@ -639,6 +696,7 @@ release_slave (NMDevice *device, gboolean configure) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); gboolean success, no_firmware = FALSE; if (configure) { @@ -658,6 +716,11 @@ release_slave (NMDevice *device, if (!nm_device_bring_up (slave, TRUE, &no_firmware)) _LOGW (LOGD_TEAM, "released team port %s could not be brought up", nm_device_get_ip_iface (slave)); + + nm_clear_g_source (&priv->teamd_read_timeout); + priv->teamd_read_timeout = g_timeout_add_seconds (5, + teamd_read_timeout_cb, + self); } else _LOGI (LOGD_TEAM, "team port %s was released", nm_device_get_ip_iface (slave)); } @@ -701,6 +764,23 @@ nm_device_team_new (const char *iface) } static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (object); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + + switch (prop_id) { + case PROP_CONFIG: + g_value_set_string (value, priv->config); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void nm_device_team_init (NMDeviceTeam * self) { } @@ -738,6 +818,7 @@ dispose (GObject *object) } teamd_cleanup (device, TRUE); + g_clear_pointer (&priv->config, g_free); G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); } @@ -754,6 +835,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) object_class->constructed = constructed; object_class->dispose = dispose; + object_class->get_property = get_property; parent_class->create_and_realize = create_and_realize; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -770,6 +852,14 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->enslave_slave = enslave_slave; parent_class->release_slave = release_slave; + obj_properties[PROP_CONFIG] = + g_param_spec_string (NM_DEVICE_TEAM_CONFIG, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_TEAM_SKELETON, NULL); diff --git a/src/devices/team/nm-device-team.h b/src/devices/team/nm-device-team.h index 0e81afa7..43e8aab4 100644 --- a/src/devices/team/nm-device-team.h +++ b/src/devices/team/nm-device-team.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) #define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) #define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) @@ -32,6 +30,9 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM)) #define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +/* Properties */ +#define NM_DEVICE_TEAM_CONFIG "config" + typedef NMDevice NMDeviceTeam; typedef NMDeviceClass NMDeviceTeamClass; @@ -39,6 +40,4 @@ GType nm_device_team_get_type (void); NMDevice *nm_device_team_new (const char *iface); -G_END_DECLS - -#endif /* NM_DEVICE_TEAM_H */ +#endif /* __NETWORKMANAGER_DEVICE_TEAM_H__ */ diff --git a/src/devices/team/nm-team-factory.h b/src/devices/team/nm-team-factory.h index 9049478d..4155870c 100644 --- a/src/devices/team/nm-team-factory.h +++ b/src/devices/team/nm-team-factory.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_TEAM_FACTORY_H__ #define __NETWORKMANAGER_TEAM_FACTORY_H__ -#include "nm-default.h" - #define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type ()) #define NM_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) diff --git a/src/devices/tests/Makefile.in b/src/devices/tests/Makefile.in index b07e6dfd..7c25dc11 100644 --- a/src/devices/tests/Makefile.in +++ b/src/devices/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-lldp$(EXEEXT) test-arping$(EXEEXT) TESTS = test-lldp$(EXEEXT) test-arping$(EXEEXT) subdir = src/devices/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -428,6 +429,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -484,13 +486,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -502,6 +505,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -562,6 +567,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -597,6 +604,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c index bff85e6c..ff6f42a9 100644 --- a/src/devices/tests/test-lldp.c +++ b/src/devices/tests/test-lldp.c @@ -33,7 +33,7 @@ #include "test-common.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /*****************************************************************************/ diff --git a/src/devices/wifi/Makefile.am b/src/devices/wifi/Makefile.am index e35a84b4..add0a007 100644 --- a/src/devices/wifi/Makefile.am +++ b/src/devices/wifi/Makefile.am @@ -52,6 +52,7 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wifi.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wifi.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/wifi/Makefile.in b/src/devices/wifi/Makefile.in index 34aa4b97..134c4012 100644 --- a/src/devices/wifi/Makefile.in +++ b/src/devices/wifi/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/devices/wifi ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -295,6 +296,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -351,13 +353,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -369,6 +372,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -429,6 +434,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -464,6 +471,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -967,6 +975,7 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wifi.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wifi.so $(top_builddir)/src/NetworkManager --version >/dev/null # 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/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h index 63895a88..135226d5 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.h +++ b/src/devices/wifi/nm-device-olpc-mesh.h @@ -30,8 +30,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_DEVICE_OLPC_MESH (nm_device_olpc_mesh_get_type ()) #define NM_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMesh)) #define NM_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) @@ -67,6 +65,4 @@ GType nm_device_olpc_mesh_get_type (void); NMDevice *nm_device_olpc_mesh_new (const char *iface); -G_END_DECLS - -#endif /* NM_DEVICE_OLPC_MESH_H */ +#endif /* __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ */ diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 82b12a11..49c380af 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -21,6 +21,8 @@ #include "nm-default.h" +#include "nm-device-wifi.h" + #include <netinet/in.h> #include <string.h> #include <unistd.h> @@ -28,7 +30,6 @@ #include "nm-common-macros.h" #include "nm-device.h" -#include "nm-device-wifi.h" #include "nm-device-private.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" @@ -46,8 +47,8 @@ #include "nm-platform.h" #include "nm-auth-utils.h" #include "nm-settings-connection.h" +#include "nm-settings.h" #include "nm-enum-types.h" -#include "nm-connection-provider.h" #include "nm-core-internal.h" #include "nm-config.h" @@ -61,25 +62,20 @@ _LOG_DECLARE_SELF(NMDeviceWifi); #define SCAN_INTERVAL_STEP 20 #define SCAN_INTERVAL_MAX 120 -#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries" +#define SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN 5 -G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) - -#define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate)) +#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries" +/*****************************************************************************/ -enum { - PROP_0, - PROP_PERM_HW_ADDRESS, +NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifi, PROP_MODE, PROP_BITRATE, PROP_ACCESS_POINTS, PROP_ACTIVE_ACCESS_POINT, PROP_CAPABILITIES, PROP_SCANNING, - - LAST_PROP -}; +); enum { ACCESS_POINT_ADDED, @@ -91,26 +87,26 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -struct _NMDeviceWifiPrivate { +typedef struct { gint8 invalid_strength_counter; GHashTable * aps; NMAccessPoint * current_ap; guint32 rate; - gboolean enabled; /* rfkilled or not */ + bool enabled:1; /* rfkilled or not */ + bool requested_scan:1; + bool ssid_found:1; gint32 last_scan; gint32 scheduled_scan_time; guint8 scan_interval; /* seconds */ guint pending_scan_id; guint ap_dump_id; - bool requested_scan; NMSupplicantManager *sup_mgr; NMSupplicantInterface *sup_iface; guint sup_timeout_id; /* supplicant association timeout */ - bool ssid_found; NM80211Mode mode; guint periodic_source_id; @@ -119,8 +115,44 @@ struct _NMDeviceWifiPrivate { guint reacquire_iface_id; NMDeviceWifiCapabilities capabilities; + + gint32 hw_addr_scan_expire; + char *hw_addr_scan; +} NMDeviceWifiPrivate; + +struct _NMDeviceWifi +{ + NMDevice parent; + NMDeviceWifiPrivate _priv; }; +struct _NMDeviceWifiClass +{ + NMDeviceClass parent; + + /* Signals */ + gboolean (*scanning_allowed) (NMDeviceWifi *device); +}; + +/*****************************************************************************/ + +G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIFI_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMDeviceWifi *_self2 = (_self); \ + \ + nm_assert (NM_IS_DEVICE_WIFI (_self)); \ + &_self->_priv; \ + }) + +/*****************************************************************************/ + static gboolean check_scanning_allowed (NMDeviceWifi *self); static void schedule_scan (NMDeviceWifi *self, gboolean backoff); @@ -169,7 +201,9 @@ static void ap_add_remove (NMDeviceWifi *self, static void remove_supplicant_interface_error_handler (NMDeviceWifi *self); -/*****************************************************************/ +static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset); + +/*****************************************************************************/ static void constructed (GObject *object) @@ -187,6 +221,18 @@ constructed (GObject *object) } static gboolean +unmanaged_on_quit (NMDevice *self) +{ + /* Wi-Fi devices cannot be assumed and are always taken down. + * However, also when being disconnected, we scan and thus + * set the MAC address to a random value. + * + * We must restore the original MAC address when quitting, thus + * signal to unmanage the device. */ + return TRUE; +} + +static gboolean supplicant_interface_acquire (NMDeviceWifi *self) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); @@ -238,6 +284,24 @@ supplicant_interface_acquire (NMDeviceWifi *self) } static void +_requested_scan_set (NMDeviceWifi *self, gboolean value) +{ + NMDeviceWifiPrivate *priv; + + value = !!value; + + priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + if (priv->requested_scan == value) + return; + + priv->requested_scan = value; + if (value) + nm_device_add_pending_action ((NMDevice *) self, "scan", TRUE); + else + nm_device_remove_pending_action ((NMDevice *) self, "scan", TRUE); +} + +static void supplicant_interface_release (NMDeviceWifi *self) { NMDeviceWifiPrivate *priv; @@ -246,6 +310,8 @@ supplicant_interface_release (NMDeviceWifi *self) priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + _requested_scan_set (self, FALSE); + nm_clear_g_source (&priv->pending_scan_id); /* Reset the scan interval to be pretty frequent when disconnected */ @@ -340,7 +406,7 @@ set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_avai g_object_unref (old_ap); } - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT); + _notify (self, PROP_ACTIVE_ACCESS_POINT); } static void @@ -386,7 +452,7 @@ periodic_update (NMDeviceWifi *self) new_rate = nm_platform_wifi_get_rate (NM_PLATFORM_GET, ifindex); if (new_rate != priv->rate) { priv->rate = new_rate; - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_BITRATE); + _notify (self, PROP_BITRATE); } } @@ -397,18 +463,10 @@ periodic_update_cb (gpointer user_data) return TRUE; } -static void -realize_start_notify (NMDevice *device, const NMPlatformLink *plink) -{ - NM_DEVICE_CLASS (nm_device_wifi_parent_class)->realize_start_notify (device, plink); - - g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); -} - static gboolean bring_up (NMDevice *device, gboolean *no_firmware) { - if (!NM_DEVICE_WIFI_GET_PRIVATE (device)->enabled) + if (!NM_DEVICE_WIFI_GET_PRIVATE ((NMDeviceWifi *) device)->enabled) return FALSE; return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->bring_up (device, no_firmware); @@ -431,7 +489,7 @@ ap_add_remove (NMDeviceWifi *self, } g_signal_emit (self, signals[signum], 0, ap); - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACCESS_POINTS); + _notify (self, PROP_ACCESS_POINTS); if (signum == ACCESS_POINT_REMOVED) { g_hash_table_remove (priv->aps, nm_exported_object_get_path ((NMExportedObject *) ap)); @@ -485,10 +543,6 @@ deactivate (NMDevice *device) /* Clear any critical protocol notification in the Wi-Fi stack */ nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE); - /* Reset MAC address back to initial address */ - if (nm_device_get_initial_hw_address (device)) - nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_WIFI); - /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. */ @@ -500,7 +554,7 @@ deactivate (NMDevice *device) if (priv->mode != NM_802_11_MODE_INFRA) { priv->mode = NM_802_11_MODE_INFRA; - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_MODE); + _notify (self, PROP_MODE); } /* Ensure we trigger a scan after deactivating a Hotspot */ @@ -510,6 +564,12 @@ deactivate (NMDevice *device) } } +static void +deactivate_reset_hw_addr (NMDevice *device) +{ + _hw_addr_set_scanning ((NMDeviceWifi *) device, TRUE); +} + static gboolean is_adhoc_wpa (NMConnection *connection) { @@ -566,7 +626,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!s_wireless) return FALSE; - perm_hw_addr = nm_device_get_permanent_hw_address (device); + perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); mac = nm_setting_wireless_get_mac_address (s_wireless); if (perm_hw_addr) { if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) @@ -679,35 +739,31 @@ check_connection_available (NMDevice *device, return !!find_first_compatible_ap (NM_DEVICE_WIFI (device), connection, TRUE); } -/* - * List of manufacturer default SSIDs that are often unchanged by users. - * - * NOTE: this list should *not* contain networks that you would like to - * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot". - */ -static const char * -manf_defaults[] = { - "linksys", - "linksys-a", - "linksys-g", - "default", - "belkin54g", - "NETGEAR", - "o2DSL", - "WLAN", - "ALICE-WLAN", - "Speedport W 501V", - "TURBONETT", -}; - -#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0])) - static gboolean is_manf_default_ssid (const GByteArray *ssid) { int i; - - for (i = 0; i < ARRAY_SIZE (manf_defaults); i++) { + /* + * List of manufacturer default SSIDs that are often unchanged by users. + * + * NOTE: this list should *not* contain networks that you would like to + * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot". + */ + static const char *manf_defaults[] = { + "linksys", + "linksys-a", + "linksys-g", + "default", + "belkin54g", + "NETGEAR", + "o2DSL", + "WLAN", + "ALICE-WLAN", + "Speedport W 501V", + "TURBONETT", + }; + + for (i = 0; i < G_N_ELEMENTS (manf_defaults); i++) { if (ssid->len == strlen (manf_defaults[i])) { if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0) return TRUE; @@ -862,7 +918,7 @@ complete_connection (NMDevice *device, if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - perm_hw_addr = nm_device_get_permanent_hw_address (device); + perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); if (perm_hw_addr) { setting_mac = nm_setting_wireless_get_mac_address (s_wifi); if (setting_mac) { @@ -1022,6 +1078,60 @@ impl_device_wifi_get_all_access_points (NMDeviceWifi *self, } static void +_hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset) +{ + NMDevice *device = (NMDevice *) self; + NMDeviceWifiPrivate *priv; + guint32 now; + gboolean randomize; + + g_return_if_fail (NM_IS_DEVICE_WIFI (self)); + + if ( nm_device_is_activating (device) + || nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) + return; + + priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + randomize = nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA, + "wifi.scan-rand-mac-address", + device, + TRUE, TRUE); + + if (!randomize) { + g_clear_pointer (&priv->hw_addr_scan, g_free); + if (do_reset) + nm_device_hw_addr_reset (device, "scanning"); + return; + } + + now = nm_utils_get_monotonic_timestamp_s (); + + if ( !priv->hw_addr_scan + || now >= priv->hw_addr_scan_expire) { + gs_free char *generate_mac_address_mask = NULL; + + /* the random MAC address for scanning expires after a while. + * + * We don't bother with to update the MAC address exactly when + * it expires, instead on the next scan request, we will generate + * a new one.*/ + priv->hw_addr_scan_expire = now + (SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN * 60); + + generate_mac_address_mask = nm_config_data_get_device_config (NM_CONFIG_GET_DATA, + "wifi.scan-generate-mac-address-mask", + device, + NULL); + + g_free (priv->hw_addr_scan); + priv->hw_addr_scan = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (device), + generate_mac_address_mask); + } + + nm_device_hw_addr_set (device, priv->hw_addr_scan, "scanning"); +} + +static void request_scan_cb (NMDevice *device, GDBusMethodInvocation *context, NMAuthSubject *subject, @@ -1199,7 +1309,7 @@ check_scanning_allowed (NMDeviceWifi *self) } static gboolean -hidden_filter_func (NMConnectionProvider *provider, +hidden_filter_func (NMSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1226,12 +1336,12 @@ build_hidden_probe_list (NMDeviceWifi *self) if (G_UNLIKELY (nullssid == NULL)) nullssid = g_byte_array_new (); - connections = nm_connection_provider_get_best_connections (nm_connection_provider_get (), - max_scan_ssids - 1, - NM_SETTING_WIRELESS_SETTING_NAME, - NULL, - hidden_filter_func, - NULL); + connections = nm_settings_get_best_connections (nm_device_get_settings ((NMDevice *) self), + max_scan_ssids - 1, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL, + hidden_filter_func, + NULL); if (connections && connections->data) { ssids = g_ptr_array_new_full (max_scan_ssids - 1, (GDestroyNotify) g_byte_array_unref); g_ptr_array_add (ssids, g_byte_array_ref (nullssid)); /* Add wildcard SSID */ @@ -1330,11 +1440,12 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options) _LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan"); } + _hw_addr_set_scanning (self, FALSE); + if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) { /* success */ backoff = TRUE; - priv->requested_scan = TRUE; - nm_device_add_pending_action (NM_DEVICE (self), "scan", TRUE); + _requested_scan_set (self, TRUE); } if (ssids) @@ -1349,10 +1460,11 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options) static gboolean request_wireless_scan_periodic (gpointer user_data) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (user_data); + NMDeviceWifi *self = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); priv->pending_scan_id = 0; - request_wireless_scan (user_data, NULL); + request_wireless_scan (self, NULL); return FALSE; } @@ -1416,10 +1528,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, priv->last_scan = nm_utils_get_monotonic_timestamp_s (); schedule_scan (self, success); - if (priv->requested_scan) { - priv->requested_scan = FALSE; - nm_device_remove_pending_action (NM_DEVICE (self), "scan", TRUE); - } + _requested_scan_set (self, FALSE); } /**************************************************************************** @@ -1458,10 +1567,12 @@ schedule_ap_list_dump (NMDeviceWifi *self) } static void -try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) +try_fill_ssid_for_hidden_ap (NMDeviceWifi *self, + NMAccessPoint *ap) { const char *bssid; - const GSList *connections, *iter; + NMSettingsConnection *const*connections; + guint i; g_return_if_fail (nm_ap_get_ssid (ap) == NULL); @@ -1470,9 +1581,9 @@ try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ - connections = nm_connection_provider_get_connections (nm_connection_provider_get ()); - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMConnection *connection = NM_CONNECTION (iter->data); + connections = nm_settings_get_connections (nm_device_get_settings ((NMDevice *) self), NULL); + for (i = 0; connections[i]; i++) { + NMConnection *connection = (NMConnection *) connections[i]; NMSettingWireless *s_wifi; s_wifi = nm_connection_get_setting_wireless (connection); @@ -1522,7 +1633,7 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, ssid = nm_ap_get_ssid (ap); if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { /* Try to fill the SSID from the AP database */ - try_fill_ssid_for_hidden_ap (ap); + try_fill_ssid_for_hidden_ap (self, ap); ssid = nm_ap_get_ssid (ap); if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { @@ -1951,6 +2062,11 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, else _LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up"); break; + case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE: + _requested_scan_set (self, FALSE); + nm_clear_g_source (&priv->pending_scan_id); + request_wireless_scan (self, NULL); + break; default: break; } @@ -1964,7 +2080,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, /* Signal scanning state changes */ if ( new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING || old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING) - g_object_notify (G_OBJECT (self), "scanning"); + _notify (self, PROP_SCANNING); } static void @@ -2008,7 +2124,7 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface, scanning = nm_supplicant_interface_get_scanning (iface); _LOGD (LOGD_WIFI_SCAN, "now %s", scanning ? "scanning" : "idle"); - g_object_notify (G_OBJECT (self), "scanning"); + _notify (self, PROP_SCANNING); /* Run a quick update of current AP when coming out of a scan */ state = nm_device_get_state (NM_DEVICE (self)); @@ -2197,9 +2313,6 @@ build_supplicant_config (NMDeviceWifi *self, NMSupplicantConfig *config = NULL; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; - NMSupplicantFeature mac_randomization_support; - NMSettingMacRandomization mac_randomization_fallback; - gs_free char *svalue = NULL; g_return_val_if_fail (priv->sup_iface, NULL); @@ -2214,20 +2327,9 @@ build_supplicant_config (NMDeviceWifi *self, _LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); } - mac_randomization_support = nm_supplicant_interface_get_mac_randomization_support (priv->sup_iface); - svalue = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - "wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, - NM_DEVICE (self)); - mac_randomization_fallback = _nm_utils_ascii_str_to_int64 (svalue, 10, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, - NM_SETTING_MAC_RANDOMIZATION_ALWAYS, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT); - if (!nm_supplicant_config_add_setting_wireless (config, s_wireless, fixed_freq, - mac_randomization_support, - mac_randomization_fallback, error)) { g_prefix_error (error, "802-11-wireless: "); goto error; @@ -2277,7 +2379,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) NMActRequest *req; NMConnection *connection; NMSettingWireless *s_wireless; - const char *cloned_mac; const char *mode; const char *ap_path; @@ -2305,7 +2406,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) /* Scanning not done in AP mode; clear the scan list */ remove_all_aps (self); } - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_MODE); + _notify (self, PROP_MODE); /* The kernel doesn't support Ad-Hoc WPA connections well at this time, * and turns them into open networks. It's been this way since at least @@ -2317,9 +2418,12 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_FAILURE; } + /* forget the temporary MAC address used during scanning */ + g_clear_pointer (&priv->hw_addr_scan, g_free); + /* Set spoof MAC to the interface */ - cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); - nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_WIFI); + if (!nm_device_hw_addr_set_cloned (device, connection, TRUE)) + return NM_ACT_STAGE_RETURN_FAILURE; /* AP mode never uses a specific object or existing scanned AP */ if (priv->mode != NM_802_11_MODE_AP) { @@ -2859,6 +2963,8 @@ set_enabled (NMDevice *device, gboolean enabled) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceState state; + enabled = !!enabled; + if (priv->enabled == enabled) return; @@ -2959,6 +3065,8 @@ finalize (GObject *object) g_hash_table_unref (priv->aps); + g_free (priv->hw_addr_scan); + G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); } @@ -2973,9 +3081,6 @@ get_property (GObject *object, guint prop_id, GPtrArray *array; switch (prop_id) { - case PROP_PERM_HW_ADDRESS: - g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (device))); - break; case PROP_MODE: g_value_set_uint (value, priv->mode); break; @@ -3030,8 +3135,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); - g_type_class_add_private (object_class, sizeof (NMDeviceWifiPrivate)); - NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) object_class->constructed = constructed; @@ -3040,7 +3143,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; - parent_class->realize_start_notify = realize_start_notify; parent_class->bring_up = bring_up; parent_class->can_auto_connect = can_auto_connect; parent_class->is_available = is_available; @@ -3057,90 +3159,81 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout; parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout; parent_class->deactivate = deactivate; + parent_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; + parent_class->unmanaged_on_quit = unmanaged_on_quit; parent_class->state_changed = device_state_changed; klass->scanning_allowed = scanning_allowed; /* Properties */ - g_object_class_install_property - (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_MODE, - g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_BITRATE, - g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_ACCESS_POINTS, - g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_ACTIVE_ACCESS_POINT, - g_param_spec_string (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_SCANNING, - g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_MODE] = + g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_AP, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BITRATE] = + g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACCESS_POINTS] = + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACTIVE_ACCESS_POINT] = + g_param_spec_string (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CAPABILITIES] = + g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SCANNING] = + g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); /* Signals */ signals[ACCESS_POINT_ADDED] = - g_signal_new ("access-point-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_added), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_AP); + g_signal_new ("access-point-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_AP); signals[ACCESS_POINT_REMOVED] = - g_signal_new ("access-point-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_AP); + g_signal_new ("access-point-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_AP); signals[SCANNING_ALLOWED] = - g_signal_new ("scanning-allowed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_allowed), - scanning_allowed_accumulator, NULL, NULL, - G_TYPE_BOOLEAN, 0); + g_signal_new ("scanning-allowed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_allowed), + scanning_allowed_accumulator, NULL, NULL, + G_TYPE_BOOLEAN, 0); nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_WIFI_SKELETON, diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index 7e0d06f5..ba9d60e2 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2016 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -25,18 +25,13 @@ #include "nm-device.h" #include "nm-wifi-ap.h" -struct NMAccessPointList; +#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type ()) +#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) +#define NM_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIFI)) +#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) +#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -G_BEGIN_DECLS - -#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type ()) -#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) -#define NM_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIFI)) -#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) -#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) - -#define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_WIFI_MODE "mode" #define NM_DEVICE_WIFI_BITRATE "bitrate" #define NM_DEVICE_WIFI_ACCESS_POINTS "access-points" @@ -44,37 +39,11 @@ G_BEGIN_DECLS #define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" #define NM_DEVICE_WIFI_SCANNING "scanning" -#ifndef NM_DEVICE_WIFI_DEFINED -#define NM_DEVICE_WIFI_DEFINED typedef struct _NMDeviceWifi NMDeviceWifi; -#endif - typedef struct _NMDeviceWifiClass NMDeviceWifiClass; -typedef struct _NMDeviceWifiPrivate NMDeviceWifiPrivate; - -struct _NMDeviceWifi -{ - NMDevice parent; - - /*< private >*/ - NMDeviceWifiPrivate *priv; -}; - -struct _NMDeviceWifiClass -{ - NMDeviceClass parent; - - /* Signals */ - void (*access_point_added) (NMDeviceWifi *device, NMAccessPoint *ap); - void (*access_point_removed) (NMDeviceWifi *device, NMAccessPoint *ap); - gboolean (*scanning_allowed) (NMDeviceWifi *device); -}; - GType nm_device_wifi_get_type (void); NMDevice * nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities); -G_END_DECLS - -#endif /* NM_DEVICE_WIFI_H */ +#endif /* __NETWORKMANAGER_DEVICE_WIFI_H__ */ diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index a0c25709..e1beb85b 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -42,29 +42,48 @@ typedef struct char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */ /* Scanned or cached values */ - GByteArray * ssid; - char * address; - NM80211Mode mode; - guint8 strength; - guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ - guint32 max_bitrate;/* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ + GByteArray * ssid; + char * address; + NM80211Mode mode; + guint8 strength; + guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ + guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ NM80211ApFlags flags; /* General flags */ NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */ NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */ /* Non-scanned attributes */ - gboolean fake; /* Whether or not the AP is from a scan */ - gboolean hotspot; /* Whether the AP is a local device's hotspot network */ + bool fake; /* Whether or not the AP is from a scan */ + bool hotspot; /* Whether the AP is a local device's hotspot network */ gint32 last_seen; /* Timestamp when the AP was seen lastly (obtained via nm_utils_get_monotonic_timestamp_s()) */ } NMAccessPointPrivate; -#define NM_AP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP, NMAccessPointPrivate)) +struct _NMAccessPoint { + NMExportedObject parent; + NMAccessPointPrivate _priv; +}; + +struct _NMAccessPointClass{ + NMExportedObjectClass parent; +}; + +#define NM_AP_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMAccessPoint *_self2 = (_self); \ + \ + nm_assert (NM_IS_AP (_self)); \ + &_self->_priv; \ + }) G_DEFINE_TYPE (NMAccessPoint, nm_ap, NM_TYPE_EXPORTED_OBJECT) -enum { - PROP_0, +NM_GOBJECT_PROPERTIES_DEFINE (NMAccessPoint, PROP_FLAGS, PROP_WPA_FLAGS, PROP_RSN_FLAGS, @@ -75,8 +94,7 @@ enum { PROP_MAX_BITRATE, PROP_STRENGTH, PROP_LAST_SEEN, - LAST_PROP -}; +); /*****************************************************************/ @@ -130,7 +148,7 @@ nm_ap_set_ssid (NMAccessPoint *ap, const guint8 *ssid, gsize len) g_byte_array_append (priv->ssid, ssid, len); } - g_object_notify (G_OBJECT (ap), NM_AP_SSID); + _notify (ap, PROP_SSID); } static void @@ -144,7 +162,7 @@ nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags) if (priv->flags != flags) { priv->flags = flags; - g_object_notify (G_OBJECT (ap), NM_AP_FLAGS); + _notify (ap, PROP_FLAGS); } } @@ -158,7 +176,7 @@ nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags) priv = NM_AP_GET_PRIVATE (ap); if (priv->wpa_flags != flags) { priv->wpa_flags = flags; - g_object_notify (G_OBJECT (ap), NM_AP_WPA_FLAGS); + _notify (ap, PROP_WPA_FLAGS); } } @@ -172,7 +190,7 @@ nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags) priv = NM_AP_GET_PRIVATE (ap); if (priv->rsn_flags != flags) { priv->rsn_flags = flags; - g_object_notify (G_OBJECT (ap), NM_AP_RSN_FLAGS); + _notify (ap, PROP_RSN_FLAGS); } } @@ -198,7 +216,7 @@ nm_ap_set_address (NMAccessPoint *ap, const char *addr) if (!priv->address || !nm_utils_hwaddr_matches (addr, -1, priv->address, -1)) { g_free (priv->address); priv->address = g_strdup (addr); - g_object_notify (G_OBJECT (ap), NM_AP_HW_ADDRESS); + _notify (ap, PROP_HW_ADDRESS); } } @@ -223,7 +241,7 @@ nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode) if (priv->mode != mode) { priv->mode = mode; - g_object_notify (G_OBJECT (ap), NM_AP_MODE); + _notify (ap, PROP_MODE); } } @@ -254,7 +272,7 @@ nm_ap_set_strength (NMAccessPoint *ap, const gint8 strength) if (priv->strength != strength) { priv->strength = strength; - g_object_notify (G_OBJECT (ap), NM_AP_STRENGTH); + _notify (ap, PROP_STRENGTH); } } @@ -278,7 +296,7 @@ nm_ap_set_freq (NMAccessPoint *ap, if (priv->freq != freq) { priv->freq = freq; - g_object_notify (G_OBJECT (ap), NM_AP_FREQUENCY); + _notify (ap, PROP_FREQUENCY); } } @@ -302,7 +320,7 @@ nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate) if (priv->max_bitrate != bitrate) { priv->max_bitrate = bitrate; - g_object_notify (G_OBJECT (ap), NM_AP_MAX_BITRATE); + _notify (ap, PROP_MAX_BITRATE); } } @@ -333,7 +351,7 @@ nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen) if (priv->last_seen != last_seen) { priv->last_seen = last_seen; - g_object_notify (G_OBJECT (ap), NM_AP_LAST_SEEN); + _notify (ap, PROP_LAST_SEEN); } } @@ -347,18 +365,20 @@ security_from_vardict (GVariant *security) g_return_val_if_fail (g_variant_is_of_type (security, G_VARIANT_TYPE_VARDICT), NM_802_11_AP_SEC_NONE); - if (g_variant_lookup (security, "KeyMgmt", "^a&s", &array)) { - if (_nm_utils_string_in_list ("wpa-psk", array)) + if ( g_variant_lookup (security, "KeyMgmt", "^a&s", &array) + && array) { + if (g_strv_contains (array, "wpa-psk")) flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; - if (_nm_utils_string_in_list ("wpa-eap", array)) + if (g_strv_contains (array, "wpa-eap")) flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; g_free (array); } - if (g_variant_lookup (security, "Pairwise", "^a&s", &array)) { - if (_nm_utils_string_in_list ("tkip", array)) + if ( g_variant_lookup (security, "Pairwise", "^a&s", &array) + && array) { + if (g_strv_contains (array, "tkip")) flags |= NM_802_11_AP_SEC_PAIR_TKIP; - if (_nm_utils_string_in_list ("ccmp", array)) + if (g_strv_contains (array, "ccmp")) flags |= NM_802_11_AP_SEC_PAIR_CCMP; g_free (array); } @@ -879,7 +899,7 @@ nm_ap_init (NMAccessPoint *ap) static void finalize (GObject *object) { - NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object); + NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE ((NMAccessPoint *) object); g_free (priv->supplicant_path); if (priv->ssid) @@ -891,16 +911,16 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { - NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object); + NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE ((NMAccessPoint *) object); GVariant *ssid; switch (prop_id) { @@ -965,8 +985,6 @@ nm_ap_class_init (NMAccessPointClass *ap_class) | NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X; - g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate)); - exported_object_class->export_path = NM_DBUS_PATH_ACCESS_POINT "/%u"; /* virtual methods */ @@ -975,72 +993,64 @@ nm_ap_class_init (NMAccessPointClass *ap_class) object_class->finalize = finalize; /* properties */ - g_object_class_install_property - (object_class, PROP_FLAGS, - g_param_spec_uint (NM_AP_FLAGS, "", "", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_FLAGS_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_WPA_FLAGS, - g_param_spec_uint (NM_AP_WPA_FLAGS, "", "", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_RSN_FLAGS, - g_param_spec_uint (NM_AP_RSN_FLAGS, "", "", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_SSID, - g_param_spec_variant (NM_AP_SSID, "", "", - G_VARIANT_TYPE ("ay"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_FREQUENCY, - g_param_spec_uint (NM_AP_FREQUENCY, "", "", - 0, 10000, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_AP_HW_ADDRESS, "", "", + obj_properties[PROP_FLAGS] = + g_param_spec_uint (NM_AP_FLAGS, "", "", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_WPA_FLAGS] = + g_param_spec_uint (NM_AP_WPA_FLAGS, "", "", + NM_802_11_AP_SEC_NONE, + all_sec_flags, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_RSN_FLAGS] = + g_param_spec_uint (NM_AP_RSN_FLAGS, "", "", + NM_802_11_AP_SEC_NONE, + all_sec_flags, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SSID] = + g_param_spec_variant (NM_AP_SSID, "", "", + G_VARIANT_TYPE ("ay"), NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_MODE, - g_param_spec_uint (NM_AP_MODE, "", "", - NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_MAX_BITRATE, - g_param_spec_uint (NM_AP_MAX_BITRATE, "", "", - 0, G_MAXUINT16, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_STRENGTH, - g_param_spec_uchar (NM_AP_STRENGTH, "", "", - 0, G_MAXINT8, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_LAST_SEEN, - g_param_spec_int (NM_AP_LAST_SEEN, "", "", - -1, G_MAXINT, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FREQUENCY] = + g_param_spec_uint (NM_AP_FREQUENCY, "", "", + 0, 10000, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string (NM_AP_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MODE] = + g_param_spec_uint (NM_AP_MODE, "", "", + NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MAX_BITRATE] = + g_param_spec_uint (NM_AP_MAX_BITRATE, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STRENGTH] = + g_param_spec_uchar (NM_AP_STRENGTH, "", "", + 0, G_MAXINT8, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LAST_SEEN] = + g_param_spec_int (NM_AP_LAST_SEEN, "", "", + -1, G_MAXINT, -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ap_class), NMDBUS_TYPE_ACCESS_POINT_SKELETON, diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index 84aff983..035d1b5e 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -44,14 +44,8 @@ #define NM_AP_STRENGTH "strength" #define NM_AP_LAST_SEEN "last-seen" -typedef struct { - NMExportedObject parent; -} NMAccessPoint; - -typedef struct { - NMExportedObjectClass parent; - -} NMAccessPointClass; +typedef struct _NMAccessPoint NMAccessPoint; +typedef struct _NMAccessPointClass NMAccessPointClass; GType nm_ap_get_type (void); diff --git a/src/devices/wifi/tests/Makefile.in b/src/devices/wifi/tests/Makefile.in index 956730f8..64113a21 100644 --- a/src/devices/wifi/tests/Makefile.in +++ b/src/devices/wifi/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-wifi-ap-utils$(EXEEXT) TESTS = test-wifi-ap-utils$(EXEEXT) subdir = src/devices/wifi/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -423,6 +424,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -479,13 +481,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -497,6 +500,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -557,6 +562,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -592,6 +599,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c index 838368c4..dbe185b3 100644 --- a/src/devices/wifi/tests/test-wifi-ap-utils.c +++ b/src/devices/wifi/tests/test-wifi-ap-utils.c @@ -26,7 +26,7 @@ #include "nm-core-internal.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define DEBUG 1 diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 1777eb36..0d061a79 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -16,6 +16,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) @@ -26,7 +27,7 @@ pkglib_LTLIBRARIES = libnm-wwan.la libnm-device-plugin-wwan.la GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM -GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' nm_modem_enum_types_sources = $(srcdir)/nm-modem.h BUILT_SOURCES += $(GLIB_GENERATED) @@ -41,6 +42,13 @@ libnm_wwan_la_SOURCES = \ \ $(GLIB_GENERATED) +if WITH_OFONO +libnm_wwan_la_SOURCES += \ + nm-modem-ofono.c \ + nm-modem-ofono.h \ + $(NULL) +endif + WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ @@ -49,6 +57,7 @@ libnm_wwan_la_LDFLAGS = \ libnm_wwan_la_LIBADD = \ $(top_builddir)/introspection/libnmdbus.la \ $(GLIB_LIBS) \ + $(LIBSYSTEMD_LIBS) \ $(MM_GLIB_LIBS) ########################################################### @@ -79,7 +88,9 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wwan.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-wwan.so $(WWAN_SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index 89328665..6d395567 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -88,10 +88,16 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@WITH_OFONO_TRUE@am__append_1 = \ +@WITH_OFONO_TRUE@ nm-modem-ofono.c \ +@WITH_OFONO_TRUE@ nm-modem-ofono.h \ +@WITH_OFONO_TRUE@ $(NULL) + subdir = src/devices/wwan ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -157,10 +163,16 @@ libnm_device_plugin_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ libnm_wwan_la_DEPENDENCIES = \ $(top_builddir)/introspection/libnmdbus.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__libnm_wwan_la_SOURCES_DIST = nm-modem-broadband.c \ + nm-modem-broadband.h nm-modem-manager.c nm-modem-manager.h \ + nm-modem.c nm-modem.h nm-modem-enum-types.h \ + nm-modem-enum-types.c nm-modem-ofono.c nm-modem-ofono.h am__objects_1 = nm-modem-enum-types.lo +@WITH_OFONO_TRUE@am__objects_2 = nm-modem-ofono.lo am_libnm_wwan_la_OBJECTS = nm-modem-broadband.lo nm-modem-manager.lo \ - nm-modem.lo $(am__objects_1) + nm-modem.lo $(am__objects_1) $(am__objects_2) libnm_wwan_la_OBJECTS = $(am_libnm_wwan_la_OBJECTS) libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -202,7 +214,7 @@ am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ $(libnm_wwan_la_SOURCES) DIST_SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ - $(libnm_wwan_la_SOURCES) + $(am__libnm_wwan_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -264,6 +276,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -320,13 +333,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -338,6 +352,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -398,6 +414,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -433,6 +451,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -508,6 +527,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) @@ -516,18 +536,11 @@ pkglib_LTLIBRARIES = libnm-wwan.la libnm-device-plugin-wwan.la ########################################################### GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM -GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' nm_modem_enum_types_sources = $(srcdir)/nm-modem.h -libnm_wwan_la_SOURCES = \ - nm-modem-broadband.c \ - nm-modem-broadband.h \ - nm-modem-manager.c \ - nm-modem-manager.h \ - nm-modem.c \ - nm-modem.h \ - \ - $(GLIB_GENERATED) - +libnm_wwan_la_SOURCES = nm-modem-broadband.c nm-modem-broadband.h \ + nm-modem-manager.c nm-modem-manager.h nm-modem.c nm-modem.h \ + $(GLIB_GENERATED) $(am__append_1) WWAN_SYMBOL_VIS_FILE = $(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ -avoid-version \ @@ -536,6 +549,7 @@ libnm_wwan_la_LDFLAGS = \ libnm_wwan_la_LIBADD = \ $(top_builddir)/introspection/libnmdbus.la \ $(GLIB_LIBS) \ + $(LIBSYSTEMD_LIBS) \ $(MM_GLIB_LIBS) @@ -646,6 +660,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-broadband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-enum-types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-ofono.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wwan-factory.Plo@am__quote@ @@ -897,7 +912,9 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wwan.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-wwan.so $(WWAN_SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null # 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/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index a8361c49..0f96dafb 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -60,6 +60,7 @@ static void ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: @@ -73,7 +74,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) case NM_DEVICE_STATE_ACTIVATED: if (nm_device_activate_ip4_state_in_conf (device)) nm_device_activate_schedule_ip4_config_timeout (device); - else { + else if (nm_device_activate_ip6_state_in_conf (device)) + nm_device_activate_schedule_ip6_config_timeout (device); + else if (nm_device_activate_ip4_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else if (nm_device_activate_ip6_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device)); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -159,8 +171,9 @@ modem_ip4_config_result (NMModem *modem, if (error) { _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message); - - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else { nm_device_set_wwan_ip4_config (device, config); nm_device_activate_schedule_ip4_config_result (device, NULL); @@ -184,9 +197,11 @@ modem_ip6_config_result (NMModem *modem, g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); if (error) { - _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message); - - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", + error->message); + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); return; } @@ -201,7 +216,9 @@ modem_ip6_config_result (NMModem *modem, nm_device_activate_schedule_ip6_config_result (device); else { _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } return; } @@ -211,7 +228,7 @@ modem_ip6_config_result (NMModem *modem, g_assert (ignored == NULL); switch (ret) { case NM_ACT_STAGE_RETURN_FAILURE: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + nm_device_ip_method_failed (device, AF_INET6, reason); break; case NM_ACT_STAGE_RETURN_STOP: /* all done */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 1a6e6b25..727c8409 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -30,6 +30,8 @@ #include "nm-device-private.h" #include "nm-platform.h" +#define NM_MODEM_BROADBAND_MODEM "modem" + G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) typedef enum { @@ -89,8 +91,35 @@ enum { /*****************************************************************************/ +#define _NMLOG_DOMAIN LOGD_MB +#define _NMLOG_PREFIX_NAME "modem-broadband" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ + NMModemBroadband *const __self = (self); \ + char __prefix_name[128]; \ + const char *__uid; \ + \ + _nm_log (_level, (_NMLOG_DOMAIN), 0, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self \ + ? ({ \ + ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ + ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + static NMDeviceStateReason -translate_mm_error (GError *error) +translate_mm_error (NMModemBroadband *self, GError *error) { NMDeviceStateReason reason; @@ -122,7 +151,7 @@ translate_mm_error (GError *error) reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT; else { /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ - nm_log_dbg (LOGD_MB, "unmapped error detected: '%s'", error->message); + _LOGD ("unmapped error detected: '%s'", error->message); reason = NM_DEVICE_STATE_REASON_UNKNOWN; } @@ -288,7 +317,7 @@ connect_context_clear (NMModemBroadband *self) g_clear_error (&ctx->first_error); g_clear_pointer (&ctx->ip_types, (GDestroyNotify) g_array_unref); - g_clear_object (&ctx->cancellable); + nm_clear_g_cancellable (&ctx->cancellable); g_clear_object (&ctx->connection); g_clear_object (&ctx->connect_properties); g_clear_object (&ctx->self); @@ -360,8 +389,7 @@ connect_ready (MMModemSimple *simple_iface, 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))); + _LOGW ("failed to connect modem: invalid bearer IP configuration"); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); connect_context_clear (self); return; @@ -389,7 +417,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self) return; if (!self->priv->ctx || self->priv->ctx->step != CONNECT_STEP_UNLOCK) - return; + g_return_if_reached (); if (error) { if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || @@ -397,7 +425,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self) mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { ask_for_pin (self); } else { - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, error)); } return; } @@ -459,9 +487,8 @@ connect_context_step (NMModemBroadband *self) else if (MODEM_CAPS_3GPP2 (ctx->caps)) ctx->connect_properties = create_cdma_connect_properties (ctx->connection); else { - 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 (ctx->connection)); + _LOGW ("failed to connect '%s': not a mobile broadband modem", + nm_connection_get_id (ctx->connection)); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); connect_context_clear (self); @@ -472,10 +499,9 @@ connect_context_step (NMModemBroadband *self) /* Build up list of IP types that we need to use in the retries */ ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), ctx->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 (ctx->connection), - error->message); + _LOGW ("failed to connect '%s': %s", + nm_connection_get_id (ctx->connection), + error->message); g_clear_error (&error); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); @@ -502,10 +528,9 @@ connect_context_step (NMModemBroadband *self) else g_assert_not_reached (); - nm_log_dbg (LOGD_MB, "(%s): launching connection with ip type '%s' (try %d)", - nm_modem_get_uid (NM_MODEM (self)), - nm_modem_ip_type_to_string (current), - ctx->ip_type_tries + 1); + _LOGD ("launching connection with ip type '%s' (try %d)", + nm_modem_ip_type_to_string (current), + ctx->ip_type_tries + 1); mm_modem_simple_connect (self->priv->simple_iface, ctx->connect_properties, @@ -528,10 +553,9 @@ connect_context_step (NMModemBroadband *self) 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 (self)), - ctx->first_error->message); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (ctx->first_error)); + _LOGW ("failed to connect modem: %s", + ctx->first_error->message); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, ctx->first_error)); } connect_context_clear (self); @@ -550,8 +574,7 @@ act_stage1_prepare (NMModem *_self, 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))); + _LOGW ("cannot access the Simple mobile broadband modem interface"); *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -745,9 +768,8 @@ 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)), - NM_G_ERROR_MSG (error)); + _LOGD ("failed to set modem low power state: %s", + NM_G_ERROR_MSG (error)); g_clear_error (&error); } @@ -770,9 +792,8 @@ 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_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _LOGW ("failed to disable modem: %s", + NM_G_ERROR_MSG (error)); nm_modem_set_prev_state (NM_MODEM (self), "disable failed"); g_clear_error (&error); } @@ -789,9 +810,8 @@ modem_enable_ready (MMModem *modem_iface, GError *error = NULL; if (!mm_modem_enable_finish (modem_iface, res, &error)) { - nm_log_warn (LOGD_MB, "(%s) failed to enable modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _LOGW ("failed to enable modem: %s", + NM_G_ERROR_MSG (error)); nm_modem_set_prev_state (NM_MODEM (self), "enable failed"); g_clear_error (&error); } @@ -854,8 +874,7 @@ static_stage3_ip4_done (NMModemBroadband *self) g_assert (self->priv->ipv4_config); g_assert (self->priv->bearer); - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", - nm_modem_get_uid (NM_MODEM (self))); + _LOGI ("IPv4 static configuration:"); /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config); @@ -880,15 +899,15 @@ static_stage3_ip4_done (NMModemBroadband *self) address.address = address_network; address.peer_address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); - address.source = NM_IP_CONFIG_SOURCE_WWAN; + address.addr_source = NM_IP_CONFIG_SOURCE_WWAN; if (address.plen <= 32) nm_ip4_config_add_address (config, &address); - nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + _LOGI (" address %s/%d", address_string, address.plen); if (gw) { nm_ip4_config_set_gateway (config, gw); - nm_log_info (LOGD_MB, " gateway %s", gw_string); + _LOGI (" gateway %s", gw_string); } /* DNS servers */ @@ -897,7 +916,7 @@ static_stage3_ip4_done (NMModemBroadband *self) if ( ip4_string_to_num (dns[i], &address_network) && address_network > 0) { nm_ip4_config_add_nameserver (config, address_network); - nm_log_info (LOGD_MB, " DNS %s", dns[i]); + _LOGI (" DNS %s", dns[i]); } } @@ -964,8 +983,7 @@ stage3_ip6_done (NMModemBroadband *self) goto out; } - nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:", - nm_modem_get_uid (NM_MODEM (self))); + _LOGI ("IPv6 base configuration:"); data_port = mm_bearer_get_interface (self->priv->bearer); g_assert (data_port); @@ -975,7 +993,7 @@ stage3_ip6_done (NMModemBroadband *self) if (address.plen <= 128) nm_ip6_config_add_address (config, &address); - nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + _LOGI (" address %s/%d", address_string, address.plen); address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config); if (address_string) { @@ -987,7 +1005,7 @@ stage3_ip6_done (NMModemBroadband *self) address_string); goto out; } - nm_log_info (LOGD_MB, " gateway %s", address_string); + _LOGI (" gateway %s", address_string); nm_ip6_config_set_gateway (config, &address.address); } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { /* Gateway required for the 'static' method */ @@ -1005,7 +1023,7 @@ stage3_ip6_done (NMModemBroadband *self) if (inet_pton (AF_INET6, dns[i], &addr)) { nm_ip6_config_add_nameserver (config, &addr); - nm_log_info (LOGD_MB, " DNS %s", dns[i]); + _LOGI (" DNS %s", dns[i]); } } @@ -1050,19 +1068,6 @@ disconnect_context_complete (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) @@ -1079,9 +1084,10 @@ simple_disconnect_ready (MMModemSimple *modem_iface, if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) { if (ctx->warn && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { - nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s", - nm_modem_get_uid (NM_MODEM (ctx->self)), - error->message); + NMModemBroadband *self = ctx->self; + + _LOGW ("failed to disconnect modem: %s", + error->message); } g_simple_async_result_take_error (ctx->result, error); } @@ -1098,9 +1104,11 @@ disconnect (NMModem *modem, { NMModemBroadband *self = NM_MODEM_BROADBAND (modem); DisconnectContext *ctx; + GError *error = NULL; connect_context_clear (self); ctx = g_slice_new (DisconnectContext); + ctx->cancellable = NULL; ctx->self = g_object_ref (self); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, @@ -1109,10 +1117,12 @@ disconnect (NMModem *modem, /* 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)) + /* Already cancelled? */ + if (g_cancellable_set_error_if_cancelled (cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + disconnect_context_complete (ctx); return; + } /* If no simple iface, we're done */ if (!ctx->self->priv->simple_iface) { @@ -1120,14 +1130,13 @@ disconnect (NMModem *modem, 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 */ - cancellable, - (GAsyncReadyCallback)simple_disconnect_ready, - ctx); + _LOGD ("notifying ModemManager about the modem disconnection"); + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + mm_modem_simple_disconnect (ctx->self->priv->simple_iface, + NULL, /* bearer path; if NULL given ALL get disconnected */ + cancellable, + (GAsyncReadyCallback) simple_disconnect_ready, + ctx); } /*****************************************************************************/ @@ -1274,9 +1283,10 @@ get_sim_ready (MMModem *modem, if (self->priv->ctx && self->priv->ctx->step == CONNECT_STEP_WAIT_FOR_SIM) connect_context_step (self); } else { - nm_log_warn (LOGD_MB, "(%s): failed to retrieve SIM object: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _NMLOG (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND) + ? LOGL_INFO : LOGL_WARN, + "failed to retrieve SIM object: %s", + NM_G_ERROR_MSG (error)); } g_clear_error (&error); g_object_unref (self); diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index a54e63a6..6607f7f5 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -23,8 +23,6 @@ #include "nm-modem.h" -G_BEGIN_DECLS - #define NM_TYPE_MODEM_BROADBAND (nm_modem_broadband_get_type ()) #define NM_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadband)) #define NM_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) @@ -32,8 +30,6 @@ G_BEGIN_DECLS #define NM_IS_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_BROADBAND)) #define NM_MODEM_BROADBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) -#define NM_MODEM_BROADBAND_MODEM "modem" - typedef struct _NMModemBroadband NMModemBroadband; typedef struct _NMModemBroadbandClass NMModemBroadbandClass; typedef struct _NMModemBroadbandPrivate NMModemBroadbandPrivate; @@ -51,6 +47,4 @@ GType nm_modem_broadband_get_type (void); NMModem *nm_modem_broadband_new (GObject *object, GError **error); -G_END_DECLS - #endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */ diff --git a/src/devices/wwan/nm-modem-enum-types.c b/src/devices/wwan/nm-modem-enum-types.c index 2d02ede9..f999b084 100644 --- a/src/devices/wwan/nm-modem-enum-types.c +++ b/src/devices/wwan/nm-modem-enum-types.c @@ -6,6 +6,7 @@ #include "config.h" #include "nm-modem-enum-types.h" +#include "nm-default.h" #include "nm-modem.h" diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index e26321b0..964485fc 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -17,20 +17,30 @@ * * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. - * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 - 2013 Canonical Ltd. */ #include "nm-default.h" -#include <string.h> +#include "nm-modem-manager.h" +#include <string.h> #include <libmm-glib.h> -#include "nm-modem-manager.h" +#if HAVE_LIBSYSTEMD +#include <systemd/sd-daemon.h> +#else +#define sd_booted() FALSE +#endif + #include "nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" +#if WITH_OFONO +#include "nm-modem-ofono.h" +#endif + #define MODEM_POKE_INTERVAL 120 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) @@ -39,9 +49,13 @@ struct _NMModemManagerPrivate { GDBusConnection *dbus_connection; MMManager *modem_manager; guint mm_launch_id; - guint mm_name_owner_changed_id; - guint mm_object_added_id; - guint mm_object_removed_id; + gulong mm_name_owner_changed_id; + gulong mm_object_added_id; + gulong mm_object_removed_id; + +#if WITH_OFONO + GDBusProxy *ofono_proxy; +#endif /* Common */ GHashTable *modems; @@ -79,34 +93,14 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) } static void -modem_manager_clear_signals (NMModemManager *self) +clear_modem_manager (NMModemManager *self) { if (!self->priv->modem_manager) return; - - if (self->priv->mm_name_owner_changed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager, - self->priv->mm_name_owner_changed_id)) - g_signal_handler_disconnect (self->priv->modem_manager, - self->priv->mm_name_owner_changed_id); - self->priv->mm_name_owner_changed_id = 0; - } - - if (self->priv->mm_object_added_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager, - self->priv->mm_object_added_id)) - g_signal_handler_disconnect (self->priv->modem_manager, - self->priv->mm_object_added_id); - self->priv->mm_object_added_id = 0; - } - - if (self->priv->mm_object_removed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager, - self->priv->mm_object_removed_id)) - g_signal_handler_disconnect (self->priv->modem_manager, - self->priv->mm_object_removed_id); - self->priv->mm_object_removed_id = 0; - } + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_name_owner_changed_id); + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_object_added_id); + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_object_removed_id); + g_clear_object (&self->priv->modem_manager); } static void @@ -183,7 +177,7 @@ modem_manager_available (NMModemManager *self) static void schedule_modem_manager_relaunch (NMModemManager *self, guint n_seconds); -static void ensure_client (NMModemManager *self); +static void ensure_modem_manager (NMModemManager *self); static void modem_manager_name_owner_changed (MMManager *modem_manager, @@ -199,10 +193,9 @@ modem_manager_name_owner_changed (MMManager *modem_manager, if (!name_owner) { nm_log_info (LOGD_MB, "ModemManager disappeared from bus"); -#if !HAVE_SYSTEMD /* If not managed by systemd, schedule relaunch */ - schedule_modem_manager_relaunch (self, 0); -#endif + if (!sd_booted ()) + schedule_modem_manager_relaunch (self, 0); return; } @@ -214,16 +207,173 @@ modem_manager_name_owner_changed (MMManager *modem_manager, * nor 'object-removed' if it was created while there was no ModemManager in * the bus. This hack avoids this issue until we get a GIO with the fix * included... */ - modem_manager_clear_signals (self); - g_clear_object (&self->priv->modem_manager); - ensure_client (self); + clear_modem_manager (self); + ensure_modem_manager (self); /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: * modem_manager_available (self); */ } -#if !HAVE_SYSTEMD +#if WITH_OFONO +static void +ofono_create_modem (NMModemManager *self, const char *path) +{ + NMModem *modem = NULL; + + /* Ensure duplicate modems aren't created. Because we're not using the + * ObjectManager interface there's a race during oFono startup where we + * receive ModemAdded signals before GetModems() returns, so some of the + * modems returned from GetModems() may already have been created. + */ + if (!g_hash_table_lookup (self->priv->modems, path)) { + modem = nm_modem_ofono_new (path); + if (modem) + handle_new_modem (self, modem); + else + nm_log_warn (LOGD_MB, "Failed to create oFono modem for %s", path); + } +} + +static void +ofono_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMModemManager *self = NM_MODEM_MANAGER (user_data); + gchar *object_path; + NMModem *modem; + + if (g_strcmp0 (signal_name, "ModemAdded") == 0) { + g_variant_get (parameters, "(oa{sv})", &object_path, NULL); + nm_log_info (LOGD_MB, "oFono modem appeared: %s", object_path); + + ofono_create_modem (NM_MODEM_MANAGER (user_data), object_path); + g_free (object_path); + } else if (g_strcmp0 (signal_name, "ModemRemoved") == 0) { + g_variant_get (parameters, "(o)", &object_path); + nm_log_info (LOGD_MB, "oFono modem removed: %s", object_path); + + modem = (NMModem *) g_hash_table_lookup (self->priv->modems, object_path); + if (modem) { + nm_modem_emit_removed (modem); + g_hash_table_remove (self->priv->modems, object_path); + } else { + nm_log_warn (LOGD_MB, "could not remove modem %s, not found in table", + object_path); + } + g_free (object_path); + } +} + +static void +ofono_enumerate_devices_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) +{ + NMModemManager *manager = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + GVariant *results; + GVariantIter *iter; + const char *path; + + results = g_dbus_proxy_call_finish (proxy, res, &error); + if (results) { + g_variant_get (results, "(a(oa{sv}))", &iter); + while (g_variant_iter_loop (iter, "(&oa{sv})", &path, NULL)) + ofono_create_modem (manager, path); + g_variant_iter_free (iter); + g_variant_unref (results); + } + + if (error) { + nm_log_warn (LOGD_MB, "failed to enumerate oFono devices: %s", + error->message); + } +} + +static void +ofono_check_name_owner (NMModemManager *self) +{ + gs_free char *name_owner = NULL; + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (self->priv->ofono_proxy)); + if (name_owner) { + nm_log_info (LOGD_MB, "oFono is now available"); + + g_dbus_proxy_call (self->priv->ofono_proxy, + "GetModems", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) ofono_enumerate_devices_done, + g_object_ref (self)); + } else { + GHashTableIter iter; + NMModem *modem; + + nm_log_info (LOGD_MB, "oFono disappeared from bus"); + + /* Remove any oFono modems that might be left around */ + g_hash_table_iter_init (&iter, self->priv->modems); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &modem)) { + if (NM_IS_MODEM_OFONO (modem)) { + nm_modem_emit_removed (modem); + g_hash_table_iter_remove (&iter); + } + } + } +} + +static void +ofono_name_owner_changed (GDBusProxy *ofono_proxy, + GParamSpec *pspec, + NMModemManager *self) +{ + ofono_check_name_owner (self); +} + +static void +ofono_proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + gs_unref_object NMModemManager *self = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + + self->priv->ofono_proxy = g_dbus_proxy_new_finish (res, &error); + if (error) { + nm_log_warn (LOGD_MB, "error getting oFono bus proxy: %s", error->message); + return; + } + + g_signal_connect (self->priv->ofono_proxy, + "notify::g-name-owner", + G_CALLBACK (ofono_name_owner_changed), + self); + + g_signal_connect (self->priv->ofono_proxy, + "g-signal", + G_CALLBACK (ofono_signal_cb), + self); + + ofono_check_name_owner (self); +} + +static void +ensure_ofono_client (NMModemManager *self) +{ + g_assert (self->priv->dbus_connection); + g_dbus_proxy_new (self->priv->dbus_connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + OFONO_DBUS_PATH, + OFONO_DBUS_INTERFACE, + NULL, + (GAsyncReadyCallback) ofono_proxy_new_cb, + g_object_ref (self)); +} +#endif static void modem_manager_poke_cb (GDBusConnection *connection, @@ -235,19 +385,18 @@ modem_manager_poke_cb (GDBusConnection *connection, result = g_dbus_connection_call_finish (connection, res, &error); if (error) { - /* Ignore common errors when MM is not installed and such */ - if ( !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_EXEC_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FORK_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMEOUT) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { - nm_log_dbg (LOGD_MB, "error poking ModemManager: %s", error->message); + nm_log_warn (LOGD_MB, "error poking ModemManager: %s", + error ? error->message : ""); + + /* Don't reschedule poke is MM service doesn't exist. */ + if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) + && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { + + /* Setup timeout to relaunch */ + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } - g_error_free (error); - /* Setup timeout to relaunch */ - schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); + g_error_free (error); } else g_variant_unref (result); @@ -273,25 +422,21 @@ modem_manager_poke (NMModemManager *self) g_object_ref (self)); /* user_data */ } -#endif /* HAVE_SYSTEMD */ - static void modem_manager_check_name_owner (NMModemManager *self) { - gchar *name_owner; + gs_free gchar *name_owner = NULL; name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager)); if (name_owner) { /* Available! */ modem_manager_available (self); - g_free (name_owner); return; } -#if !HAVE_SYSTEMD /* If the lifecycle is not managed by systemd, poke */ - modem_manager_poke (self); -#endif + if (!sd_booted ()) + modem_manager_poke (self); } static void @@ -303,7 +448,8 @@ manager_new_ready (GObject *source, GError *error = NULL; - g_assert (!self->priv->modem_manager); + g_return_if_fail (!self->priv->modem_manager); + self->priv->modem_manager = mm_manager_new_finish (res, &error); if (!self->priv->modem_manager) { /* We're not really supposed to get any error here. If we do get one, @@ -316,20 +462,20 @@ manager_new_ready (GObject *source, } else { /* Setup signals in the GDBusObjectManagerClient */ self->priv->mm_name_owner_changed_id = - g_signal_connect (self->priv->modem_manager, - "notify::name-owner", - G_CALLBACK (modem_manager_name_owner_changed), - self); + g_signal_connect (self->priv->modem_manager, + "notify::name-owner", + G_CALLBACK (modem_manager_name_owner_changed), + self); self->priv->mm_object_added_id = - g_signal_connect (self->priv->modem_manager, - "object-added", - G_CALLBACK (modem_object_added), - self); + g_signal_connect (self->priv->modem_manager, + "object-added", + G_CALLBACK (modem_object_added), + self); self->priv->mm_object_removed_id = - g_signal_connect (self->priv->modem_manager, - "object-removed", - G_CALLBACK (modem_object_removed), - self); + g_signal_connect (self->priv->modem_manager, + "object-removed", + G_CALLBACK (modem_object_removed), + self); modem_manager_check_name_owner (self); } @@ -339,7 +485,7 @@ manager_new_ready (GObject *source, } static void -ensure_client (NMModemManager *self) +ensure_modem_manager (NMModemManager *self) { g_assert (self->priv->dbus_connection); @@ -359,46 +505,12 @@ ensure_client (NMModemManager *self) modem_manager_check_name_owner (self); } -static void -bus_get_ready (GObject *source, - GAsyncResult *res, - NMModemManager *self) -{ - /* Note we always get an extra reference to self here */ - - GError *error = NULL; - - self->priv->dbus_connection = g_bus_get_finish (res, &error); - if (!self->priv->dbus_connection) { - nm_log_warn (LOGD_CORE, "error getting bus connection: %s", error->message); - g_error_free (error); - /* Setup timeout to relaunch */ - schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); - } else { - /* Got the bus, ensure client */ - ensure_client (self); - } - - /* Balance refcount */ - g_object_unref (self); -} - static gboolean -ensure_bus (NMModemManager *self) +mm_launch_cb (NMModemManager *self) { - /* Clear launch ID */ self->priv->mm_launch_id = 0; - - if (!self->priv->dbus_connection) - g_bus_get (G_BUS_TYPE_SYSTEM, - NULL, - (GAsyncReadyCallback)bus_get_ready, - g_object_ref (self)); - else - /* If bus is already available, ensure client */ - ensure_client (self); - - return FALSE; + ensure_modem_manager (self); + return G_SOURCE_REMOVE; } static void @@ -407,11 +519,31 @@ schedule_modem_manager_relaunch (NMModemManager *self, { /* No need to pass an extra reference to self; timeout/idle will be * cancelled if the object gets disposed. */ - if (n_seconds) - self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)mm_launch_cb, self); else - self->priv->mm_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_idle_add ((GSourceFunc)mm_launch_cb, self); +} + +static void +bus_get_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_object NMModemManager *self = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + + self->priv->dbus_connection = g_bus_get_finish (res, &error); + if (!self->priv->dbus_connection) { + nm_log_warn (LOGD_MB, "error getting bus connection: %s", error->message); + return; + } + + /* Got the bus, ensure clients */ + ensure_modem_manager (self); +#if WITH_OFONO + ensure_ofono_client (self); +#endif } /************************************************************************/ @@ -423,7 +555,11 @@ nm_modem_manager_init (NMModemManager *self) self->priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - schedule_modem_manager_relaunch (self, 0); + // FIXME: this doesn't handle bus-daemon restart + g_bus_get (G_BUS_TYPE_SYSTEM, + NULL, + (GAsyncReadyCallback)bus_get_ready, + g_object_ref (self)); } static void @@ -433,8 +569,16 @@ dispose (GObject *object) nm_clear_g_source (&self->priv->mm_launch_id); - modem_manager_clear_signals (self); - g_clear_object (&self->priv->modem_manager); + clear_modem_manager (self); + +#if WITH_OFONO + if (self->priv->ofono_proxy) { + g_signal_handlers_disconnect_by_func (self->priv->ofono_proxy, ofono_name_owner_changed, self); + g_signal_handlers_disconnect_by_func (self->priv->ofono_proxy, ofono_signal_cb, self); + g_clear_object (&self->priv->ofono_proxy); + } +#endif + g_clear_object (&self->priv->dbus_connection); if (self->priv->modems) { diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c new file mode 100644 index 00000000..86492d3d --- /dev/null +++ b/src/devices/wwan/nm-modem-ofono.c @@ -0,0 +1,1202 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 - 2016 Canonical Ltd. + */ + +#include "nm-default.h" + +#include "nm-modem-ofono.h" + +#include <string.h> + +#include "nm-core-internal.h" +#include "nm-device-private.h" +#include "nm-modem.h" +#include "nm-platform.h" + +G_DEFINE_TYPE (NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM) + +#define NM_MODEM_OFONO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OFONO, NMModemOfonoPrivate)) + +#define VARIANT_IS_OF_TYPE_BOOLEAN(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_BOOLEAN) )) +#define VARIANT_IS_OF_TYPE_STRING(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING) )) +#define VARIANT_IS_OF_TYPE_OBJECT_PATH(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_OBJECT_PATH) )) +#define VARIANT_IS_OF_TYPE_STRING_ARRAY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING_ARRAY) )) +#define VARIANT_IS_OF_TYPE_DICTIONARY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_DICTIONARY) )) + +typedef struct { + GHashTable *connect_properties; + + GDBusProxy *modem_proxy; + GDBusProxy *connman_proxy; + GDBusProxy *context_proxy; + GDBusProxy *sim_proxy; + + GError *property_error; + + char *context_path; + char *imsi; + + gboolean modem_online; + gboolean gprs_attached; + + NMIP4Config *ip4_config; +} NMModemOfonoPrivate; + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_MB +#define _NMLOG_PREFIX_NAME "modem-ofono" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ + NMModemOfono *const __self = (self); \ + char __prefix_name[128]; \ + const char *__uid; \ + \ + _nm_log (_level, (_NMLOG_DOMAIN), 0, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self \ + ? ({ \ + ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ + ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + +static gboolean +ip_string_to_network_address (const gchar *str, + guint32 *out) +{ + guint32 addr = 0; + gboolean success = FALSE; + + if (!str || inet_pton (AF_INET, str, &addr) != 1) + addr = 0; + else + success = TRUE; + + *out = (guint32)addr; + return success; +} + +static void +get_capabilities (NMModem *_self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) +{ + /* FIXME: auto-detect capabilities to allow LTE */ + *modem_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; + *current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; +} + +static void +update_modem_state (NMModemOfono *self) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemState state = nm_modem_get_state (NM_MODEM (self)); + NMModemState new_state = NM_MODEM_STATE_DISABLED; + const char *reason = NULL; + + _LOGI ("'Attached': %s 'Online': %s 'IMSI': %s", + priv->gprs_attached ? "true" : "false", + priv->modem_online ? "true" : "false", + priv->imsi); + + if (priv->modem_online == FALSE) { + reason = "modem 'Online=false'"; + } else if (priv->imsi == NULL && state != NM_MODEM_STATE_ENABLING) { + reason = "modem not ready"; + } else if (priv->gprs_attached == FALSE) { + new_state = NM_MODEM_STATE_SEARCHING; + reason = "modem searching"; + } else { + new_state = NM_MODEM_STATE_REGISTERED; + reason = "modem ready"; + } + + if (state != new_state) + nm_modem_set_state (NM_MODEM (self), new_state, reason); +} + +/* Disconnect */ +typedef struct { + NMModemOfono *self; + GSimpleAsyncResult *result; + GCancellable *cancellable; + gboolean warn; +} DisconnectContext; + +static void +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 (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 *result, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); +} + +static void +disconnect_done (GDBusProxy *proxy, + GAsyncResult *result, + gpointer user_data) +{ + DisconnectContext *ctx = (DisconnectContext*) user_data; + NMModemOfono *self = ctx->self; + GError *error = NULL; + + g_dbus_proxy_call_finish (proxy, result, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD ("disconnect cancelled"); + return; + } + + if (error) { + if (ctx->warn) + _LOGW ("failed to disconnect modem: %s", error->message); + g_clear_error (&error); + } + + _LOGD ("modem disconnected"); + + update_modem_state (self); + disconnect_context_complete (ctx); +} + +static void +disconnect (NMModem *modem, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + DisconnectContext *ctx; + NMModemState state = nm_modem_get_state (NM_MODEM (self)); + + _LOGD ("warn: %s modem_state: %s", + warn ? "TRUE" : "FALSE", + nm_modem_state_to_string (state)); + + if (state != NM_MODEM_STATE_CONNECTED) + return; + + ctx = g_slice_new (DisconnectContext); + ctx->self = g_object_ref (self); + ctx->warn = warn; + + if (callback) { + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + disconnect); + } + /* Setup cancellable */ + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + if (disconnect_context_complete_if_cancelled (ctx)) + return; + + nm_modem_set_state (NM_MODEM (self), + NM_MODEM_STATE_DISCONNECTING, + nm_modem_state_to_string (NM_MODEM_STATE_DISCONNECTING)); + + g_dbus_proxy_call (priv->context_proxy, + "SetProperty", + g_variant_new ("(sv)", + "Active", + g_variant_new ("b", warn)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) disconnect_done, + ctx); +} + +static void +deactivate_cleanup (NMModem *_self, NMDevice *device) +{ + NMModemOfono *self = NM_MODEM_OFONO (_self); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + /* TODO: cancel SimpleConnect() if any */ + + g_clear_object (&priv->ip4_config); + + /* Chain up parent's */ + NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (_self, device); +} + + +static gboolean +check_connection_compatible (NMModem *modem, + NMConnection *connection) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMSettingConnection *s_con; + NMSettingGsm *s_gsm; + const char *uuid; + const char *id; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + uuid = nm_connection_get_uuid (connection); + id = nm_connection_get_id (connection); + + s_gsm = nm_connection_get_setting_gsm (connection); + if (!s_gsm) + return FALSE; + + if (!priv->imsi) { + _LOGW ("skipping %s/%s: no IMSI", uuid, id); + return FALSE; + } + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME)) { + _LOGD ("skipping %s/%s: not GSM", uuid, id); + return FALSE; + } + + if (!g_strrstr (id, "/context")) { + _LOGD ("skipping %s/%s: unexpected ID", uuid, id); + return FALSE; + } + + if (!g_strrstr (id, priv->imsi)) { + _LOGD ("skipping %s/%s: ID doesn't contain IMSI", uuid, id); + return FALSE; + } + + _LOGD ("%s/%s compatible with IMSI %s", uuid, id, priv->imsi); + return TRUE; +} + +static void +handle_sim_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (g_strcmp0 (property, "SubscriberIdentity") == 0 && VARIANT_IS_OF_TYPE_STRING (v)) { + gsize length; + const char *value_str = g_variant_get_string (v, &length); + + _LOGD ("SubscriberIdentify found"); + + /* Check for empty DBus string value */ + if (length && + g_strcmp0 (value_str, "(null)") != 0 && + g_strcmp0 (value_str, priv->imsi) != 0) { + + if (priv->imsi != NULL) { + _LOGW ("SimManager:'SubscriberIdentity' changed: %s", priv->imsi); + g_free(priv->imsi); + } + + priv->imsi = g_strdup (value_str); + update_modem_state (self); + } + } +} + +static void +sim_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_sim_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +sim_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting sim properties: %s", error->message); + g_error_free (error); + return; + } + + _LOGD ("sim v_properties is type: %s", g_variant_get_type_string (v_properties)); + + v_dict = g_variant_get_child_value (v_properties, 0); + if (!v_dict) { + _LOGW ("error getting sim properties: no v_dict"); + return; + } + + _LOGD ("sim v_dict is type: %s", g_variant_get_type_string (v_dict)); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_sim_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +static void +handle_sim_iface (NMModemOfono *self, gboolean found) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + _LOGD ("SimManager interface %sfound", found ? "" : "not "); + + if (!found && priv->sim_proxy) { + _LOGI ("SimManager interface disappeared"); + g_signal_handlers_disconnect_by_data (priv->sim_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->sim_proxy); + g_clear_pointer (&priv->imsi, g_free); + update_modem_state (self); + } else if (found && !priv->sim_proxy) { + GError *error = NULL; + + _LOGI ("found new SimManager interface"); + + priv->sim_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_SIM_MANAGER, + NULL, /* GCancellable */ + &error); + if (priv->sim_proxy == NULL) { + _LOGW ("failed to create SimManager proxy: %s", error->message); + g_error_free (error); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->sim_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (sim_property_changed), + self); + + g_dbus_proxy_call (priv->sim_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) sim_get_properties_done, + g_object_ref (self)); + } +} + +static void +handle_connman_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (g_strcmp0 (property, "Attached") == 0 && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { + gboolean attached = g_variant_get_boolean (v); + gboolean old_attached = priv->gprs_attached; + + _LOGD ("Attached: %s", attached ? "True" : "False"); + + if (priv->gprs_attached != attached) { + priv->gprs_attached = attached; + + _LOGI ("Attached %s -> %s", + old_attached ? "true" : "false", + attached ? "true" : "false"); + + update_modem_state (self); + } + } +} + +static void +connman_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_connman_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +connman_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting connman properties: %s", error->message); + g_error_free (error); + return; + } + + v_dict = g_variant_get_child_value (v_properties, 0); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_connman_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +static void +handle_connman_iface (NMModemOfono *self, gboolean found) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + _LOGD ("ConnectionManager interface %sfound", found ? "" : "not "); + + if (!found && priv->connman_proxy) { + _LOGI ("ConnectionManager interface disappeared"); + + g_signal_handlers_disconnect_by_data (priv->connman_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->connman_proxy); + + /* The connection manager proxy disappeared, we should + * consider the modem disabled. + */ + priv->gprs_attached = FALSE; + + update_modem_state (self); + } else if (found && !priv->connman_proxy) { + GError *error = NULL; + + _LOGI ("found new ConnectionManager interface"); + + priv->connman_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, + NULL, /* GCancellable */ + &error); + if (priv->connman_proxy == NULL) { + _LOGW ("failed to create ConnectionManager proxy: %s", error->message); + g_error_free (error); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->connman_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (connman_property_changed), + self); + + g_dbus_proxy_call (priv->connman_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) connman_get_properties_done, + g_object_ref (self)); + } +} + +static void +handle_modem_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if ((g_strcmp0 (property, "Online") == 0) && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { + gboolean online = g_variant_get_boolean (v); + + _LOGD ("Online: %s", online ? "True" : "False"); + + if (online != priv->modem_online) { + priv->modem_online = online; + _LOGI ("modem is now %s", online ? "Online" : "Offline"); + update_modem_state (self); + } + + } else if ((g_strcmp0 (property, "Interfaces") == 0) && VARIANT_IS_OF_TYPE_STRING_ARRAY (v)) { + const char **array, **iter; + gboolean found_connman = FALSE; + gboolean found_sim = FALSE; + + _LOGD ("Interfaces found"); + + array = g_variant_get_strv (v, NULL); + if (array) { + for (iter = array; *iter; iter++) { + if (g_strcmp0 (OFONO_DBUS_INTERFACE_SIM_MANAGER, *iter) == 0) + found_sim = TRUE; + else if (g_strcmp0 (OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, *iter) == 0) + found_connman = TRUE; + } + g_free (array); + } + + handle_sim_iface (self, found_sim); + handle_connman_iface (self, found_connman); + } +} + +static void +modem_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_modem_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +modem_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting modem properties: %s", error->message); + g_error_free (error); + return; + } + + v_dict = g_variant_get_child_value (v_properties, 0); + if (!v_dict) { + _LOGW ("error getting modem properties: no v_dict"); + return; + } + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_modem_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +NMModem * +nm_modem_ofono_new (const char *path) +{ + gs_free char *basename = NULL; + + g_return_val_if_fail (path != NULL, NULL); + + nm_log_info (LOGD_MB, "ofono: creating new Ofono modem path %s", path); + + /* Use short modem name (not its object path) as the NM device name (which + * comes from NM_MODEM_UID)and the device ID. + */ + basename = g_path_get_basename (path); + + return (NMModem *) g_object_new (NM_TYPE_MODEM_OFONO, + NM_MODEM_PATH, path, + NM_MODEM_UID, basename, + NM_MODEM_DEVICE_ID, basename, + NM_MODEM_CONTROL_PORT, "ofono", /* mandatory */ + NM_MODEM_DRIVER, "ofono", + NM_MODEM_STATE, NM_MODEM_STATE_INITIALIZING, + NULL); +} + +static void +stage1_prepare_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + g_clear_pointer (&priv->connect_properties, g_hash_table_destroy); + + g_dbus_proxy_call_finish (proxy, result, &error); + if (error) { + _LOGW ("connection failed: %s", error->message); + + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_BUSY); + /* + * FIXME: add code to check for InProgress so that the + * connection doesn't continue to try and activate, + * leading to the connection being disabled, and a 5m + * timeout... + */ + + g_clear_error (&error); + } +} + +static void +context_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMPlatformIP4Address addr; + gboolean ret = FALSE; + GVariant *v_dict; + const gchar *s, *addr_s; + const gchar **array, **iter; + guint32 address_network, gateway_network; + guint prefix = 0; + + _LOGD ("PropertyChanged: %s", property); + + /* + * TODO: might be a good idea and re-factor this to mimic bluez-device, + * ie. have this function just check the key, and call a sub-func to + * handle the action. + */ + + if (g_strcmp0 (property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value (v, 0); + if (!v_dict) { + _LOGW ("error getting IPv4 Settings: no v_dict"); + goto out; + } + + _LOGI ("IPv4 static Settings:"); + + if (g_variant_lookup (v_dict, "Interface", "&s", &s)) { + if (s && strlen (s)) { + _LOGD ("Interface: %s", s); + g_object_set (self, + NM_MODEM_DATA_PORT, g_strdup (s), + NM_MODEM_IP4_METHOD, NM_MODEM_IP_METHOD_STATIC, + NULL); + } else { + _LOGW ("Settings 'Interface'; empty"); + goto out; + } + + } else { + _LOGW ("Settings 'Interface' missing"); + goto out; + } + + /* TODO: verify handling of ip4_config; check other places it's used... */ + g_clear_object (&priv->ip4_config); + + memset (&addr, 0, sizeof (addr)); + + /* + * TODO: + * + * NM 1.2 changed the NMIP4Config constructor to take an ifindex + * ( vs. void pre 1.2 ), to tie config instance to a specific + * platform interface. + * + * This doesn't work for ofono, as the devices are created + * dynamically ( eg. ril_0, ril_1 ) in NMModemManager. The + * device created doesn't really map directly to a platform + * link. The closest would be one of the devices owned by + * rild ( eg. ccmin0 ), which is passed to us above as + * 'Interface'. + * + * This needs discussion with upstream. + */ + priv->ip4_config = nm_ip4_config_new (0); + + /* TODO: simply if/else error logic! */ + + if (g_variant_lookup (v_dict, "Address", "&s", &addr_s)) { + _LOGD ("Address: %s", addr_s); + + if (ip_string_to_network_address (addr_s, &address_network)) { + addr.address = address_network; + addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN; + } else { + _LOGW ("can't convert 'Address' %s to addr", s); + goto out; + } + + } else { + _LOGW ("Settings 'Address' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "Netmask", "&s", &s)) { + _LOGD ("Netmask: %s", s); + + if (s && ip_string_to_network_address (s, &address_network)) { + prefix = nm_utils_ip4_netmask_to_prefix (address_network); + if (prefix > 0) + addr.plen = prefix; + } else { + _LOGW ("invalid 'Netmask': %s", s); + goto out; + } + } else { + _LOGW ("Settings 'Netmask' missing"); + goto out; + } + + _LOGI ("Address: %s/%d", addr_s, prefix); + + nm_ip4_config_add_address (priv->ip4_config, &addr); + + if (g_variant_lookup (v_dict, "Gateway", "&s", &s)) { + if (s && ip_string_to_network_address (s, &gateway_network)) { + _LOGI ("Gateway: %s", s); + nm_ip4_config_set_gateway (priv->ip4_config, gateway_network); + } else { + _LOGW ("invalid 'Gateway': %s", s); + goto out; + } + nm_ip4_config_set_gateway (priv->ip4_config, gateway_network); + } else { + _LOGW ("Settings 'Gateway' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "DomainNameServers", "^a&s", &array)) { + if (array) { + for (iter = array; *iter; iter++) { + if (ip_string_to_network_address (*iter, &address_network) && address_network > 0) { + _LOGI ("DNS: %s", *iter); + nm_ip4_config_add_nameserver (priv->ip4_config, address_network); + } else { + _LOGW ("invalid NameServer: %s", *iter); + } + } + + if (iter == array) { + _LOGW ("Settings: 'DomainNameServers': none specified"); + g_free (array); + goto out; + } + g_free (array); + } + } else { + _LOGW ("Settings 'DomainNameServers' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "MessageProxy", "&s", &s)) { + _LOGI ("MessageProxy: %s", s); + if (s && ip_string_to_network_address (s, &address_network)) { + NMPlatformIP4Route mms_route; + + mms_route.network = address_network; + mms_route.plen = 32; + mms_route.gateway = gateway_network; + + mms_route.metric = 1; + + nm_ip4_config_add_route (priv->ip4_config, &mms_route); + } else { + _LOGW ("invalid MessageProxy: %s", s); + } + } + + ret = TRUE; + +out: + if (nm_modem_get_state (NM_MODEM (self)) != NM_MODEM_STATE_CONNECTED) { + _LOGI ("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE"); + if (!ret) + reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, ret, reason); + } else { + _LOGW ("MODEM_PPP_FAILED"); + g_signal_emit_by_name (self, NM_MODEM_PPP_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); + } +} + +static NMActStageReturn +static_stage3_ip4_config_start (NMModem *_self, + NMActRequest *req, + NMDeviceStateReason *reason) +{ + NMModemOfono *self = NM_MODEM_OFONO (_self); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + GError *error = NULL; + + if (priv->ip4_config) { + _LOGD ("IP4 config is done; setting modem_state -> CONNECTED"); + g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error); + + /* Signal listener takes ownership of the IP4Config */ + priv->ip4_config = NULL; + + nm_modem_set_state (NM_MODEM (self), + NM_MODEM_STATE_CONNECTED, + nm_modem_state_to_string (NM_MODEM_STATE_CONNECTED)); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } + + return ret; +} + +static void +context_proxy_new_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + priv->context_proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (error) { + _LOGE ("failed to create ofono ConnectionContext DBus proxy: %s", error->message); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_BUSY); + return; + } + + if (!priv->gprs_attached) { + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return; + } + + /* We have an old copy of the settings from a previous activation, + * clear it so that we can gate getting the IP config from oFono + * on whether or not we have already received them + */ + g_clear_object (&priv->ip4_config); + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (context_property_changed), + self); + + g_dbus_proxy_call (priv->context_proxy, + "SetProperty", + g_variant_new ("(sv)", + "Active", + g_variant_new ("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) stage1_prepare_done, + g_object_ref (self)); +} + +static void +do_context_activate (NMModemOfono *self) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_MODEM_OFONO (self)); + + g_clear_object (&priv->context_proxy); + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + priv->context_path, + OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT, + NULL, + (GAsyncReadyCallback) context_proxy_new_cb, + g_object_ref (self)); +} + +static GHashTable * +create_connect_properties (NMConnection *connection) +{ + NMSettingGsm *setting; + GHashTable *properties; + const char *str; + + setting = nm_connection_get_setting_gsm (connection); + properties = g_hash_table_new (g_str_hash, g_str_equal); + + str = nm_setting_gsm_get_apn (setting); + if (str) + g_hash_table_insert (properties, "AccessPointName", g_strdup (str)); + + str = nm_setting_gsm_get_username (setting); + if (str) + g_hash_table_insert (properties, "Username", g_strdup (str)); + + str = nm_setting_gsm_get_password (setting); + if (str) + g_hash_table_insert (properties, "Password", g_strdup (str)); + + return properties; +} + +static NMActStageReturn +act_stage1_prepare (NMModem *modem, + NMConnection *connection, + NMDeviceStateReason *reason) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + const char *context_id; + char **id = NULL; + + context_id = nm_connection_get_id (connection); + id = g_strsplit (context_id, "/", 0); + g_assert (id[2]); + + _LOGD ("trying %s %s", id[1], id[2]); + + g_free (priv->context_path); + priv->context_path = g_strdup_printf ("%s/%s", + nm_modem_get_path (modem), + id[2]); + g_strfreev (id); + + if (!priv->context_path) { + *reason = NM_DEVICE_STATE_REASON_GSM_APN_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (priv->connect_properties) + g_hash_table_destroy (priv->connect_properties); + + priv->connect_properties = create_connect_properties (connection); + + _LOGI ("activating context %s", priv->context_path); + + if (nm_modem_get_state (modem) == NM_MODEM_STATE_REGISTERED) { + do_context_activate (self); + } else { + _LOGW ("could not activate context: modem is not registered."); + *reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +static void +modem_proxy_new_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + priv->modem_proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (error) { + _LOGE ("failed to create ofono modem DBus proxy: %s", error->message); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->modem_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (modem_property_changed), + self); + + g_dbus_proxy_call (priv->modem_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) modem_get_properties_done, + g_object_ref (self)); +} + +static void +nm_modem_ofono_init (NMModemOfono *self) +{ +} + +static void +constructed (GObject *object) +{ + NMModemOfono *self = NM_MODEM_OFONO (object); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_MODEM, + NULL, + (GAsyncReadyCallback) modem_proxy_new_cb, + g_object_ref (self)); +} + +static void +dispose (GObject *object) +{ + NMModemOfono *self = NM_MODEM_OFONO (object); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (priv->connect_properties) { + g_hash_table_destroy (priv->connect_properties); + priv->connect_properties = NULL; + } + + g_clear_object (&priv->ip4_config); + + if (priv->modem_proxy) { + g_signal_handlers_disconnect_by_data (priv->modem_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->modem_proxy); + } + + g_clear_object (&priv->connman_proxy); + g_clear_object (&priv->context_proxy); + + if (priv->sim_proxy) { + g_signal_handlers_disconnect_by_data (priv->sim_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->sim_proxy); + } + + g_free (priv->imsi); + priv->imsi = NULL; + + G_OBJECT_CLASS (nm_modem_ofono_parent_class)->dispose (object); +} + +static void +nm_modem_ofono_class_init (NMModemOfonoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMModemClass *modem_class = NM_MODEM_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMModemOfonoPrivate)); + + /* Virtual methods */ + object_class->constructed = constructed; + object_class->dispose = dispose; + + modem_class->get_capabilities = get_capabilities; + modem_class->disconnect = disconnect; + modem_class->disconnect_finish = disconnect_finish; + modem_class->deactivate_cleanup = deactivate_cleanup; + modem_class->check_connection_compatible = check_connection_compatible; + + /* same as nm-modem-broadband */ + modem_class->act_stage1_prepare = act_stage1_prepare; + + /* same as nm-modem-broadband */ + modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; +} diff --git a/src/devices/wwan/nm-modem-ofono.h b/src/devices/wwan/nm-modem-ofono.h new file mode 100644 index 00000000..5965526d --- /dev/null +++ b/src/devices/wwan/nm-modem-ofono.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 - Canonical Ltd. + */ + +#ifndef NM_MODEM_OFONO_H +#define NM_MODEM_OFONO_H + +#include "nm-modem.h" + +#define NM_TYPE_MODEM_OFONO (nm_modem_ofono_get_type ()) +#define NM_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OFONO, NMModemOfono)) +#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) +#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) + +#define OFONO_DBUS_SERVICE "org.ofono" +#define OFONO_DBUS_PATH "/" +#define OFONO_DBUS_INTERFACE "org.ofono.Manager" +#define OFONO_DBUS_INTERFACE_MODEM "org.ofono.Modem" +#define OFONO_DBUS_INTERFACE_CONNECTION_MANAGER "org.ofono.ConnectionManager" +#define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" +#define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" + +typedef struct { + NMModem parent; +} NMModemOfono; + +typedef struct { + NMModemClass parent; +} NMModemOfonoClass; + +GType nm_modem_ofono_get_type (void); + +NMModem *nm_modem_ofono_new (const char *path); + +#endif /* NM_MODEM_OFONO_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index a6c77007..2e3d63bb 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -202,7 +202,9 @@ nm_modem_set_mm_enabled (NMModem *self, return; } - NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); + /* Not all modem classes support set_mm_enabled */ + if (NM_MODEM_GET_CLASS (self)->set_mm_enabled) + NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); /* Pre-empt the state change signal */ nm_modem_set_state (self, @@ -573,6 +575,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, const char *method; NMActStageReturn ret; + nm_log_dbg (LOGD_MB, "ip4_config_start"); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_DEVICE (device), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_DEVICE_CLASS (device_class), NM_ACT_STAGE_RETURN_FAILURE); @@ -602,9 +606,11 @@ nm_modem_stage3_ip4_config_start (NMModem *self, ret = ppp_stage3_ip_config_start (self, req, reason); break; case NM_MODEM_IP_METHOD_STATIC: + nm_log_dbg (LOGD_MB, "MODEM_IP_METHOD_STATIC"); ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; case NM_MODEM_IP_METHOD_AUTO: + nm_log_dbg (LOGD_MB, "MODEM_IP_METHOD_AUTO"); ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index 60e5589b..8f797d44 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -22,12 +22,9 @@ #ifndef __NETWORKMANAGER_MODEM_H__ #define __NETWORKMANAGER_MODEM_H__ -#include "nm-default.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_MODEM (nm_modem_get_type ()) #define NM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM, NMModem)) #define NM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM, NMModemClass)) @@ -268,6 +265,4 @@ void nm_modem_emit_ip6_config_result (NMModem *self, const gchar *nm_modem_ip_type_to_string (NMModemIPType ip_type); -G_END_DECLS - #endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index 805aea69..507935fc 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -90,7 +90,7 @@ modem_added_cb (NMModemManager *manager, NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WWAN_ETHERNET) + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WWAN_NET) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME) ) @@ -102,7 +102,7 @@ create_device (NMDeviceFactory *factory, gboolean *out_ignore) { g_return_val_if_fail (plink, NULL); - g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_ETHERNET, NULL); + g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_NET, NULL); *out_ignore = TRUE; return NULL; } diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h index 78031e60..61bdcb1e 100644 --- a/src/devices/wwan/nm-wwan-factory.h +++ b/src/devices/wwan/nm-wwan-factory.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_WWAN_FACTORY_H__ #define __NETWORKMANAGER_WWAN_FACTORY_H__ -#include "nm-default.h" - #define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type ()) #define NM_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory)) diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in index 063489cb..dcb45183 100644 --- a/src/dhcp-manager/Makefile.in +++ b/src/dhcp-manager/Makefile.in @@ -91,8 +91,9 @@ host_triplet = @host@ libexec_PROGRAMS = nm-dhcp-helper$(EXEEXT) subdir = src/dhcp-manager ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -218,6 +219,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -274,13 +276,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -292,6 +295,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -352,6 +357,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -387,6 +394,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/dhcp-manager/nm-dhcp-client-logging.h b/src/dhcp-manager/nm-dhcp-client-logging.h index bb4f2f4a..8dd18bf2 100644 --- a/src/dhcp-manager/nm-dhcp-client-logging.h +++ b/src/dhcp-manager/nm-dhcp-client-logging.h @@ -21,7 +21,6 @@ #ifndef __NETWORKMANAGER_DHCP_CLIENT_LOGGING_H__ #define __NETWORKMANAGER_DHCP_CLIENT_LOGGING_H__ -#include "nm-default.h" #include "nm-dhcp-client.h" #define _NMLOG_PREFIX_NAME "dhcp" @@ -52,4 +51,27 @@ } \ } G_STMT_END +#define _NMLOG2(level, domain, ifname, ...) \ + G_STMT_START { \ + const NMLogLevel _level = (level); \ + const NMLogDomain _domain = (domain); \ + \ + /* we check first for LOGD_DHCP instead of the correct domain. + * In the worst case, we guess wrong and enter the block. + * + * Same for the _NMLOG_ENABLED() macro. Probably it would be more + * expensive to determine the correct value then what we could + * safe. */ \ + if (nm_logging_enabled (_level, _domain)) { \ + const char *__ifname = (ifname); \ + \ + nm_log (_level, _domain, \ + "%s%s%s%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (_domain == LOGD_DHCP4 ? "4" : (_domain == LOGD_DHCP6 ? "6" : "")), \ + NM_PRINT_FMT_QUOTED (__ifname, " (", __ifname, ")", "") \ + _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + } \ + } G_STMT_END + #endif /* __NETWORKMANAGER_DHCP_CLIENT_LOGGING_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index c1025817..3be2ea03 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -448,6 +448,7 @@ generate_duid_from_machine_id (void) GRand *generator; guint i; gs_free char *machine_id_s = NULL; + gs_free char *str = NULL; machine_id_s = nm_utils_machine_id_read (); if (nm_utils_machine_id_parse (machine_id_s, uuid)) { @@ -457,7 +458,7 @@ generate_duid_from_machine_id (void) g_checksum_get_digest (sum, buffer, &sumlen); g_checksum_free (sum); } else { - nm_log_warn (LOGD_DHCP6, "dhcp6: failed to read " SYSCONFDIR "/machine-id " + nm_log_warn (LOGD_DHCP, "dhcp: failed to read " SYSCONFDIR "/machine-id " "or " LOCALSTATEDIR "/lib/dbus/machine-id to generate " "DHCPv6 DUID; creating non-persistent random DUID."); @@ -481,6 +482,8 @@ generate_duid_from_machine_id (void) */ g_byte_array_append (duid, buffer, 16); + nm_log_dbg (LOGD_DHCP, "dhcp: generated DUID %s", + (str = nm_dhcp_utils_duid_to_string (duid))); return duid; } @@ -489,17 +492,10 @@ get_duid (NMDhcpClient *self) { static GByteArray *duid = NULL; GByteArray *copy = NULL; - char *str; if (G_UNLIKELY (duid == NULL)) { duid = generate_duid_from_machine_id (); g_assert (duid); - - if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP6)) { - str = nm_dhcp_utils_duid_to_string (duid); - _LOGD ("generated DUID %s", str); - g_free (str); - } } if (G_LIKELY (duid)) { @@ -519,7 +515,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, NMSettingIP6ConfigPrivacy privacy) { NMDhcpClientPrivate *priv; - char *str; + gs_free char *str = NULL; g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); @@ -534,11 +530,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, if (!priv->duid) priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self); - if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP6)) { - str = nm_dhcp_utils_duid_to_string (priv->duid); - _LOGD ("DUID is '%s'", str); - g_free (str); - } + _LOGD ("DUID is '%s'", (str = nm_dhcp_utils_duid_to_string (priv->duid))); g_clear_pointer (&priv->hostname, g_free); priv->hostname = g_strdup (hostname); @@ -559,51 +551,49 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) { - char *pid_contents = NULL, *proc_contents = NULL, *proc_path = NULL; - long int tmp; + guint64 start_time; + pid_t pid, ppid; + const char *exe; + char proc_path[NM_STRLEN ("/proc/%lu/cmdline") + 100]; + gs_free char *pid_contents = NULL, *proc_contents = NULL; /* Check for an existing instance and stop it */ if (!g_file_get_contents (pid_file, &pid_contents, NULL, NULL)) return; - errno = 0; - tmp = strtol (pid_contents, NULL, 10); - if ((errno == 0) && (tmp > 1)) { - guint64 start_time; - const char *exe; - pid_t ppid; - - /* Ensure the process is a DHCP client */ - start_time = nm_utils_get_start_time_for_pid (tmp, NULL, &ppid); - proc_path = g_strdup_printf ("/proc/%ld/cmdline", tmp); - if ( start_time - && g_file_get_contents (proc_path, &proc_contents, NULL, NULL)) { - exe = strrchr (proc_contents, '/'); - if (exe) - exe++; - else - exe = proc_contents; - - if (!strcmp (exe, binary_name)) { - if (ppid == getpid ()) { - /* the process is our own child. */ - nm_utils_kill_child_sync (tmp, SIGTERM, LOGD_DHCP, "dhcp-client", NULL, 1000 / 2, 1000 / 20); - } else { - nm_utils_kill_process_sync (tmp, start_time, SIGTERM, LOGD_DHCP, - "dhcp-client", 1000 / 2, 1000 / 20, 2000); - } - } - } + pid = _nm_utils_ascii_str_to_int64 (pid_contents, 10, 1, G_MAXINT64, 0); + if (pid <= 0) + goto out; + + start_time = nm_utils_get_start_time_for_pid (pid, NULL, &ppid); + if (start_time == 0) + goto out; + + nm_sprintf_buf (proc_path, "/proc/%lu/cmdline", (long unsigned) pid); + if (!g_file_get_contents (proc_path, &proc_contents, NULL, NULL)) + goto out; + + exe = strrchr (proc_contents, '/'); + if (exe) + exe++; + else + exe = proc_contents; + if (!nm_streq0 (exe, binary_name)) + goto out; + + if (ppid == getpid ()) { + /* the process is our own child. */ + nm_utils_kill_child_sync (pid, SIGTERM, LOGD_DHCP, "dhcp-client", NULL, 1000 / 2, 1000 / 20); + } else { + nm_utils_kill_process_sync (pid, start_time, SIGTERM, LOGD_DHCP, + "dhcp-client", 1000 / 2, 1000 / 20, 2000); } +out: if (remove (pid_file) == -1) { nm_log_dbg (LOGD_DHCP, "dhcp: could not remove pid file \"%s\": %d (%s)", pid_file, errno, g_strerror (errno)); } - - g_free (proc_path); - g_free (pid_contents); - g_free (proc_contents); } void @@ -631,7 +621,7 @@ nm_dhcp_client_stop (NMDhcpClient *self, gboolean release) /********************************************/ static char * -bytearray_variant_to_string (GVariant *value, const char *key) +bytearray_variant_to_string (NMDhcpClient *self, GVariant *value, const char *key) { const guint8 *array; gsize length; @@ -662,7 +652,7 @@ bytearray_variant_to_string (GVariant *value, const char *key) converted = str->str; if (!g_utf8_validate (converted, -1, NULL)) - nm_log_warn (LOGD_DHCP, "dhcp: option '%s' couldn't be converted to UTF-8", key); + _LOGW ("option '%s' couldn't be converted to UTF-8", key); g_string_free (str, FALSE); return converted; } @@ -671,7 +661,8 @@ bytearray_variant_to_string (GVariant *value, const char *key) #define NEW_TAG "new_" static void -maybe_add_option (GHashTable *hash, +maybe_add_option (NMDhcpClient *self, + GHashTable *hash, const char *key, GVariant *value) { @@ -701,7 +692,7 @@ maybe_add_option (GHashTable *hash, if (!key[0]) return; - str_value = bytearray_variant_to_string (value, key); + str_value = bytearray_variant_to_string (self, value, key); if (str_value) g_hash_table_insert (hash, g_strdup (key), str_value); } @@ -747,7 +738,7 @@ nm_dhcp_client_handle_event (gpointer unused, str_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); g_variant_iter_init (&iter, options); while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) { - maybe_add_option (str_options, name, value); + maybe_add_option (self, str_options, name, value); g_variant_unref (value); } @@ -836,7 +827,7 @@ set_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_IFACE: /* construct-only */ - priv->iface = g_strdup (g_value_get_string (value)); + priv->iface = g_value_dup_string (value); break; case PROP_IFINDEX: /* construct-only */ diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 1c78c5b1..5779d4ed 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -24,8 +24,6 @@ #include <nm-ip4-config.h> #include <nm-ip6-config.h> -#include "nm-default.h" - #define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ()) #define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClient)) #define NM_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index 008f8af2..8d4c54ae 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -720,7 +720,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, address.timestamp = now_monotonic_ts; address.lifetime = address.preferred = expiry; - address.source = NM_IP_CONFIG_SOURCE_DHCP; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; ip4 = nm_ip4_config_new (ifindex); nm_ip4_config_add_address (ip4, &address); diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.h b/src/dhcp-manager/nm-dhcp-dhclient-utils.h index 0e255027..83d5a23d 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.h +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.h @@ -22,8 +22,6 @@ #include <nm-setting-ip4-config.h> #include <nm-setting-ip6-config.h> -#include "nm-default.h" - char *nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, GBytes *client_id, diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index b35921ec..bd020624 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -18,7 +18,8 @@ * Copyright (C) 2005 - 2012 Red Hat, Inc. */ -#include "config.h" +#include <config.h> +#define __CONFIG_H__ #define _XOPEN_SOURCE #include <time.h> @@ -178,6 +179,9 @@ merge_dhclient_config (NMDhcpDhclient *self, } } + if (is_ip6 && hostname && !strchr (hostname, '.')) + _LOGW ("hostname is not a FQDN, it will be ignored"); + new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, fqdn, orig_path, orig, out_new_client_id); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); diff --git a/src/dhcp-manager/nm-dhcp-dhclient.h b/src/dhcp-manager/nm-dhcp-dhclient.h index 3e8d9c5d..7f0c855a 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.h +++ b/src/dhcp-manager/nm-dhcp-dhclient.h @@ -19,7 +19,6 @@ #ifndef __NETWORKMANAGER_DHCP_DHCLIENT_H__ #define __NETWORKMANAGER_DHCP_DHCLIENT_H__ -#include "nm-default.h" #include "nm-dhcp-client.h" #define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type ()) diff --git a/src/dhcp-manager/nm-dhcp-listener.c b/src/dhcp-manager/nm-dhcp-listener.c index 595b2097..eadff3ec 100644 --- a/src/dhcp-manager/nm-dhcp-listener.c +++ b/src/dhcp-manager/nm-dhcp-listener.c @@ -111,20 +111,20 @@ handle_event (GDBusConnection *connection, iface = get_option (options, "interface"); if (iface == NULL) { - nm_log_warn (LOGD_DHCP, "DHCP event: didn't have associated interface."); + nm_log_warn (LOGD_DHCP, "dhcp-event: didn't have associated interface."); goto out; } pid_str = get_option (options, "pid"); pid = _nm_utils_ascii_str_to_int64 (pid_str, 10, 0, G_MAXINT32, -1); if (pid == -1) { - nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); + nm_log_warn (LOGD_DHCP, "dhcp-event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); goto out; } reason = get_option (options, "reason"); if (reason == NULL) { - nm_log_warn (LOGD_DHCP, "(pid %d) DHCP event didn't have a reason", pid); + nm_log_warn (LOGD_DHCP, "dhcp-event: (pid %d) DHCP event didn't have a reason", pid); goto out; } @@ -132,9 +132,9 @@ handle_event (GDBusConnection *connection, if (!handled) { if (g_ascii_strcasecmp (reason, "RELEASE") == 0) { /* Ignore event when the dhcp client gets killed and we receive its last message */ - nm_log_dbg (LOGD_DHCP, "(pid %d) unhandled RELEASE DHCP event for interface %s", pid, iface); + nm_log_dbg (LOGD_DHCP, "dhcp-event: (pid %d) unhandled RELEASE DHCP event for interface %s", pid, iface); } else - nm_log_warn (LOGD_DHCP, "(pid %d) unhandled DHCP event for interface %s", pid, iface); + nm_log_warn (LOGD_DHCP, "dhcp-event: (pid %d) unhandled DHCP event for interface %s", pid, iface); } out: diff --git a/src/dhcp-manager/nm-dhcp-listener.h b/src/dhcp-manager/nm-dhcp-listener.h index b2631acc..ff31fe34 100644 --- a/src/dhcp-manager/nm-dhcp-listener.h +++ b/src/dhcp-manager/nm-dhcp-listener.h @@ -19,8 +19,6 @@ #ifndef __NETWORKMANAGER_DHCP_LISTENER_H__ #define __NETWORKMANAGER_DHCP_LISTENER_H__ -#include "nm-default.h" - #define NM_TYPE_DHCP_LISTENER (nm_dhcp_listener_get_type ()) #define NM_DHCP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_LISTENER, NMDhcpListener)) #define NM_IS_DHCP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_LISTENER)) diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index fe723e96..50469c5c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -372,7 +372,7 @@ nm_dhcp_manager_init (NMDhcpManager *self) for (iter = client_descs; iter; iter = iter->next) { ClientDesc *desc = iter->data; - nm_log_dbg (LOGD_DHCP, "Registered DHCP client '%s' (%s)", + nm_log_dbg (LOGD_DHCP, "dhcp-init: Registered DHCP client '%s' (%s)", desc->name, g_type_name (desc->gtype)); } @@ -380,7 +380,7 @@ nm_dhcp_manager_init (NMDhcpManager *self) client = nm_config_get_dhcp_client (config); if (nm_config_get_configure_and_quit (config)) { if (g_strcmp0 (client, "internal") != 0) - nm_log_warn (LOGD_DHCP, "Using internal DHCP client since configure-and-quit is set."); + nm_log_warn (LOGD_DHCP, "dhcp-init: Using internal DHCP client since configure-and-quit is set."); client = "internal"; } @@ -389,7 +389,7 @@ nm_dhcp_manager_init (NMDhcpManager *self) if (type == G_TYPE_INVALID) { if (client) - nm_log_warn (LOGD_DHCP, "DHCP client '%s' not available", client); + nm_log_warn (LOGD_DHCP, "dhcp-init: DHCP client '%s' not available", client); type = is_client_enabled ("dhclient"); if (type == G_TYPE_INVALID) @@ -399,9 +399,9 @@ nm_dhcp_manager_init (NMDhcpManager *self) } if (type == G_TYPE_INVALID) - nm_log_warn (LOGD_DHCP, "No usable DHCP client found! DHCP configurations will fail"); + nm_log_warn (LOGD_DHCP, "dhcp-init: No usable DHCP client found! DHCP configurations will fail"); else - nm_log_info (LOGD_DHCP, "Using DHCP client '%s'", find_client_desc (NULL, type)->name); + nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", find_client_desc (NULL, type)->name); priv->client_type = type; priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index 42d968ab..df92c91c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -22,8 +22,6 @@ #ifndef __NETWORKMANAGER_DHCP_MANAGER_H__ #define __NETWORKMANAGER_DHCP_MANAGER_H__ - -#include "nm-default.h" #include "nm-dhcp-client.h" #include "nm-ip4-config.h" #include "nm-dhcp4-config.h" diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c index 82cb3350..ac8eb60a 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -34,13 +34,11 @@ #include "NetworkManagerUtils.h" #include "nm-platform.h" #include "nm-dhcp-client-logging.h" +#include "nm-sd.h" #include "sd-dhcp-client.h" #include "sd-dhcp6-client.h" -#include "nm-sd-adapt.h" -#include "dhcp-lease-internal.h" - G_DEFINE_TYPE (NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT) #define NM_DHCP_SYSTEMD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdPrivate)) @@ -193,7 +191,7 @@ add_requests_to_options (GHashTable *options, const ReqOption *requests) #define LOG_LEASE(domain, ...) \ G_STMT_START { \ if (log_lease) { \ - nm_log (LOGL_INFO, (domain), __VA_ARGS__); \ + _LOG2I ((domain), (iface), __VA_ARGS__); \ } \ } G_STMT_END @@ -256,7 +254,7 @@ lease_to_ip4_config (const char *iface, SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, end_time); - address.source = NM_IP_CONFIG_SOURCE_DHCP; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; nm_ip4_config_add_address (ip4_config, &address); /* DNS Servers */ @@ -323,7 +321,7 @@ lease_to_ip4_config (const char *iface, route.gateway = a.s_addr; if (route.plen) { - route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = default_priority; nm_ip4_config_add_route (ip4_config, &route); @@ -578,6 +576,8 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last return FALSE; } + _LOGT ("dhcp-client4: set %p", priv->client4); + r = sd_dhcp_client_attach_event (priv->client4, NULL, 0); if (r < 0) { _LOGW ("failed to attach event (%d)", r); @@ -602,9 +602,9 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last } } - r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client)); + r = sd_dhcp_client_set_ifindex (priv->client4, nm_dhcp_client_get_ifindex (client)); if (r < 0) { - _LOGW ("failed to set ifindex (%d)", r); + _LOGW ("failed to set ififindex (%d)", r); goto error; } @@ -741,7 +741,7 @@ lease_to_ip6_config (const char *iface, .timestamp = ts, .lifetime = lft_valid, .preferred = lft_pref, - .source = NM_IP_CONFIG_SOURCE_DHCP, + .addr_source = NM_IP_CONFIG_SOURCE_DHCP, }; nm_ip6_config_add_address (ip6_config, &address); @@ -895,6 +895,8 @@ ip6_start (NMDhcpClient *client, return FALSE; } + _LOGT ("dhcp-client6: set %p", priv->client4); + if (info_only) sd_dhcp6_client_set_information_request (priv->client6, 1); @@ -928,7 +930,7 @@ ip6_start (NMDhcpClient *client, } } - r = sd_dhcp6_client_set_index (priv->client6, nm_dhcp_client_get_ifindex (client)); + r = sd_dhcp6_client_set_ifindex (priv->client6, nm_dhcp_client_get_ifindex (client)); if (r < 0) { _LOGW ("failed to set ifindex (%d)", r); goto error; @@ -958,6 +960,8 @@ ip6_start (NMDhcpClient *client, goto error; } + nm_dhcp_client_start_timeout (client); + return TRUE; error: @@ -973,6 +977,10 @@ stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); int r = 0; + _LOGT ("dhcp-client%d: stop %p", + priv->client4 ? '4' : '6', + priv->client4 ? (gpointer) priv->client4 : (gpointer) priv->client6); + if (priv->client4) { sd_dhcp_client_set_callback (priv->client4, NULL, NULL); r = sd_dhcp_client_stop (priv->client4); diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index a88a7e6d..593d8c5d 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -28,11 +28,14 @@ #include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-platform.h" +#include "nm-dhcp-client-logging.h" +#include "nm-core-internal.h" /********************************************/ static gboolean -ip4_process_dhcpcd_rfc3442_routes (const char *str, +ip4_process_dhcpcd_rfc3442_routes (const char *iface, + const char *str, guint32 priority, NMIP4Config *ip4_config, guint32 *gwaddr) @@ -45,7 +48,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, goto out; if ((g_strv_length (routes) % 2) != 0) { - nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid"); + _LOG2W (LOGD_DHCP4, iface, " classless static routes provided, but invalid"); goto out; } @@ -61,16 +64,16 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, errno = 0; rt_cidr = strtol (slash + 1, NULL, 10); if (errno || rt_cidr > 32) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1); + _LOG2W (LOGD_DHCP4, iface, "DHCP provided invalid classless static route cidr: '%s'", slash + 1); continue; } } if (inet_pton (AF_INET, *r, &rt_addr) <= 0) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r); + _LOG2W (LOGD_DHCP4, iface, "DHCP provided invalid classless static route address: '%s'", *r); continue; } if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1)); + _LOG2W (LOGD_DHCP4, iface, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1)); continue; } @@ -79,12 +82,12 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, /* FIXME: how to handle multiple routers? */ *gwaddr = rt_route; } else { - nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1)); + _LOG2I (LOGD_DHCP4, iface, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1)); memset (&route, 0, sizeof (route)); route.network = rt_addr; route.plen = rt_cidr; route.gateway = rt_route; - route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; nm_ip4_config_add_route (ip4_config, &route); } @@ -160,7 +163,8 @@ error: } static gboolean -ip4_process_dhclient_rfc3442_routes (const char *str, +ip4_process_dhclient_rfc3442_routes (const char *iface, + const char *str, guint32 priority, NMIP4Config *ip4_config, guint32 *gwaddr) @@ -172,7 +176,7 @@ ip4_process_dhclient_rfc3442_routes (const char *str, o = octets = g_strsplit_set (str, " .", 0); if (g_strv_length (octets) < 5) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str); goto out; } @@ -180,7 +184,7 @@ ip4_process_dhclient_rfc3442_routes (const char *str, memset (&route, 0, sizeof (route)); o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success); if (!success) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes"); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes"); break; } @@ -192,13 +196,13 @@ ip4_process_dhclient_rfc3442_routes (const char *str, char addr[INET_ADDRSTRLEN]; /* normal route */ - route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; nm_ip4_config_add_route (ip4_config, &route); - nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", - nm_utils_inet4_ntop (route.network, addr), route.plen, - nm_utils_inet4_ntop (route.gateway, NULL)); + _LOG2I (LOGD_DHCP4, iface, " classless static route %s/%d gw %s", + nm_utils_inet4_ntop (route.network, addr), route.plen, + nm_utils_inet4_ntop (route.gateway, NULL)); } } @@ -208,7 +212,8 @@ out: } static gboolean -ip4_process_classless_routes (GHashTable *options, +ip4_process_classless_routes (const char *iface, + GHashTable *options, guint32 priority, NMIP4Config *ip4_config, guint32 *gwaddr) @@ -257,7 +262,7 @@ ip4_process_classless_routes (GHashTable *options, p = str; while (*p) { if (!g_ascii_isdigit (*p) && (*p != ' ') && (*p != '.') && (*p != '/')) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str); return FALSE; } p++; @@ -265,14 +270,17 @@ ip4_process_classless_routes (GHashTable *options, if (strchr (str, '/')) { /* dhcpcd format */ - return ip4_process_dhcpcd_rfc3442_routes (str, priority, ip4_config, gwaddr); + return ip4_process_dhcpcd_rfc3442_routes (iface, str, priority, ip4_config, gwaddr); } - return ip4_process_dhclient_rfc3442_routes (str, priority, ip4_config, gwaddr); + return ip4_process_dhclient_rfc3442_routes (iface, str, priority, ip4_config, gwaddr); } static void -process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4_config) +process_classful_routes (const char *iface, + GHashTable *options, + guint32 priority, + NMIP4Config *ip4_config) { const char *str; char **searches, **s; @@ -283,7 +291,7 @@ process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4 searches = g_strsplit (str, " ", 0); if ((g_strv_length (searches) % 2)) { - nm_log_info (LOGD_DHCP, " static routes provided, but invalid"); + _LOG2I (LOGD_DHCP, iface, " static routes provided, but invalid"); goto out; } @@ -292,11 +300,11 @@ process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4 guint32 rt_addr, rt_route; if (inet_pton (AF_INET, *s, &rt_addr) <= 0) { - nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route address: '%s'", *s); + _LOG2W (LOGD_DHCP, iface, "DHCP provided invalid static route address: '%s'", *s); continue; } if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) { - nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route gateway: '%s'", *(s + 1)); + _LOG2W (LOGD_DHCP, iface, "DHCP provided invalid static route gateway: '%s'", *(s + 1)); continue; } @@ -314,11 +322,11 @@ process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4 route.plen = 32; } route.gateway = rt_route; - route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; nm_ip4_config_add_route (ip4_config, &route); - nm_log_info (LOGD_DHCP, " static route %s", + _LOG2I (LOGD_DHCP, iface, " static route %s", nm_platform_ip4_route_to_string (&route, NULL, 0)); } @@ -327,7 +335,10 @@ out: } static void -process_domain_search (const char *str, GFunc add_func, gpointer user_data) +process_domain_search (const char *iface, + const char *str, + GFunc add_func, + gpointer user_data) { char **searches, **s; char *unescaped, *p; @@ -348,14 +359,14 @@ process_domain_search (const char *str, GFunc add_func, gpointer user_data) } while (*p++); if (strchr (unescaped, '\\')) { - nm_log_warn (LOGD_DHCP, " invalid domain search: '%s'", unescaped); + _LOG2W (LOGD_DHCP, iface, " invalid domain search: '%s'", unescaped); goto out; } searches = g_strsplit (unescaped, " ", 0); for (s = searches; *s; s++) { if (strlen (*s)) { - nm_log_info (LOGD_DHCP, " domain search '%s'", *s); + _LOG2I (LOGD_DHCP, iface, " domain search '%s'", *s); add_func (*s, user_data); } } @@ -393,29 +404,29 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, str = g_hash_table_lookup (options, "ip_address"); if (str && (inet_pton (AF_INET, str, &addr) > 0)) - nm_log_info (LOGD_DHCP4, " address %s", str); + _LOG2I (LOGD_DHCP4, iface, " address %s", str); else goto error; str = g_hash_table_lookup (options, "subnet_mask"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { plen = nm_utils_ip4_netmask_to_prefix (tmp_addr); - nm_log_info (LOGD_DHCP4, " plen %d (%s)", plen, str); + _LOG2I (LOGD_DHCP4, iface, " plen %d (%s)", plen, str); } else { /* Get default netmask for the IP according to appropriate class. */ plen = nm_utils_ip4_get_default_prefix (addr); - nm_log_info (LOGD_DHCP4, " plen %d (default)", plen); + _LOG2I (LOGD_DHCP4, iface, " plen %d (default)", plen); } nm_platform_ip4_address_set_addr (&address, addr, plen); /* Routes: if the server returns classless static routes, we MUST ignore * the 'static_routes' option. */ - if (!ip4_process_classless_routes (options, priority, ip4_config, &gwaddr)) - process_classful_routes (options, priority, ip4_config); + if (!ip4_process_classless_routes (iface, options, priority, ip4_config, &gwaddr)) + process_classful_routes (iface, options, priority, ip4_config); if (gwaddr) { - nm_log_info (LOGD_DHCP4, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL)); + _LOG2I (LOGD_DHCP4, iface, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL)); nm_ip4_config_set_gateway (ip4_config, gwaddr); } else { /* If the gateway wasn't provided as a classless static route with a @@ -430,10 +441,10 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, /* FIXME: how to handle multiple routers? */ if (inet_pton (AF_INET, *s, &gwaddr) > 0) { nm_ip4_config_set_gateway (ip4_config, gwaddr); - nm_log_info (LOGD_DHCP4, " gateway %s", *s); + _LOG2I (LOGD_DHCP4, iface, " gateway %s", *s); break; } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid gateway '%s'", *s); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid gateway '%s'", *s); } g_strfreev (routers); } @@ -455,7 +466,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, if (str) { if (inet_pton (AF_INET, str, &tmp_addr) > 0) { - nm_log_info (LOGD_DHCP4, " server identifier %s", str); + _LOG2I (LOGD_DHCP4, iface, " server identifier %s", str); if ( nm_utils_ip4_address_clear_host_address(tmp_addr, address.plen) != nm_utils_ip4_address_clear_host_address(address.address, address.plen) && !nm_ip4_config_get_direct_route_for_host (ip4_config, tmp_addr)) { /* DHCP server not on assigned subnet and the no direct route was returned. Add route */ @@ -465,29 +476,29 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, route.plen = 32; /* this will be a device route if gwaddr is 0 */ route.gateway = gwaddr; - route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; nm_ip4_config_add_route (ip4_config, &route); - nm_log_dbg (LOGD_IP, "adding route for server identifier: %s", - nm_platform_ip4_route_to_string (&route, NULL, 0)); + _LOG2D (LOGD_IP, iface, "adding route for server identifier: %s", + nm_platform_ip4_route_to_string (&route, NULL, 0)); } } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid server identifier '%s'", str); } str = g_hash_table_lookup (options, "dhcp_lease_time"); if (str) { address.lifetime = address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP4, " lease time %u", address.lifetime); + _LOG2I (LOGD_DHCP4, iface, " lease time %u", address.lifetime); } - address.source = NM_IP_CONFIG_SOURCE_DHCP; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; nm_ip4_config_add_address (ip4_config, &address); str = g_hash_table_lookup (options, "host_name"); if (str) - nm_log_info (LOGD_DHCP4, " hostname '%s'", str); + _LOG2I (LOGD_DHCP4, iface, " hostname '%s'", str); str = g_hash_table_lookup (options, "domain_name_servers"); if (str) { @@ -498,10 +509,10 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { if (tmp_addr) { nm_ip4_config_add_nameserver (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " nameserver '%s'", *s); + _LOG2I (LOGD_DHCP4, iface, " nameserver '%s'", *s); } } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid nameserver '%s'", *s); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid nameserver '%s'", *s); } g_strfreev (dns); } @@ -512,7 +523,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, char **s; for (s = domains; *s; s++) { - nm_log_info (LOGD_DHCP4, " domain name '%s'", *s); + _LOG2I (LOGD_DHCP4, iface, " domain name '%s'", *s); nm_ip4_config_add_domain (ip4_config, *s); } g_strfreev (domains); @@ -520,7 +531,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, str = g_hash_table_lookup (options, "domain_search"); if (str) - process_domain_search (str, ip4_add_domain_search, ip4_config); + process_domain_search (iface, str, ip4_add_domain_search, ip4_config); str = g_hash_table_lookup (options, "netbios_name_servers"); if (str) { @@ -531,10 +542,10 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { if (tmp_addr) { nm_ip4_config_add_wins (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " wins '%s'", *s); + _LOG2I (LOGD_DHCP4, iface, " wins '%s'", *s); } } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid WINS server '%s'", *s); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid WINS server '%s'", *s); } g_strfreev (nbns); } @@ -554,7 +565,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, str = g_hash_table_lookup (options, "nis_domain"); if (str) { - nm_log_info (LOGD_DHCP4, " NIS domain '%s'", str); + _LOG2I (LOGD_DHCP4, iface, " NIS domain '%s'", str); nm_ip4_config_set_nis_domain (ip4_config, str); } @@ -567,10 +578,10 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { if (tmp_addr) { nm_ip4_config_add_nis_server (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " nis '%s'", *s); + _LOG2I (LOGD_DHCP4, iface, " nis '%s'", *s); } } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid NIS server '%s'", *s); + _LOG2W (LOGD_DHCP4, iface, "ignoring invalid NIS server '%s'", *s); } g_strfreev (nis); } @@ -615,8 +626,8 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, g_hash_table_iter_init (&iter, options); while (g_hash_table_iter_next (&iter, &key, &value)) { - nm_log_dbg (LOGD_DHCP6, "(%s): option '%s'=>'%s'", - iface, (const char *) key, (const char *) value); + _LOG2D (LOGD_DHCP6, iface, "(%s): option '%s'=>'%s'", + iface, (const char *) key, (const char *) value); } ip6_config = nm_ip6_config_new (ifindex); @@ -624,27 +635,27 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, str = g_hash_table_lookup (options, "max_life"); if (str) { address.lifetime = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " valid_lft %u", address.lifetime); + _LOG2I (LOGD_DHCP6, iface, " valid_lft %u", address.lifetime); } str = g_hash_table_lookup (options, "preferred_life"); if (str) { address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " preferred_lft %u", address.preferred); + _LOG2I (LOGD_DHCP6, iface, " preferred_lft %u", address.preferred); } str = g_hash_table_lookup (options, "ip6_address"); if (str) { if (!inet_pton (AF_INET6, str, &tmp_addr)) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCP returned invalid address '%s'", - iface, str); + _LOG2W (LOGD_DHCP6, iface, "(%s): DHCP returned invalid address '%s'", + iface, str); goto error; } address.address = tmp_addr; - address.source = NM_IP_CONFIG_SOURCE_DHCP; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; nm_ip6_config_add_address (ip6_config, &address); - nm_log_info (LOGD_DHCP6, " address %s", str); + _LOG2I (LOGD_DHCP6, iface, " address %s", str); } else if (info_only == FALSE) { /* No address in Managed mode is a hard error */ goto error; @@ -652,7 +663,7 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, str = g_hash_table_lookup (options, "host_name"); if (str) - nm_log_info (LOGD_DHCP6, " hostname '%s'", str); + _LOG2I (LOGD_DHCP6, iface, " hostname '%s'", str); str = g_hash_table_lookup (options, "dhcp6_name_servers"); if (str) { @@ -663,17 +674,17 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, if (inet_pton (AF_INET6, *s, &tmp_addr) > 0) { if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_addr)) { nm_ip6_config_add_nameserver (ip6_config, &tmp_addr); - nm_log_info (LOGD_DHCP6, " nameserver '%s'", *s); + _LOG2I (LOGD_DHCP6, iface, " nameserver '%s'", *s); } } else - nm_log_warn (LOGD_DHCP6, "ignoring invalid nameserver '%s'", *s); + _LOG2W (LOGD_DHCP6, iface, "ignoring invalid nameserver '%s'", *s); } g_strfreev (dns); } str = g_hash_table_lookup (options, "dhcp6_domain_search"); if (str) - process_domain_search (str, ip6_add_domain_search, ip6_config); + process_domain_search (iface, str, ip6_add_domain_search, ip6_config); return ip6_config; @@ -685,18 +696,9 @@ error: char * nm_dhcp_utils_duid_to_string (const GByteArray *duid) { - guint32 i = 0; - GString *s; - g_return_val_if_fail (duid != NULL, NULL); - s = g_string_sized_new (MIN (duid->len * 3, 50)); - while (i < duid->len) { - if (s->len) - g_string_append_c (s, ':'); - g_string_append_printf (s, "%02x", duid->data[i++]); - } - return g_string_free (s, FALSE); + return _nm_utils_bin2str (duid->data, duid->len, FALSE); } /** diff --git a/src/dhcp-manager/nm-dhcp-utils.h b/src/dhcp-manager/nm-dhcp-utils.h index 056982c3..6540b1ff 100644 --- a/src/dhcp-manager/nm-dhcp-utils.h +++ b/src/dhcp-manager/nm-dhcp-utils.h @@ -24,8 +24,6 @@ #include <nm-ip4-config.h> #include <nm-ip6-config.h> -#include "nm-default.h" - NMIP4Config *nm_dhcp_utils_ip4_config_from_options (int ifindex, const char *iface, GHashTable *options, diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in index 2528b3c5..1ce288ba 100644 --- a/src/dhcp-manager/tests/Makefile.in +++ b/src/dhcp-manager/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) TESTS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) subdir = src/dhcp-manager/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -428,6 +429,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -484,13 +486,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -502,6 +505,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -562,6 +567,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -597,6 +604,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 046dd7e2..77849c8c 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -31,7 +31,7 @@ #include "nm-ip4-config.h" #include "nm-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define DEBUG 1 diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c index f477c061..89d693ed 100644 --- a/src/dhcp-manager/tests/test-dhcp-utils.c +++ b/src/dhcp-manager/tests/test-dhcp-utils.c @@ -28,7 +28,7 @@ #include "nm-dhcp-utils.h" #include "nm-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" typedef struct { const char *name; diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h index 50f050e5..3deda582 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -24,12 +24,9 @@ #ifndef __NETWORKMANAGER_DNS_MANAGER_H__ #define __NETWORKMANAGER_DNS_MANAGER_H__ -#include "nm-default.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -G_BEGIN_DECLS - typedef enum { NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0, NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, @@ -117,6 +114,4 @@ typedef enum { gboolean nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self); -G_END_DECLS - #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h index 4c84b145..e24bc173 100644 --- a/src/dns-manager/nm-dns-plugin.h +++ b/src/dns-manager/nm-dns-plugin.h @@ -19,9 +19,7 @@ #ifndef __NETWORKMANAGER_DNS_PLUGIN_H__ #define __NETWORKMANAGER_DNS_PLUGIN_H__ -#include "nm-default.h" #include "nm-dns-manager.h" - #include "nm-config-data.h" #define NM_TYPE_DNS_PLUGIN (nm_dns_plugin_get_type ()) diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.c b/src/dnsmasq-manager/nm-dnsmasq-manager.c index 12395db6..7b725944 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-manager.c +++ b/src/dnsmasq-manager/nm-dnsmasq-manager.c @@ -65,60 +65,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static void -nm_dnsmasq_manager_init (NMDnsMasqManager *manager) -{ -} - -static void -finalize (GObject *object) -{ - NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (object); - - nm_dnsmasq_manager_stop (NM_DNSMASQ_MANAGER (object)); - - g_free (priv->iface); - g_free (priv->pidfile); - - G_OBJECT_CLASS (nm_dnsmasq_manager_parent_class)->finalize (object); -} - -static void -nm_dnsmasq_manager_class_init (NMDnsMasqManagerClass *manager_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - - g_type_class_add_private (manager_class, sizeof (NMDnsMasqManagerPrivate)); - - object_class->finalize = finalize; - - /* signals */ - signals[STATE_CHANGED] = - g_signal_new (NM_DNS_MASQ_MANAGER_STATE_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDnsMasqManagerClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); -} - -NMDnsMasqManager * -nm_dnsmasq_manager_new (const char *iface) -{ - NMDnsMasqManager *manager; - NMDnsMasqManagerPrivate *priv; - - manager = (NMDnsMasqManager *) g_object_new (NM_TYPE_DNSMASQ_MANAGER, NULL); - - priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); - priv->iface = g_strdup (iface); - priv->pidfile = g_strdup_printf (RUNSTATEDIR "/nm-dnsmasq-%s.pid", iface); - - return manager; -} - typedef struct { GPtrArray *array; GStringChunk *chunk; @@ -387,3 +333,56 @@ nm_dnsmasq_manager_stop (NMDnsMasqManager *manager) unlink (priv->pidfile); } + +NMDnsMasqManager * +nm_dnsmasq_manager_new (const char *iface) +{ + NMDnsMasqManager *manager; + NMDnsMasqManagerPrivate *priv; + + manager = (NMDnsMasqManager *) g_object_new (NM_TYPE_DNSMASQ_MANAGER, NULL); + + priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); + priv->iface = g_strdup (iface); + priv->pidfile = g_strdup_printf (RUNSTATEDIR "/nm-dnsmasq-%s.pid", iface); + + return manager; +} + +static void +nm_dnsmasq_manager_init (NMDnsMasqManager *manager) +{ +} + +static void +finalize (GObject *object) +{ + NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (object); + + nm_dnsmasq_manager_stop (NM_DNSMASQ_MANAGER (object)); + + g_free (priv->iface); + g_free (priv->pidfile); + + G_OBJECT_CLASS (nm_dnsmasq_manager_parent_class)->finalize (object); +} + +static void +nm_dnsmasq_manager_class_init (NMDnsMasqManagerClass *manager_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (manager_class); + + g_type_class_add_private (manager_class, sizeof (NMDnsMasqManagerPrivate)); + + object_class->finalize = finalize; + + /* signals */ + signals[STATE_CHANGED] = + g_signal_new (NM_DNS_MASQ_MANAGER_STATE_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); +} diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.h b/src/dnsmasq-manager/nm-dnsmasq-manager.h index 47c88e6e..b610b498 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-manager.h +++ b/src/dnsmasq-manager/nm-dnsmasq-manager.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_DNSMASQ_MANAGER_H__ #define __NETWORKMANAGER_DNSMASQ_MANAGER_H__ - -#include "nm-default.h" #include "nm-ip4-config.h" #define NM_TYPE_DNSMASQ_MANAGER (nm_dnsmasq_manager_get_type ()) @@ -48,9 +46,6 @@ typedef struct { typedef struct { GObjectClass parent; - - /* Signals */ - void (*state_changed) (NMDnsMasqManager *manager, NMDnsMasqStatus status); } NMDnsMasqManagerClass; GType nm_dnsmasq_manager_get_type (void); diff --git a/src/dnsmasq-manager/nm-dnsmasq-utils.h b/src/dnsmasq-manager/nm-dnsmasq-utils.h index 43d0b9a3..459dda04 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-utils.h +++ b/src/dnsmasq-manager/nm-dnsmasq-utils.h @@ -21,7 +21,6 @@ #ifndef __NETWORKMANAGER_DNSMASQ_UTILS_H__ #define __NETWORKMANAGER_DNSMASQ_UTILS_H__ -#include "nm-default.h" #include "nm-platform.h" gboolean nm_dnsmasq_utils_get_range (const NMPlatformIP4Address *addr, diff --git a/src/dnsmasq-manager/tests/Makefile.in b/src/dnsmasq-manager/tests/Makefile.in index 38344a8b..70f1ba1d 100644 --- a/src/dnsmasq-manager/tests/Makefile.in +++ b/src/dnsmasq-manager/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-dnsmasq-utils$(EXEEXT) TESTS = test-dnsmasq-utils$(EXEEXT) subdir = src/dnsmasq-manager/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -422,6 +423,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -478,13 +480,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -496,6 +499,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -556,6 +561,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -591,6 +598,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c index aeec5879..cf6dab50 100644 --- a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c +++ b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c @@ -24,7 +24,7 @@ #include "nm-dnsmasq-utils.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static void test_address_ranges (void) diff --git a/src/main-utils.c b/src/main-utils.c index 86242802..c2ed9d1c 100644 --- a/src/main-utils.c +++ b/src/main-utils.c @@ -31,7 +31,6 @@ #include <glib/gstdio.h> #include <glib-unix.h> -#include <gmodule.h> #include "main-utils.h" #include "NetworkManagerUtils.h" @@ -243,6 +242,7 @@ nm_main_utils_early_setup (const char *progname, textdomain (GETTEXT_PACKAGE); for (i = 0; options[i].long_name; i++) { + NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") if (!strcmp (options[i].long_name, "log-level")) { opt_fmt_log_level = options[i].description; opt_loc_log_level = &options[i].description; @@ -252,6 +252,7 @@ nm_main_utils_early_setup (const char *progname, opt_loc_log_domains = &options[i].description; options[i].description = g_strdup_printf (options[i].description, nm_logging_all_domains_to_string ()); } + NM_PRAGMA_WARNING_REENABLE } /* Parse options */ diff --git a/src/main-utils.h b/src/main-utils.h index 10ba3135..dbbdb85f 100644 --- a/src/main-utils.h +++ b/src/main-utils.h @@ -21,8 +21,6 @@ #ifndef __MAIN_UTILS_H__ #define __MAIN_UTILS_H__ -#include "nm-default.h" - void nm_main_utils_ensure_root (void); void nm_main_utils_setup_signals (GMainLoop *main_loop); diff --git a/src/main.c b/src/main.c index e243baa8..490dcfe9 100644 --- a/src/main.c +++ b/src/main.c @@ -31,7 +31,6 @@ #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> -#include <gmodule.h> #include <string.h> #include <sys/resource.h> @@ -71,81 +70,10 @@ static struct { 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, - gboolean *net_enabled, - gboolean *wifi_enabled, - gboolean *wwan_enabled, - GError **error) -{ - GKeyFile *state_file; - GError *tmp_error = NULL; - gboolean wifi, net, wwan; - - g_return_val_if_fail (net_enabled != NULL, FALSE); - g_return_val_if_fail (wifi_enabled != NULL, FALSE); - g_return_val_if_fail (wwan_enabled != NULL, FALSE); - - state_file = g_key_file_new (); - g_key_file_set_list_separator (state_file, ','); - if (!g_key_file_load_from_file (state_file, filename, G_KEY_FILE_KEEP_COMMENTS, &tmp_error)) { - gboolean ret = FALSE; - - /* This is kinda ugly; create the file and directory if it doesn't - * exist yet. We can't rely on distros necessarily creating the - * /var/lib/NetworkManager for us since we have to ensure that - * users upgrading NM get this working too. - */ - if (g_error_matches (tmp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { - char *data; - gsize len = 0; - - g_clear_error (&tmp_error); - - /* Write out the initial state to the state file */ - g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled); - g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled); - g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled); - - data = g_key_file_to_data (state_file, &len, NULL); - if (data) - ret = g_file_set_contents (filename, data, len, error); - g_free (data); - } else { - /* the error is not "No such file or directory" - propagate the error */ - g_propagate_error (error, tmp_error); - } - - return ret; - } - - /* Reading state bits of NetworkManager; an error leaves the passed-in state - * value unchanged. - */ - net = g_key_file_get_boolean (state_file, "main", "NetworkingEnabled", &tmp_error); - if (tmp_error == NULL) - *net_enabled = net; - g_clear_error (&tmp_error); - - wifi = g_key_file_get_boolean (state_file, "main", "WirelessEnabled", &tmp_error); - if (tmp_error == NULL) - *wifi_enabled = wifi; - g_clear_error (&tmp_error); - - wwan = g_key_file_get_boolean (state_file, "main", "WWANEnabled", &tmp_error); - if (tmp_error == NULL) - *wwan_enabled = wwan; - g_clear_error (&tmp_error); - - g_key_file_free (state_file); - return TRUE; -} - static void _set_g_fatal_warnings (void) { @@ -256,7 +184,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli) "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_(NM_DEFAULT_PID_FILE) }, - { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &global_opt.state_file, N_("State file location"), N_(NM_DEFAULT_SYSTEM_STATE_FILE) }, { "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", NULL }, { "print-config", 0, 0, G_OPTION_ARG_NONE, &global_opt.print_config, N_("Print NetworkManager configuration and exit"), NULL }, {NULL} @@ -272,7 +199,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli) 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); } /* @@ -282,7 +208,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli) int main (int argc, char *argv[]) { - gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE; gboolean success = FALSE; NMConfig *config; GError *error = NULL; @@ -423,17 +348,12 @@ main (int argc, char *argv[]) nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting..."); - /* Parse the state file */ - if (!parse_state_file (global_opt.state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) { - nm_log_err (LOGD_CORE, "State file %s parsing failed: %s", - global_opt.state_file, - error->message); - /* Not a hard failure */ - } - g_clear_error (&error); - nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config))); nm_config_data_log (nm_config_get_data (config), "CONFIG: ", " ", NULL); + + /* the first access to State causes the file to be read (and possibly print a warning) */ + nm_config_state_get (config); + nm_log_dbg (LOGD_CORE, "WEXT support is %s", #if HAVE_WEXT "enabled" @@ -444,10 +364,7 @@ main (int argc, char *argv[]) nm_auth_manager_setup (nm_config_get_auth_polkit (config)); - nm_manager_setup (global_opt.state_file, - net_enabled, - wifi_enabled, - wwan_enabled); + nm_manager_setup (); if (!nm_bus_manager_get_connection (nm_bus_manager_get ())) { nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available"); @@ -499,6 +416,8 @@ done: nm_manager_stop (nm_manager_get ()); + nm_config_state_set (config, TRUE, TRUE); + if (global_opt.pidfile && wrote_pidfile) unlink (global_opt.pidfile); diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index acc3e4ca..22fa5b69 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -445,9 +445,9 @@ master_failed (NMActiveConnection *self) if (device) { device_state = nm_device_get_state (device); if (nm_device_is_activating (device) || (device_state == NM_DEVICE_STATE_ACTIVATED)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + nm_device_queue_state (device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); return; } } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 929ce195..1bd00499 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_ACTIVATION_REQUEST_H__ #define __NETWORKMANAGER_ACTIVATION_REQUEST_H__ - -#include "nm-default.h" #include "nm-connection.h" #include "nm-active-connection.h" diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 2b7847b2..1844587c 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -546,7 +546,7 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device) g_signal_connect (device, NM_DEVICE_STATE_CHANGED, G_CALLBACK (device_state_changed), self); - g_signal_connect (device, "notify::master", + g_signal_connect (device, "notify::" NM_DEVICE_MASTER, G_CALLBACK (device_master_changed), self); g_signal_connect (device, "notify::" NM_DEVICE_METERED, G_CALLBACK (device_metered_changed), self); @@ -719,14 +719,14 @@ nm_active_connection_get_assumed (NMActiveConnection *self) /****************************************************************/ -static void unwatch_parent (NMActiveConnection *self); +static void unwatch_parent (NMActiveConnection *self, gboolean unref); static void parent_destroyed (gpointer user_data, GObject *parent) { NMActiveConnection *self = user_data; - unwatch_parent (self); + unwatch_parent (self, FALSE); g_signal_emit (self, signals[PARENT_ACTIVE], 0, NULL); } @@ -741,19 +741,20 @@ parent_state_cb (NMActiveConnection *parent_ac, if (parent_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED) return; - unwatch_parent (self); + unwatch_parent (self, TRUE); g_signal_emit (self, signals[PARENT_ACTIVE], 0, parent_ac); } static void -unwatch_parent (NMActiveConnection *self) +unwatch_parent (NMActiveConnection *self, gboolean unref) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); g_signal_handlers_disconnect_by_func (priv->parent, (GCallback) parent_state_cb, self); - g_object_weak_unref ((GObject *) priv->parent, parent_destroyed, self); + if (unref) + g_object_weak_unref ((GObject *) priv->parent, parent_destroyed, self); priv->parent = NULL; } @@ -1135,7 +1136,7 @@ dispose (GObject *object) g_clear_object (&priv->master); if (priv->parent) - unwatch_parent (self); + unwatch_parent (self, TRUE); g_clear_object (&priv->subject); diff --git a/src/nm-audit-manager.c b/src/nm-audit-manager.c index 728575f6..9e884096 100644 --- a/src/nm-audit-manager.c +++ b/src/nm-audit-manager.c @@ -233,10 +233,10 @@ nm_audit_manager_audit_enabled (NMAuditManager *self) void _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, NMSettingsConnection *connection, - gboolean result, gpointer subject_context, const char *reason) + gboolean result, const char *args, gpointer subject_context, const char *reason) { gs_unref_ptrarray GPtrArray *fields = NULL; - AuditField uuid_field = { }, name_field = { }; + AuditField uuid_field = { }, name_field = { }, args_field = { }; g_return_if_fail (op); @@ -252,11 +252,16 @@ _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, gui g_ptr_array_add (fields, &name_field); } + if (args) { + _audit_field_init_string (&args_field, "args", args, FALSE, BACKEND_ALL); + g_ptr_array_add (fields, &args_field); + } + _audit_log_helper (self, fields, file, line, func, op, result, subject_context, reason); } void -_nm_audit_manager_log_control_op (NMAuditManager *self, const char *file, guint line, +_nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, const char *arg, gboolean result, gpointer subject_context, const char *reason) diff --git a/src/nm-audit-manager.h b/src/nm-audit-manager.h index 9aef417f..af8a2037 100644 --- a/src/nm-audit-manager.h +++ b/src/nm-audit-manager.h @@ -21,15 +21,10 @@ #ifndef __NM_AUDIT_MANAGER_H__ #define __NM_AUDIT_MANAGER_H__ -#include <glib.h> -#include <glib-object.h> - #include "nm-connection.h" #include "nm-device.h" #include "nm-types.h" -G_BEGIN_DECLS - #define NM_TYPE_AUDIT_MANAGER (nm_audit_manager_get_type ()) #define NM_AUDIT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUDIT_MANAGER, NMAuditManager)) #define NM_AUDIT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AUDIT_MANAGER, NMAuditManagerClass)) @@ -57,6 +52,7 @@ typedef struct { #define NM_AUDIT_OP_SLEEP_CONTROL "sleep-control" #define NM_AUDIT_OP_NET_CONTROL "networking-control" #define NM_AUDIT_OP_RADIO_CONTROL "radio-control" +#define NM_AUDIT_OP_STATISTICS "statistics" #define NM_AUDIT_OP_DEVICE_AUTOCONNECT "device-autoconnect" #define NM_AUDIT_OP_DEVICE_DISCONNECT "device-disconnect" @@ -64,17 +60,21 @@ typedef struct { #define NM_AUDIT_OP_DEVICE_MANAGED "device-managed" #define NM_AUDIT_OP_DEVICE_REAPPLY "device-reapply" +#define NM_AUDIT_OP_CHECKPOINT_CREATE "checkpoint-create" +#define NM_AUDIT_OP_CHECKPOINT_ROLLBACK "checkpoint-rollback" +#define NM_AUDIT_OP_CHECKPOINT_DESTROY "checkpoint-destroy" + GType nm_audit_manager_get_type (void); NMAuditManager *nm_audit_manager_get (void); gboolean nm_audit_manager_audit_enabled (NMAuditManager *self); -#define nm_audit_log_connection_op(op, connection, result, subject_context, reason) \ +#define nm_audit_log_connection_op(op, connection, result, args, subject_context, reason) \ G_STMT_START { \ NMAuditManager *_audit = nm_audit_manager_get (); \ \ if (nm_audit_manager_audit_enabled (_audit)) { \ _nm_audit_manager_log_connection_op (_audit, __FILE__, __LINE__, G_STRFUNC, \ - (op), (connection), (result), (subject_context), \ + (op), (connection), (result), (args), (subject_context), \ (reason)); \ } \ } G_STMT_END @@ -84,7 +84,7 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self); NMAuditManager *_audit = nm_audit_manager_get (); \ \ if (nm_audit_manager_audit_enabled (_audit)) { \ - _nm_audit_manager_log_control_op (_audit, __FILE__, __LINE__, G_STRFUNC, \ + _nm_audit_manager_log_generic_op (_audit, __FILE__, __LINE__, G_STRFUNC, \ (op), (arg), (result), (subject_context), (reason)); \ } \ } G_STMT_END @@ -99,17 +99,27 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self); } \ } G_STMT_END +#define nm_audit_log_checkpoint_op(op, arg, result, subject_context, reason) \ + G_STMT_START { \ + NMAuditManager *_audit = nm_audit_manager_get (); \ + \ + if (nm_audit_manager_audit_enabled (_audit)) { \ + _nm_audit_manager_log_generic_op (_audit, __FILE__, __LINE__, G_STRFUNC, \ + (op), (arg), (result), (subject_context), (reason)); \ + } \ + } G_STMT_END + void _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, NMSettingsConnection *connection, - gboolean result, gpointer subject_context, const char *reason); + gboolean result, const char *args, gpointer subject_context, + const char *reason); -void _nm_audit_manager_log_control_op (NMAuditManager *self, const char *file, guint line, +void _nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, const char *arg, gboolean result, gpointer subject_context, const char *reason); void _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, NMDevice *device, gboolean result, gpointer subject_context, const char *reason); -G_END_DECLS #endif /* __NM_AUDIT_MANAGER_H__ */ diff --git a/src/nm-auth-manager.h b/src/nm-auth-manager.h index 2875cccb..9251b334 100644 --- a/src/nm-auth-manager.h +++ b/src/nm-auth-manager.h @@ -21,13 +21,8 @@ #ifndef NM_AUTH_MANAGER_H #define NM_AUTH_MANAGER_H - -#include "nm-default.h" #include "nm-auth-subject.h" -G_BEGIN_DECLS - - #define NM_TYPE_AUTH_MANAGER (nm_auth_manager_get_type ()) #define NM_AUTH_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUTH_MANAGER, NMAuthManager)) #define NM_AUTH_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AUTH_MANAGER, NMAuthManagerClass)) @@ -72,7 +67,5 @@ gboolean nm_auth_manager_polkit_authority_check_authorization_finish (NMAuthMana #endif -G_END_DECLS - #endif /* NM_AUTH_MANAGER_H */ diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c index 86b873f0..eb496b28 100644 --- a/src/nm-auth-subject.c +++ b/src/nm-auth-subject.c @@ -37,10 +37,6 @@ #include "nm-enum-types.h" #include "NetworkManagerUtils.h" -G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT) - -#define NM_AUTH_SUBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectPrivate)) - enum { PROP_0, PROP_SUBJECT_TYPE, @@ -61,6 +57,30 @@ typedef struct { } unix_process; } NMAuthSubjectPrivate; +struct _NMAuthSubject { + GObject parent; + NMAuthSubjectPrivate _priv; +}; + +struct _NMAuthSubjectClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT) + +#define NM_AUTH_SUBJECT_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMAuthSubject *_self2 = (_self); \ + \ + nm_assert (NM_IS_AUTH_SUBJECT (_self)); \ + &_self->_priv; \ + }) + /**************************************************************/ #define CHECK_SUBJECT(self, error_value) \ @@ -252,7 +272,7 @@ nm_auth_subject_new_internal (void) static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE ((NMAuthSubject *) object); switch (prop_id) { case PROP_SUBJECT_TYPE: @@ -276,7 +296,7 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE ((NMAuthSubject *) object); NMAuthSubjectType subject_type; const char *str; gulong id; @@ -317,8 +337,10 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p } static void -_clear_private (NMAuthSubjectPrivate *priv) +_clear_private (NMAuthSubject *self) { + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); + priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID; priv->unix_process.pid = G_MAXULONG; priv->unix_process.uid = G_MAXULONG; @@ -328,7 +350,7 @@ _clear_private (NMAuthSubjectPrivate *priv) static void nm_auth_subject_init (NMAuthSubject *self) { - _clear_private (NM_AUTH_SUBJECT_GET_PRIVATE (self)); + _clear_private (self); } static void @@ -363,7 +385,7 @@ constructed (GObject *object) /* Is the process already gone? Then fail creation of the auth subject * by clearing the type. */ if (kill (priv->unix_process.pid, 0) != 0) - _clear_private (priv); + _clear_private (self); /* Otherwise, although we didn't detect a start_time, the process is still around. * That could be due to procfs mounted with hidepid. So just accept the request. @@ -378,16 +400,14 @@ constructed (GObject *object) break; } - _clear_private (priv); + _clear_private (self); g_return_if_reached (); } static void finalize (GObject *object) { - NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); - - _clear_private (priv); + _clear_private ((NMAuthSubject *) object); G_OBJECT_CLASS (nm_auth_subject_parent_class)->finalize (object); } @@ -397,8 +417,6 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - g_type_class_add_private (config_class, sizeof (NMAuthSubjectPrivate)); - /* virtual methods */ object_class->get_property = get_property; object_class->set_property = set_property; diff --git a/src/nm-auth-subject.h b/src/nm-auth-subject.h index 5f507058..a0b6d14b 100644 --- a/src/nm-auth-subject.h +++ b/src/nm-auth-subject.h @@ -39,13 +39,7 @@ typedef enum { #define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid" #define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid" -struct _NMAuthSubject { - GObject parent; -}; - -typedef struct { - GObjectClass parent; -} NMAuthSubjectClass; +typedef struct _NMAuthSubjectClass NMAuthSubjectClass; GType nm_auth_subject_get_type (void); diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index e1761cab..a6bc506c 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -399,8 +399,8 @@ nm_auth_chain_add_call (NMAuthChain *self, call); #else if (!call->chain->error) { - call->chain->error = g_error_new_literal (DBUS_GERROR, - DBUS_GERROR_FAILED, + call->chain->error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Polkit support is disabled at compile time"); } call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); diff --git a/src/nm-bus-manager.c b/src/nm-bus-manager.c index 656e7dbf..449de4e6 100644 --- a/src/nm-bus-manager.c +++ b/src/nm-bus-manager.c @@ -533,6 +533,54 @@ nm_bus_manager_get_caller_info_from_message (NMBusManager *self, return _get_caller_info (self, NULL, connection, message, out_sender, out_uid, out_pid); } +/** + * nm_bus_manager_ensure_uid: + * + * @self: bus manager instance + * @context: D-Bus method invocation + * @uid: a user-id + * @error_domain: error domain to return on failure + * @error_code: error code to return on failure + * + * Retrieves the uid of the D-Bus method caller and + * checks that it matches @uid, unless @uid is G_MAXULONG. + * In case of failure the function returns FALSE and finishes + * handling the D-Bus method with an error. + * + * Returns: %TRUE if the check succeeded, %FALSE otherwise + */ +gboolean +nm_bus_manager_ensure_uid (NMBusManager *self, + GDBusMethodInvocation *context, + gulong uid, + GQuark error_domain, + int error_code) +{ + gulong caller_uid; + GError *error = NULL; + + g_return_val_if_fail (NM_IS_BUS_MANAGER (self), FALSE); + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (context), FALSE); + + if (!nm_bus_manager_get_caller_info (self, context, NULL, &caller_uid, NULL)) { + error = g_error_new_literal (error_domain, + error_code, + "Unable to determine request UID."); + g_dbus_method_invocation_take_error (context, error); + return FALSE; + } + + if (uid != G_MAXULONG && caller_uid != uid) { + error = g_error_new_literal (error_domain, + error_code, + "Permission denied"); + g_dbus_method_invocation_take_error (context, error); + return FALSE; + } + + return TRUE; +} + gboolean nm_bus_manager_get_unix_user (NMBusManager *self, const char *sender, diff --git a/src/nm-bus-manager.h b/src/nm-bus-manager.h index 49579d46..bc23d2ce 100644 --- a/src/nm-bus-manager.h +++ b/src/nm-bus-manager.h @@ -22,8 +22,6 @@ #ifndef __NM_BUS_MANAGER_H__ #define __NM_BUS_MANAGER_H__ -G_BEGIN_DECLS - #define NM_TYPE_BUS_MANAGER (nm_bus_manager_get_type ()) #define NM_BUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_BUS_MANAGER, NMBusManager)) #define NM_BUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_BUS_MANAGER, NMBusManagerClass)) @@ -68,6 +66,12 @@ gboolean nm_bus_manager_get_caller_info (NMBusManager *self, gulong *out_uid, gulong *out_pid); +gboolean nm_bus_manager_ensure_uid (NMBusManager *self, + GDBusMethodInvocation *context, + gulong uid, + GQuark error_domain, + int error_code); + const char *nm_bus_manager_connection_get_private_name (NMBusManager *self, GDBusConnection *connection); @@ -102,6 +106,4 @@ GDBusProxy *nm_bus_manager_new_proxy (NMBusManager *self, const char *path, const char *iface); -G_END_DECLS - #endif /* __NM_BUS_MANAGER_H__ */ diff --git a/src/nm-checkpoint-manager.c b/src/nm-checkpoint-manager.c new file mode 100644 index 00000000..254dc31e --- /dev/null +++ b/src/nm-checkpoint-manager.c @@ -0,0 +1,298 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2016 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-checkpoint-manager.h" + +#include "nm-checkpoint.h" +#include "nm-connection.h" +#include "nm-core-utils.h" +#include "nm-device.h" +#include "nm-exported-object.h" +#include "nm-manager.h" +#include "nm-utils.h" + +/*****************************************************************************/ + +struct _NMCheckpointManager { + NMManager *_manager; + GHashTable *checkpoints; + guint rollback_timeout_id; +}; + +#define GET_MANAGER(self) \ + ({ \ + typeof (self) _self = (self); \ + \ + _nm_unused NMCheckpointManager *_self2 = _self; \ + \ + nm_assert (_self); \ + nm_assert (NM_IS_MANAGER (_self->_manager)); \ + _self->_manager; \ + }) + +/*****************************************************************************/ + +#define _NMLOG_PREFIX_NAME "checkpoint" +#define _NMLOG_DOMAIN LOGD_CORE + +#define _NMLOG(level, ...) \ + nm_log (level, _NMLOG_DOMAIN, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static void update_rollback_timeout (NMCheckpointManager *self); + +static void +checkpoint_destroy (gpointer checkpoint) +{ + nm_exported_object_unexport (NM_EXPORTED_OBJECT (checkpoint)); + g_object_unref (G_OBJECT (checkpoint)); +} + +static gboolean +rollback_timeout_cb (NMCheckpointManager *self) +{ + NMCheckpoint *checkpoint; + GHashTableIter iter; + GVariant *result; + gint64 ts, now; + + now = nm_utils_get_monotonic_timestamp_ms (); + + g_hash_table_iter_init (&iter, self->checkpoints); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &checkpoint)) { + ts = nm_checkpoint_get_rollback_ts (checkpoint); + if (ts && ts <= now) { + result = nm_checkpoint_rollback (checkpoint); + if (result) + g_variant_unref (result); + g_hash_table_iter_remove (&iter); + } + } + + self->rollback_timeout_id = 0; + update_rollback_timeout (self); + + return G_SOURCE_REMOVE; +} + +static void +update_rollback_timeout (NMCheckpointManager *self) +{ + NMCheckpoint *checkpoint; + GHashTableIter iter; + gint64 ts, delta, next = G_MAXINT64; + + g_hash_table_iter_init (&iter, self->checkpoints); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &checkpoint)) { + ts = nm_checkpoint_get_rollback_ts (checkpoint); + if (ts && ts < next) + next = ts; + } + + nm_clear_g_source (&self->rollback_timeout_id); + + if (next != G_MAXINT64) { + delta = MAX (next - nm_utils_get_monotonic_timestamp_ms (), 0); + self->rollback_timeout_id = g_timeout_add (delta, + (GSourceFunc) rollback_timeout_cb, + self); + _LOGT ("update timeout: next check in %" G_GINT64_FORMAT " ms", delta); + } +} + +static NMCheckpoint * +find_checkpoint_for_device (NMCheckpointManager *self, NMDevice *device) +{ + GHashTableIter iter; + NMCheckpoint *checkpoint; + + g_hash_table_iter_init (&iter, self->checkpoints); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &checkpoint)) { + if (nm_checkpoint_includes_device (checkpoint, device)) + return checkpoint; + } + + return NULL; +} + +NMCheckpoint * +nm_checkpoint_manager_create (NMCheckpointManager *self, + const char *const *device_paths, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GError **error) +{ + NMCheckpoint *checkpoint; + const char * const *path; + gs_unref_ptrarray GPtrArray *devices = NULL; + NMDevice *device; + const char *checkpoint_path; + guint i; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + devices = g_ptr_array_new (); + for (path = device_paths; *path; path++) { + device = nm_manager_get_device_by_path (GET_MANAGER (self), *path); + if (!device) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "device %s does not exist", *path); + return NULL; + } + g_ptr_array_add (devices, device); + } + + if (!NM_FLAGS_HAS (flags, NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL)) { + for (i = 0; i < devices->len; i++) { + device = devices->pdata[i]; + if (find_checkpoint_for_device (self, device)) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "a checkpoint for device '%s' already exists", + nm_device_get_iface (device)); + return NULL; + } + } + } + + checkpoint = nm_checkpoint_new (GET_MANAGER (self), devices, + rollback_timeout, error); + if (!checkpoint) + return NULL; + + if (NM_FLAGS_HAS (flags, NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL)) + g_hash_table_remove_all (self->checkpoints); + + nm_exported_object_export (NM_EXPORTED_OBJECT (checkpoint)); + checkpoint_path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint)); + + if (!nm_g_hash_table_insert (self->checkpoints, + (gpointer) checkpoint_path, + checkpoint)) + g_return_val_if_reached (NULL); + + update_rollback_timeout (self); + + return checkpoint; +} + +gboolean +nm_checkpoint_manager_destroy_all (NMCheckpointManager *self, + GError **error) +{ + g_return_val_if_fail (self, FALSE); + + g_hash_table_remove_all (self->checkpoints); + + return TRUE; +} + +gboolean +nm_checkpoint_manager_destroy (NMCheckpointManager *self, + const char *checkpoint_path, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (checkpoint_path && checkpoint_path[0] == '/', FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + if (!nm_streq (checkpoint_path, "/")) { + ret = g_hash_table_remove (self->checkpoints, checkpoint_path); + if (!ret) { + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "checkpoint %s does not exist", checkpoint_path); + } + return ret; + } else + return nm_checkpoint_manager_destroy_all (self, error); +} + +gboolean +nm_checkpoint_manager_rollback (NMCheckpointManager *self, + const char *checkpoint_path, + GVariant **results, + GError **error) +{ + NMCheckpoint *cp; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (checkpoint_path && checkpoint_path[0] == '/', FALSE); + g_return_val_if_fail (results, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + cp = g_hash_table_lookup (self->checkpoints, checkpoint_path); + if (!cp) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + "checkpoint %s does not exist", checkpoint_path); + return FALSE; + } + + *results = nm_checkpoint_rollback (cp); + g_hash_table_remove (self->checkpoints, checkpoint_path); + + return TRUE; +} + +/*****************************************************************************/ + +NMCheckpointManager * +nm_checkpoint_manager_new (NMManager *manager) +{ + NMCheckpointManager *self; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + self = g_slice_new0 (NMCheckpointManager); + + /* the NMCheckpointManager instance is actually owned by NMManager. + * Thus, we cannot take a reference to it, and we also don't bother + * taking a weak-reference. Instead let GET_MANAGER() assert that + * self->_manager is alive -- which we always expect as the lifetime + * of NMManager shall surpass the lifetime of the NMCheckpointManager + * instance. */ + self->_manager = manager; + self->checkpoints = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, checkpoint_destroy); + + return self; +} + +void +nm_checkpoint_manager_unref (NMCheckpointManager *self) +{ + if (!self) + return; + + nm_clear_g_source (&self->rollback_timeout_id); + g_hash_table_destroy (self->checkpoints); + + g_slice_free (NMCheckpointManager, self); +} + diff --git a/src/nm-checkpoint-manager.h b/src/nm-checkpoint-manager.h new file mode 100644 index 00000000..022b1a80 --- /dev/null +++ b/src/nm-checkpoint-manager.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_CHECKPOINT_MANAGER_H__ +#define __NM_CHECKPOINT_MANAGER_H__ + +#include "nm-dbus-interface.h" +#include "nm-checkpoint.h" + +typedef struct _NMCheckpointManager NMCheckpointManager; + +NMCheckpointManager *nm_checkpoint_manager_new (NMManager *manager); +void nm_checkpoint_manager_unref (NMCheckpointManager *self); + +NMCheckpoint *nm_checkpoint_manager_create (NMCheckpointManager *self, + const char *const*device_names, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GError **error); + +gboolean nm_checkpoint_manager_destroy_all (NMCheckpointManager *self, + GError **error); + +gboolean nm_checkpoint_manager_destroy (NMCheckpointManager *self, + const char *checkpoint_path, + GError **error); +gboolean nm_checkpoint_manager_rollback (NMCheckpointManager *self, + const char *checkpoint_path, + GVariant **results, + GError **error); + +#endif /* __NM_CHECKPOINT_MANAGER_H__ */ + diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c new file mode 100644 index 00000000..cb1adc39 --- /dev/null +++ b/src/nm-checkpoint.c @@ -0,0 +1,433 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2016 Red Hat, Inc. + */ + +#include "nm-default.h" +#include "nm-checkpoint.h" + +#include <string.h> + +#include "nm-auth-subject.h" +#include "nm-core-utils.h" +#include "nm-dbus-interface.h" +#include "nm-device.h" +#include "nm-manager.h" +#include "nm-settings.h" +#include "nm-settings-connection.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "nmdbus-checkpoint.h" + +#define _NMLOG_PREFIX_NAME "checkpoint" +#define _NMLOG_DOMAIN LOGD_CORE + +#define _NMLOG(level, ...) \ + G_STMT_START { \ + if (nm_logging_enabled (level, _NMLOG_DOMAIN)) { \ + char __prefix[32]; \ + \ + if (self) \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", ""_NMLOG_PREFIX_NAME"", (self)); \ + else \ + g_strlcpy (__prefix, _NMLOG_PREFIX_NAME, sizeof (__prefix)); \ + _nm_log ((level), (_NMLOG_DOMAIN), 0, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +typedef struct { + char *original_dev_path; + NMDevice *device; + NMConnection *connection; +} DeviceCheckpoint; + +typedef struct { + /* properties */ + GHashTable *devices; + gint64 created; + guint32 rollback_timeout; + /* private members */ + NMManager *manager; + gint64 rollback_ts; +} NMCheckpointPrivate; + +struct _NMCheckpoint { + NMExportedObject parent; + NMCheckpointPrivate priv; +}; + +typedef struct { + NMExportedObjectClass parent; +} NMCheckpointClass; + +G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_EXPORTED_OBJECT) + +#define NM_CHECKPOINT_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMCheckpoint *_self2 = (_self); \ + \ + nm_assert (NM_IS_CHECKPOINT (_self)); \ + &_self->priv; \ + }) + +NM_GOBJECT_PROPERTIES_DEFINE_BASE ( + PROP_DEVICES, + PROP_CREATED, + PROP_ROLLBACK_TIMEOUT, +); + +guint64 +nm_checkpoint_get_rollback_ts (NMCheckpoint *self) +{ + g_return_val_if_fail (NM_IS_CHECKPOINT (self), 0); + + return NM_CHECKPOINT_GET_PRIVATE (self)->rollback_ts; +} + +gboolean +nm_checkpoint_includes_device (NMCheckpoint *self, NMDevice *device) +{ + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); + + return g_hash_table_contains (priv->devices, device); +} + +GVariant * +nm_checkpoint_rollback (NMCheckpoint *self) +{ + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); + DeviceCheckpoint *dev_checkpoint; + GHashTableIter iter; + NMSettingsConnection *connection; + NMDevice *device; + GError *local_error = NULL; + GVariantBuilder builder; + + _LOGI ("rollback of %s", nm_exported_object_get_path ((NMExportedObject *) self)); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{su}")); + + /* Start rolling-back each device */ + g_hash_table_iter_init (&iter, priv->devices); + while (g_hash_table_iter_next (&iter, (gpointer *) &device, (gpointer *) &dev_checkpoint)) { + gs_unref_object NMAuthSubject *subject = NULL; + guint32 result = NM_ROLLBACK_RESULT_OK; + const char *con_path; + + _LOGD ("rollback: restoring state of device %s", nm_device_get_iface (device)); + + if (!nm_device_is_real (device)) { + result = NM_ROLLBACK_RESULT_ERR_NO_DEVICE; + _LOGD ("rollback: device is not realized"); + goto next_dev; + } + + if (nm_device_get_state (device) <= NM_DEVICE_STATE_UNMANAGED) { + result = NM_ROLLBACK_RESULT_ERR_DEVICE_UNMANAGED; + _LOGD ("rollback: device is unmanaged"); + goto next_dev; + } + + if (dev_checkpoint->connection) { + /* The device had an active connection, check if the + * connection still exists + * */ + con_path = nm_connection_get_path (dev_checkpoint->connection); + connection = nm_settings_get_connection_by_path (nm_settings_get(), con_path); + + if (connection) { + /* If the connection is still there, restore its content + * and save it + * */ + _LOGD ("rollback: connection %s still exists", con_path); + + nm_connection_replace_settings_from_connection (NM_CONNECTION (connection), + dev_checkpoint->connection); + nm_settings_connection_commit_changes (connection, + NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, + NULL, + NULL); + } else { + /* The connection was deleted, recreate it */ + _LOGD ("rollback: adding connection %s again", con_path); + + connection = nm_settings_add_connection (nm_settings_get (), + dev_checkpoint->connection, + TRUE, + &local_error); + if (!connection) { + _LOGD ("rollback: connection add failure: %s", local_error->message); + g_clear_error (&local_error); + result = NM_ROLLBACK_RESULT_ERR_FAILED; + goto next_dev; + } + } + + /* Now re-activate the connection */ + subject = nm_auth_subject_new_internal (); + if (!nm_manager_activate_connection (priv->manager, + connection, + NULL, + device, + subject, + &local_error)) { + _LOGW ("rollback: reactivation of connection %s/%s failed: %s", + nm_connection_get_id ((NMConnection *) connection), + nm_connection_get_uuid ((NMConnection * ) connection), + local_error->message); + g_clear_error (&local_error); + result = NM_ROLLBACK_RESULT_ERR_FAILED; + goto next_dev; + } + } else { + /* The device was initially disconnected, deactivate any existing connection */ + _LOGD ("rollback: disconnecting device"); + + if ( nm_device_get_state (device) > NM_DEVICE_STATE_DISCONNECTED + && nm_device_get_state (device) < NM_DEVICE_STATE_DEACTIVATING) { + nm_device_state_changed (device, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } + +next_dev: + g_variant_builder_add (&builder, "{su}", dev_checkpoint->original_dev_path, result); + } + + return g_variant_new ("(a{su})", &builder); +} + +static DeviceCheckpoint * +device_checkpoint_create (NMDevice *device, + GError **error) +{ + DeviceCheckpoint *dev_checkpoint; + NMConnection *connection; + const char *path; + + if (!nm_device_is_real (device)) { + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "device '%s' is not realized", + nm_device_get_iface (device)); + return NULL; + } + + if (nm_device_get_state (device) <= NM_DEVICE_STATE_UNMANAGED) { + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "device '%s' is unmanaged", + nm_device_get_iface (device)); + return NULL; + } + + path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)); + + dev_checkpoint = g_slice_new0 (DeviceCheckpoint); + dev_checkpoint->device = g_object_ref (device); + dev_checkpoint->original_dev_path = g_strdup (path); + + connection = nm_device_get_applied_connection (device); + if (connection) + dev_checkpoint->connection = nm_simple_connection_new_clone (connection); + + return dev_checkpoint; +} + +static void +device_checkpoint_destroy (gpointer data) +{ + DeviceCheckpoint *dev_checkpoint = data; + + g_clear_object (&dev_checkpoint->connection); + g_clear_object (&dev_checkpoint->device); + g_free (dev_checkpoint->original_dev_path); + + g_slice_free (DeviceCheckpoint, dev_checkpoint); +} + +static void +nm_checkpoint_init (NMCheckpoint *self) +{ + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); + + priv->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, device_checkpoint_destroy); +} + +static void +get_all_devices (NMManager *manager, GPtrArray *devices) +{ + const GSList *list, *iter; + NMDevice *dev; + + list = nm_manager_get_devices (manager); + + for (iter = list; iter; iter = g_slist_next (iter)) { + dev = iter->data; + + if (!nm_device_is_real (dev)) + continue; + if (nm_device_get_state (dev) <= NM_DEVICE_STATE_UNMANAGED) + continue; + /* We never touch assumed connections, unless told explicitly */ + if (nm_device_uses_assumed_connection (dev)) + continue; + + g_ptr_array_add (devices, dev); + } +} + +NMCheckpoint * +nm_checkpoint_new (NMManager *manager, GPtrArray *devices, guint32 rollback_timeout, + GError **error) +{ + NMCheckpoint *self; + NMCheckpointPrivate *priv; + DeviceCheckpoint *dev_checkpoint; + NMDevice *device; + guint i; + + g_return_val_if_fail (manager, NULL); + g_return_val_if_fail (devices, NULL); + g_return_val_if_fail (!error || !*error, NULL); + + if (!devices->len) + get_all_devices (manager, devices); + + if (!devices->len) { + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "no device available"); + return NULL; + } + + self = g_object_new (NM_TYPE_CHECKPOINT, NULL); + + priv = NM_CHECKPOINT_GET_PRIVATE (self); + priv->manager = manager; + priv->created = nm_utils_monotonic_timestamp_as_boottime (nm_utils_get_monotonic_timestamp_ms (), + NM_UTILS_NS_PER_MSEC); + priv->rollback_timeout = rollback_timeout; + priv->rollback_ts = rollback_timeout ? + (nm_utils_get_monotonic_timestamp_ms () + ((gint64) rollback_timeout * 1000)) : + 0; + + for (i = 0; i < devices->len; i++) { + device = (NMDevice *) devices->pdata[i]; + dev_checkpoint = device_checkpoint_create (device, error); + if (!dev_checkpoint) { + g_object_unref (self); + return NULL; + } + g_hash_table_insert (priv->devices, device, dev_checkpoint); + } + + return self; +} + +static void +dispose (GObject *object) +{ + NMCheckpoint *self = NM_CHECKPOINT (object); + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); + + g_clear_pointer (&priv->devices, g_hash_table_unref); + + G_OBJECT_CLASS (nm_checkpoint_parent_class)->dispose (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMCheckpoint *self = NM_CHECKPOINT (object); + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); + gs_free_slist GSList *devices = NULL; + GHashTableIter iter; + NMDevice *device; + + switch (prop_id) { + case PROP_DEVICES: + g_hash_table_iter_init (&iter, priv->devices); + while (g_hash_table_iter_next (&iter, (gpointer *) &device, NULL)) + devices = g_slist_append (devices, device); + nm_utils_g_value_set_object_path_array (value, devices, NULL, NULL); + break; + case PROP_CREATED: + g_value_set_int64 (value, priv->created); + break; + case PROP_ROLLBACK_TIMEOUT: + g_value_set_uint (value, priv->rollback_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (checkpoint_class); + NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (checkpoint_class); + + g_type_class_add_private (checkpoint_class, sizeof (NMCheckpointPrivate)); + + exported_object_class->export_path = NM_DBUS_PATH "/Checkpoint/%u"; + exported_object_class->export_on_construction = FALSE; + + /* virtual methods */ + object_class->dispose = dispose; + object_class->get_property = get_property; + + /* properties */ + obj_properties[PROP_DEVICES] = + g_param_spec_boxed (NM_CHECKPOINT_DEVICES, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CREATED] = + g_param_spec_int64 (NM_CHECKPOINT_CREATED, "", "", + G_MININT64, G_MAXINT64, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ROLLBACK_TIMEOUT] = + g_param_spec_uint (NM_CHECKPOINT_ROLLBACK_TIMEOUT, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (checkpoint_class), + NMDBUS_TYPE_CHECKPOINT_SKELETON, + NULL); +} diff --git a/src/nm-checkpoint.h b/src/nm-checkpoint.h new file mode 100644 index 00000000..c7d2d42f --- /dev/null +++ b/src/nm-checkpoint.h @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_CHECKPOINT_H__ +#define __NETWORKMANAGER_CHECKPOINT_H__ + +#include "nm-exported-object.h" +#include "nm-dbus-interface.h" + +#define NM_TYPE_CHECKPOINT (nm_checkpoint_get_type ()) +#define NM_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CHECKPOINT, NMCheckpoint)) +#define NM_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CHECKPOINT, NMCheckpointClass)) +#define NM_IS_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CHECKPOINT)) +#define NM_IS_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CHECKPOINT)) +#define NM_CHECKPOINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CHECKPOINT, NMCheckpointClass)) + +typedef struct _NMCheckpoint NMCheckpoint; + +#define NM_CHECKPOINT_DEVICES "devices" +#define NM_CHECKPOINT_CREATED "created" +#define NM_CHECKPOINT_ROLLBACK_TIMEOUT "rollback-timeout" + +GType nm_checkpoint_get_type (void); + +NMCheckpoint *nm_checkpoint_new (NMManager *manager, GPtrArray *devices, guint32 rollback_timeout, + GError **error); + +guint64 nm_checkpoint_get_rollback_ts (NMCheckpoint *checkpoint); +gboolean nm_checkpoint_includes_device (NMCheckpoint *checkpoint, NMDevice *device); +GVariant *nm_checkpoint_rollback (NMCheckpoint *self); + +#endif /* __NETWORKMANAGER_CHECKPOINT_H__ */ diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 28057b47..23c4cecd 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -40,7 +40,7 @@ typedef struct { gboolean has; GSList *spec; } match_device; -} ConnectionInfo; +} MatchSectionInfo; typedef struct { char *config_main_file; @@ -52,7 +52,11 @@ typedef struct { /* A zero-terminated list of pre-processed information from the * [connection] sections. This is to speed up lookup. */ - ConnectionInfo *connection_infos; + MatchSectionInfo *connection_infos; + + /* A zero-terminated list of pre-processed information from the + * [device] sections. This is to speed up lookup. */ + MatchSectionInfo *device_infos; struct { char *uri; @@ -268,9 +272,16 @@ nm_config_data_get_rc_manager (const NMConfigData *self) gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device) { + gs_free char *value = NULL; + gboolean has_match; + g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE); g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + value = nm_config_data_get_device_config (self, NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER, device, &has_match); + if (has_match) + return nm_config_parse_boolean (value, FALSE); + return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier); } @@ -451,6 +462,7 @@ static int _nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy) { gboolean a_is_connection, b_is_connection; + gboolean a_is_device, b_is_device; gboolean a_is_intern, b_is_intern; const char *a = *pa; const char *b = *pb; @@ -488,6 +500,28 @@ _nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy) if (b_is_connection && !a_is_connection) return -1; + /* we sort device groups before connection groups (to the end). */ + a_is_device = a && g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); + b_is_device = b && g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); + + if (a_is_device && b_is_device) { + /* if both are device groups, we want the explicit [device] group first. */ + a_is_device = a[NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE)] == '\0'; + b_is_device = b[NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE)] == '\0'; + + if (a_is_device != b_is_device) { + if (a_is_device) + return -1; + return 1; + } + /* the sections are ordered lowest-priority first. Reverse their order. */ + return pa < pb ? 1 : -1; + } + if (a_is_device && !b_is_device) + return 1; + if (b_is_device && !a_is_device) + return -1; + /* no reordering. */ return 0; } @@ -1049,25 +1083,18 @@ global_dns_equal (NMGlobalDnsConfig *old, NMGlobalDnsConfig *new) /************************************************************************/ -char * -nm_config_data_get_connection_default (const NMConfigData *self, - const char *property, - NMDevice *device) +static const MatchSectionInfo * +_match_section_infos_lookup (const MatchSectionInfo *match_section_infos, + GKeyFile *keyfile, + const char *property, + NMDevice *device, + char **out_value) { - NMConfigDataPrivate *priv; - const ConnectionInfo *connection_info; - - g_return_val_if_fail (self, NULL); - g_return_val_if_fail (property && *property, NULL); - g_return_val_if_fail (strchr (property, '.'), NULL); - - priv = NM_CONFIG_DATA_GET_PRIVATE (self); - - if (!priv->connection_infos) + if (!match_section_infos) return NULL; - for (connection_info = &priv->connection_infos[0]; connection_info->group_name; connection_info++) { - char *value; + for (; match_section_infos->group_name; match_section_infos++) { + char *value = NULL; gboolean match; /* FIXME: Here we use g_key_file_get_string(). This should be in sync with what keyfile-reader @@ -1077,23 +1104,87 @@ nm_config_data_get_connection_default (const NMConfigData *self, * string_to_value(keyfile_to_string(keyfile)) in one. Optimally, keyfile library would * expose both functions, and we would return here keyfile_to_string(keyfile). * The caller then could convert the string to the proper value via string_to_value(value). */ - value = g_key_file_get_string (priv->keyfile, connection_info->group_name, property, NULL); - if (!value && !connection_info->stop_match) + value = g_key_file_get_string (keyfile, match_section_infos->group_name, property, NULL); + if (!value && !match_section_infos->stop_match) continue; match = TRUE; - if (connection_info->match_device.has) - match = device && nm_device_spec_match_list (device, connection_info->match_device.spec); + if (match_section_infos->match_device.has) + match = device && nm_device_spec_match_list (device, match_section_infos->match_device.spec); - if (match) - return value; + if (match) { + *out_value = value; + return match_section_infos; + } g_free (value); } return NULL; } +char * +nm_config_data_get_device_config (const NMConfigData *self, + const char *property, + NMDevice *device, + gboolean *has_match) +{ + NMConfigDataPrivate *priv; + const MatchSectionInfo *connection_info; + char *value = NULL; + + g_return_val_if_fail (self, NULL); + g_return_val_if_fail (property && *property, NULL); + + priv = NM_CONFIG_DATA_GET_PRIVATE (self); + + connection_info = _match_section_infos_lookup (&priv->device_infos[0], + priv->keyfile, + property, + device, + &value); + NM_SET_OUT (has_match, !!connection_info); + return value; +} + +gboolean +nm_config_data_get_device_config_boolean (const NMConfigData *self, + const char *property, + NMDevice *device, + gint val_no_match, + gint val_invalid) +{ + gs_free char *value = NULL; + gboolean has_match; + + value = nm_config_data_get_device_config (self, property, device, &has_match); + if (!has_match) + return val_no_match; + return nm_config_parse_boolean (value, val_invalid); +} + +char * +nm_config_data_get_connection_default (const NMConfigData *self, + const char *property, + NMDevice *device) +{ + NMConfigDataPrivate *priv; + char *value = NULL; + + g_return_val_if_fail (self, NULL); + g_return_val_if_fail (property && *property, NULL); + g_return_val_if_fail (strchr (property, '.'), NULL); + + priv = NM_CONFIG_DATA_GET_PRIVATE (self); + + _match_section_infos_lookup (&priv->connection_infos[0], + priv->keyfile, + property, + device, + &value); + return value; +} + static void -_get_connection_info_init (ConnectionInfo *connection_info, GKeyFile *keyfile, char *group) +_get_connection_info_init (MatchSectionInfo *connection_info, GKeyFile *keyfile, char *group) { /* pass ownership of @group on... */ connection_info->group_name = group; @@ -1105,27 +1196,43 @@ _get_connection_info_init (ConnectionInfo *connection_info, GKeyFile *keyfile, c connection_info->stop_match = nm_config_keyfile_get_boolean (keyfile, group, "stop-match", FALSE); } -static ConnectionInfo * -_get_connection_infos (GKeyFile *keyfile) +static void +_match_section_infos_free (MatchSectionInfo *match_section_infos) +{ + guint i; + + if (!match_section_infos) + return; + for (i = 0; match_section_infos[i].group_name; i++) { + g_free (match_section_infos[i].group_name); + g_slist_free_full (match_section_infos[i].match_device.spec, g_free); + } + g_free (match_section_infos); +} + +static MatchSectionInfo * +_match_section_infos_construct (GKeyFile *keyfile, const char *prefix) { char **groups; gsize i, j, ngroups; char *connection_tag = NULL; - ConnectionInfo *connection_infos = NULL; + MatchSectionInfo *match_section_infos = NULL; - /* get the list of existing [connection.\+] sections that we consider - * for nm_config_data_get_connection_default(). + /* get the list of existing [connection.\+]/[device.\+] sections. * * We expect the sections in their right order, with lowest priority * first. Only exception is the (literal) [connection] section, which * we will always reorder to the end. */ groups = g_key_file_get_groups (keyfile, &ngroups); if (!groups) - ngroups = 0; - else if (ngroups > 0) { + return NULL; + + if (ngroups > 0) { + gsize l = strlen (prefix); + for (i = 0, j = 0; i < ngroups; i++) { - if (g_str_has_prefix (groups[i], NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)) { - if (groups[i][NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)] == '\0') + if (g_str_has_prefix (groups[i], prefix)) { + if (groups[i][l] == '\0') connection_tag = groups[i]; else groups[j++] = groups[i]; @@ -1135,18 +1242,23 @@ _get_connection_infos (GKeyFile *keyfile) ngroups = j; } - connection_infos = g_new0 (ConnectionInfo, ngroups + 1 + (connection_tag ? 1 : 0)); + if (ngroups == 0 && !connection_tag) { + g_free (groups); + return NULL; + } + + match_section_infos = g_new0 (MatchSectionInfo, ngroups + 1 + (connection_tag ? 1 : 0)); for (i = 0; i < ngroups; i++) { /* pass ownership of @group on... */ - _get_connection_info_init (&connection_infos[i], keyfile, groups[ngroups - i - 1]); + _get_connection_info_init (&match_section_infos[i], keyfile, groups[ngroups - i - 1]); } if (connection_tag) { /* pass ownership of @connection_tag on... */ - _get_connection_info_init (&connection_infos[i], keyfile, connection_tag); + _get_connection_info_init (&match_section_infos[i], keyfile, connection_tag); } g_free (groups); - return connection_infos; + return match_section_infos; } /************************************************************************/ @@ -1306,7 +1418,6 @@ static void finalize (GObject *gobject) { NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (gobject); - guint i; g_free (priv->config_main_file); g_free (priv->config_description); @@ -1326,13 +1437,8 @@ finalize (GObject *gobject) nm_global_dns_config_free (priv->global_dns); - if (priv->connection_infos) { - for (i = 0; priv->connection_infos[i].group_name; i++) { - g_free (priv->connection_infos[i].group_name); - g_slist_free_full (priv->connection_infos[i].match_device.spec, g_free); - } - g_free (priv->connection_infos); - } + _match_section_infos_free (priv->connection_infos); + _match_section_infos_free (priv->device_infos); g_key_file_unref (priv->keyfile); if (priv->keyfile_user) @@ -1359,7 +1465,8 @@ constructed (GObject *object) priv->keyfile = _merge_keyfiles (priv->keyfile_user, priv->keyfile_intern); - priv->connection_infos = _get_connection_infos (priv->keyfile); + priv->connection_infos = _match_section_infos_construct (priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION); + priv->device_infos = _match_section_infos_construct (priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); priv->connectivity.uri = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", NULL)); priv->connectivity.response = g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "response", NULL); diff --git a/src/nm-config-data.h b/src/nm-config-data.h index e01ad6ea..e63b4590 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -183,6 +183,17 @@ char *nm_config_data_get_connection_default (const NMConfigData *self, const char *property, NMDevice *device); +char *nm_config_data_get_device_config (const NMConfigData *self, + const char *property, + NMDevice *device, + gboolean *has_match); + +gboolean nm_config_data_get_device_config_boolean (const NMConfigData *self, + const char *property, + NMDevice *device, + gint val_no_match, + gint val_invalid); + char **nm_config_data_get_groups (const NMConfigData *self); char **nm_config_data_get_keys (const NMConfigData *self, const char *group); gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const char *group); diff --git a/src/nm-config.c b/src/nm-config.c index 247b9a89..4bc4f483 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -39,12 +39,27 @@ #define DEFAULT_SYSTEM_CONFIG_DIR NMLIBDIR "/conf.d" #define DEFAULT_NO_AUTO_DEFAULT_FILE NMSTATEDIR "/no-auto-default.state" #define DEFAULT_INTERN_CONFIG_FILE NMSTATEDIR "/NetworkManager-intern.conf" +#define DEFAULT_STATE_FILE NMSTATEDIR "/NetworkManager.state" + +/*****************************************************************************/ + +#define _NMLOG_PREFIX_NAME "config" +#define _NMLOG_DOMAIN LOGD_CORE + +#define _NMLOG(level, ...) \ + nm_log (level, _NMLOG_DOMAIN, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ struct NMConfigCmdLineOptions { char *config_main_file; char *intern_config_file; char *config_dir; char *system_config_dir; + char *state_file; char *no_auto_default_file; char *plugins; gboolean configure_and_quit; @@ -59,6 +74,10 @@ struct NMConfigCmdLineOptions { }; typedef struct { + NMConfigState p; +} State; + +typedef struct { NMConfigCmdLineOptions cli; NMConfigData *config_data; @@ -82,6 +101,19 @@ typedef struct { gboolean configure_and_quit; char **atomic_section_prefixes; + + /* The state. This is actually a mutable data member and it makes sense: + * The regular config is immutable (NMConfigData) and can old be swapped + * as a whole (via nm_config_set_values() or during reload). Thus, it can + * be changed, but it is still immutable and is swapped atomically as a + * whole. Also, we emit a config-changed signal on that occasion. + * + * For state, there are no events. You can query it and set it. + * It only gets read *once* at startup, and later is cached and only + * written out to disk. Hence, no need for the immutable dance here + * because the state changes only on explicit actions from the daemon + * itself. */ + State *state; } NMConfigPrivate; enum { @@ -367,7 +399,9 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device) priv = NM_CONFIG_GET_PRIVATE (self); - hw_address = nm_device_get_hw_address (device); + hw_address = nm_device_get_permanent_hw_address (device, FALSE); + if (!hw_address) + return; no_auto_default_current = nm_config_data_get_no_auto_default (priv->config_data); @@ -407,6 +441,7 @@ _nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli) g_clear_pointer (&cli->system_config_dir, g_free); g_clear_pointer (&cli->no_auto_default_file, g_free); g_clear_pointer (&cli->intern_config_file, g_free); + g_clear_pointer (&cli->state_file, g_free); g_clear_pointer (&cli->plugins, g_free); cli->configure_and_quit = FALSE; cli->is_debug = FALSE; @@ -428,6 +463,7 @@ _nm_config_cmd_line_options_copy (const NMConfigCmdLineOptions *cli, NMConfigCmd dst->config_main_file = g_strdup (cli->config_main_file); dst->no_auto_default_file = g_strdup (cli->no_auto_default_file); dst->intern_config_file = g_strdup (cli->intern_config_file); + dst->state_file = g_strdup (cli->state_file); dst->plugins = g_strdup (cli->plugins); dst->configure_and_quit = cli->configure_and_quit; dst->is_debug = cli->is_debug; @@ -467,6 +503,7 @@ nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli, { "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_dir, N_("Config directory location"), N_(DEFAULT_CONFIG_DIR) }, { "system-config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->system_config_dir, N_("System config directory location"), N_(DEFAULT_SYSTEM_CONFIG_DIR) }, { "intern-config", 0, 0, G_OPTION_ARG_FILENAME, &cli->intern_config_file, N_("Internal config file location"), N_(DEFAULT_INTERN_CONFIG_FILE) }, + { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &cli->state_file, N_("State file location"), N_(DEFAULT_STATE_FILE) }, { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, N_("State file for no-auto-default devices"), N_(DEFAULT_NO_AUTO_DEFAULT_FILE) }, { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), N_(CONFIG_PLUGINS_DEFAULT) }, { "configure-and-quit", 0, 0, G_OPTION_ARG_NONE, &cli->configure_and_quit, N_("Quit after initial configuration"), NULL }, @@ -541,14 +578,7 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy) { const char *a, *b; gboolean a_is_connection, b_is_connection; - - /* basic NULL checking... */ - if (pa == pb) - return 0; - if (!pa) - return -1; - if (!pb) - return 1; + gboolean a_is_device, b_is_device; a = *pa; b = *pb; @@ -563,16 +593,34 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy) return 1; return -1; } - if (!a_is_connection) { - /* both are non-connection entries. Don't reorder. */ - return 0; + if (a_is_connection) { + /* both are [connection.\+] entires. Reverse their order. + * One of the sections might be literally [connection]. That section + * is special and it's order will be fixed later. It doesn't actually + * matter here how it compares with [connection.\+] sections. */ + return pa > pb ? -1 : 1; } - /* both are [connection.\+] entires. Reverse their order. - * One of the sections might be literally [connection]. That section - * is special and it's order will be fixed later. It doesn't actually - * matter here how it compares with [connection.\+] sections. */ - return pa > pb ? -1 : 1; + a_is_device = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); + b_is_device = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); + + if (a_is_device != b_is_device) { + /* one is a [device*] entry, the other not. We sort [device*] entires + * after. */ + if (a_is_device) + return 1; + return -1; + } + if (a_is_device) { + /* both are [device.\+] entires. Reverse their order. + * One of the sections might be literally [device]. That section + * is special and it's order will be fixed later. It doesn't actually + * matter here how it compares with [device.\+] sections. */ + return pa > pb ? -1 : 1; + } + + /* don't reorder the rest. */ + return 0; } void @@ -595,7 +643,8 @@ _setting_is_device_spec (const char *group, const char *key) || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier") || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only") || _IS (NM_CONFIG_KEYFILE_GROUP_KEYFILE, "unmanaged-devices") - || (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && !strcmp (key, "match-device")); + || (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && !strcmp (key, "match-device")) + || (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE ) && !strcmp (key, "match-device")); } static gboolean @@ -845,15 +894,6 @@ read_base_config (GKeyFile *keyfile, return TRUE; } -static int -sort_asciibetically (gconstpointer a, gconstpointer b) -{ - const char *s1 = *(const char **)a; - const char *s2 = *(const char **)b; - - return strcmp (s1, s2); -} - static GPtrArray * _get_config_dir_files (const char *config_dir) { @@ -882,7 +922,7 @@ _get_config_dir_files (const char *config_dir) } g_object_unref (dir); - g_ptr_array_sort (confs, sort_asciibetically); + g_ptr_array_sort (confs, nm_strcmp_p); return confs; } @@ -1645,7 +1685,190 @@ nm_config_set_values (NMConfig *self, g_key_file_unref (keyfile_new); } -/************************************************************************/ +/****************************************************************************** + * State + ******************************************************************************/ + +static const char * +state_get_filename (const NMConfigCmdLineOptions *cli) +{ + /* For an empty filename, we assume the user wants to disable + * state. NMConfig will not try to read it nor write it out. */ + if (!cli->state_file) + return DEFAULT_STATE_FILE; + return cli->state_file[0] ? cli->state_file : NULL; +} + +static State * +state_new (void) +{ + State *state; + + state = g_slice_new0 (State); + state->p.net_enabled = TRUE; + state->p.wifi_enabled = TRUE; + state->p.wwan_enabled = TRUE; + + return state; +} + +static void +state_free (State *state) +{ + if (!state) + return; + g_slice_free (State, state); +} + +static State * +state_new_from_file (const char *filename) +{ + GKeyFile *keyfile; + gs_free_error GError *error = NULL; + State *state; + + state = state_new (); + + if (!filename) + return state; + + keyfile = g_key_file_new (); + g_key_file_set_list_separator (keyfile, ','); + if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error)) { + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + _LOGD ("state: missing state file \"%s\": %s", filename, error->message); + else + _LOGW ("state: error reading state file \"%s\": %s", filename, error->message); + goto out; + } + + _LOGD ("state: successfully read state file \"%s\"", filename); + + state->p.net_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "NetworkingEnabled", state->p.net_enabled); + state->p.wifi_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "WirelessEnabled", state->p.wifi_enabled); + state->p.wwan_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "WWANEnabled", state->p.wwan_enabled); + +out: + g_key_file_unref (keyfile); + return state; +} + +const NMConfigState * +nm_config_state_get (NMConfig *self) +{ + NMConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_CONFIG (self), NULL); + + priv = NM_CONFIG_GET_PRIVATE (self); + + if (G_UNLIKELY (!priv->state)) { + /* read the state from file lazy on first access. The reason is that + * we want to log a failure to read the file via nm-logging. + * + * So we cannot read the state during construction of NMConfig, + * because at that time nm-logging is not yet configured. + */ + priv->state = state_new_from_file (state_get_filename (&priv->cli)); + } + + return &priv->state->p; +} + +static void +state_write (NMConfig *self) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self); + const char *filename; + GString *str; + GError *error = NULL; + + filename = state_get_filename (&priv->cli); + + if (!filename) { + priv->state->p.dirty = FALSE; + return; + } + + str = g_string_sized_new (256); + + /* Let's construct the keyfile data by hand. */ + + g_string_append (str, "[main]\n"); + g_string_append_printf (str, "NetworkingEnabled=%s\n", priv->state->p.net_enabled ? "true" : "false"); + g_string_append_printf (str, "WirelessEnabled=%s\n", priv->state->p.wifi_enabled ? "true" : "false"); + g_string_append_printf (str, "WWANEnabled=%s\n", priv->state->p.wwan_enabled ? "true" : "false"); + + if (!g_file_set_contents (filename, + str->str, str->len, + &error)) { + _LOGD ("state: error writing state file \"%s\": %s", filename, error->message); + g_clear_error (&error); + /* we leave the state dirty. That potentally means, that we try to + * write the file over and over again, although it isn't possible. */ + priv->state->p.dirty = TRUE; + } else + priv->state->p.dirty = FALSE; + + _LOGT ("state: success writing state file \"%s\"", filename); + + g_string_free (str, TRUE); +} + +void +_nm_config_state_set (NMConfig *self, + gboolean allow_persist, + gboolean force_persist, + ...) +{ + NMConfigPrivate *priv; + va_list ap; + NMConfigRunStatePropertyType property_type; + + g_return_if_fail (NM_IS_CONFIG (self)); + + priv = NM_CONFIG_GET_PRIVATE (self); + + va_start (ap, force_persist); + + /* We expect that the NMConfigRunStatePropertyType is an integer type <= sizeof (int). + * Smaller would be fine, since the variadic arguments get promoted to int. + * Larger would be a problem, also, because we want that "0" is a valid sentinel. */ + G_STATIC_ASSERT_EXPR (sizeof (NMConfigRunStatePropertyType) <= sizeof (int)); + + while ((property_type = va_arg (ap, int)) != NM_CONFIG_STATE_PROPERTY_NONE) { + bool *p_bool, v_bool; + + switch (property_type) { + case NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED: + p_bool = &priv->state->p.net_enabled; + break; + case NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED: + p_bool = &priv->state->p.wifi_enabled; + break; + case NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED: + p_bool = &priv->state->p.wwan_enabled; + break; + default: + va_end (ap); + g_return_if_reached (); + } + + v_bool = va_arg (ap, gboolean); + if (*p_bool == v_bool) + continue; + *p_bool = v_bool; + priv->state->p.dirty = TRUE; + } + + va_end (ap); + + if ( allow_persist + && (force_persist || priv->state->p.dirty)) + state_write (self); +} + +/*****************************************************************************/ void nm_config_reload (NMConfig *self, NMConfigChangeFlags reload_flags) @@ -1929,6 +2152,8 @@ finalize (GObject *gobject) { NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject); + state_free (priv->state); + g_free (priv->config_dir); g_free (priv->system_config_dir); g_free (priv->no_auto_default_file); diff --git a/src/nm-config.h b/src/nm-config.h index 9a153e48..a75e3935 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -45,6 +45,7 @@ #define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern." #define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection" +#define NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "device" #define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-" #define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist" @@ -69,6 +70,8 @@ #define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed" #define NM_CONFIG_KEYFILE_KEY_AUDIT "audit" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier" + #define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was." #define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set." @@ -79,6 +82,24 @@ typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions; +typedef enum { + NM_CONFIG_STATE_PROPERTY_NONE, + + /* 1 set-argument: (gboolean enabled) */ + NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, + NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED, + NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED, +} NMConfigRunStatePropertyType; + +typedef struct { + bool net_enabled; + bool wifi_enabled; + bool wwan_enabled; + + /* Whether the runstate is modified and not saved to disk. */ + bool dirty; +} NMConfigState; + struct _NMConfig { GObject parent; }; @@ -127,6 +148,15 @@ NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, char **atomic_sectio NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, char **atomic_section_prefixes, GError **error); void nm_config_reload (NMConfig *config, NMConfigChangeFlags reload_flags); +const NMConfigState *nm_config_state_get (NMConfig *config); + +void _nm_config_state_set (NMConfig *config, + gboolean allow_persist, + gboolean force_persist, + ...); +#define nm_config_state_set(config, allow_persist, force_persist, ...) \ + _nm_config_state_set (config, allow_persist, force_persist, ##__VA_ARGS__, 0) + gint nm_config_parse_boolean (const char *str, gint default_value); GKeyFile *nm_config_create_keyfile (void); diff --git a/src/nm-connection-provider.c b/src/nm-connection-provider.c deleted file mode 100644 index e04cab92..00000000 --- a/src/nm-connection-provider.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details: - * - * Copyright (C) 2012 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-connection-provider.h" -#include "nm-utils.h" - -G_DEFINE_INTERFACE (NMConnectionProvider, nm_connection_provider, G_TYPE_OBJECT) - -GSList * -nm_connection_provider_get_best_connections (NMConnectionProvider *self, - guint max_requested, - const char *ctype1, - const char *ctype2, - NMConnectionFilterFunc func, - gpointer func_data) -{ - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL); - - if (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections) - return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections (self, max_requested, ctype1, ctype2, func, func_data); - return NULL; -} - -const GSList * -nm_connection_provider_get_connections (NMConnectionProvider *self) -{ - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL); - - if (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connections) - return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connections (self); - return NULL; -} - -/** - * nm_connection_provider_add_connection: - * @self: the #NMConnectionProvider - * @connection: the source connection to create a new #NMSettingsConnection from - * @save_to_disk: %TRUE to save the connection to disk immediately, %FALSE to - * not save to disk - * @error: on return, a location to store any errors that may occur - * - * Creates a new #NMSettingsConnection for the given source @connection. - * The plugin owns the returned object and the caller must reference the object - * to continue using it. - * - * Returns: the new #NMSettingsConnection or %NULL - */ -NMConnection * -nm_connection_provider_add_connection (NMConnectionProvider *self, - NMConnection *connection, - gboolean save_to_disk, - GError **error) -{ - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL); - - g_assert (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->add_connection); - return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->add_connection (self, connection, save_to_disk, error); -} - -/** - * nm_connection_provider_get_connection_by_uuid: - * @self: the #NMConnectionProvider - * @uuid: the UUID to search for - * - * Returns: the connection with the given @uuid, or %NULL - */ -NMConnection * -nm_connection_provider_get_connection_by_uuid (NMConnectionProvider *self, - const char *uuid) -{ - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL); - g_return_val_if_fail (uuid != NULL, NULL); - g_return_val_if_fail (nm_utils_is_uuid (uuid), NULL); - - g_assert (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connection_by_uuid); - return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connection_by_uuid (self, uuid); -} - -/*****************************************************************************/ - -static void -nm_connection_provider_default_init (NMConnectionProviderInterface *g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - initialized = TRUE; - - /* Signals */ - g_signal_new (NM_CP_SIGNAL_CONNECTION_ADDED, - iface_type, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - g_signal_new (NM_CP_SIGNAL_CONNECTION_UPDATED, - iface_type, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - g_signal_new (NM_CP_SIGNAL_CONNECTION_REMOVED, - iface_type, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); -} diff --git a/src/nm-connection-provider.h b/src/nm-connection-provider.h deleted file mode 100644 index b31af05f..00000000 --- a/src/nm-connection-provider.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details: - * - * Copyright (C) 2012 Red Hat, Inc. - */ - -#ifndef __NETWORKMANAGER_CONNECTION_PROVIDER_H__ -#define __NETWORKMANAGER_CONNECTION_PROVIDER_H__ - -#include <nm-connection.h> - -#include "nm-default.h" - -#define NM_TYPE_CONNECTION_PROVIDER (nm_connection_provider_get_type ()) -#define NM_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProvider)) -#define NM_IS_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_PROVIDER)) -#define NM_CONNECTION_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProviderInterface)) - -#define NM_CP_SIGNAL_CONNECTION_ADDED "cp-connection-added" -#define NM_CP_SIGNAL_CONNECTION_UPDATED "cp-connection-updated" -#define NM_CP_SIGNAL_CONNECTION_REMOVED "cp-connection-removed" - - -/** - * NMConnectionFilterFunc: - * @provider: The provider requesting the filtering - * @connection: the connection to be filtered - * @func_data: the caller-provided data pointer - * - * Returns: %TRUE to allow the connection, %FALSE to ignore it - */ -typedef gboolean (*NMConnectionFilterFunc) (NMConnectionProvider *provider, - NMConnection *connection, - gpointer func_data); - - -typedef struct { - GTypeInterface g_iface; - - /* Methods */ - GSList * (*get_best_connections) (NMConnectionProvider *self, - guint max_requested, - const char *ctype1, - const char *ctype2, - NMConnectionFilterFunc func, - gpointer func_data); - - const GSList * (*get_connections) (NMConnectionProvider *self); - - NMConnection * (*add_connection) (NMConnectionProvider *self, - NMConnection *connection, - gboolean save_to_disk, - GError **error); - - NMConnection * (*get_connection_by_uuid) (NMConnectionProvider *self, - const char *uuid); -} NMConnectionProviderInterface; - -GType nm_connection_provider_get_type (void); - -/** - * nm_connection_provider_get: - * - * Returns: the global #NMConnectionProvider - */ -NMConnectionProvider *nm_connection_provider_get (void); - -/** - * nm_connection_provider_get_best_connections: - * @self: the #NMConnectionProvider - * @max_requested: if non-zero, the maximum number of connections to return - * @ctype1: an #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) to - * filter connections against - * @ctype2: a second #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) - * to filter connections against - * @func: caller-supplied function for filtering connections - * @func_data: caller-supplied data passed to @func - * - * Returns: a #GSList of #NMConnection objects in sorted order representing the - * "best" or highest-priority connections filtered by @ctype1 and/or @ctype2, - * and/or @func. Caller is responsible for freeing the returned #GSList, but - * the contained values do not need to be unreffed. - */ -GSList *nm_connection_provider_get_best_connections (NMConnectionProvider *self, - guint max_requested, - const char *ctype1, - const char *ctype2, - NMConnectionFilterFunc func, - gpointer func_data); - -/** - * nm_connection_provider_get_connections: - * @self: the #NMConnectionProvider - * - * Returns: a #GSList of #NMConnection objects representing all known - * connections. Returned list is owned by the connection provider and must - * not be freed. - */ -const GSList *nm_connection_provider_get_connections (NMConnectionProvider *self); - -/** - * nm_connection_provider_add_connection: - * @self: the #NMConnectionProvider - * @connection: the connection to be added - * @save_to_disk: whether to store the connection on disk - * @error: returns any error if adding fails - * - * returns: a newly added #NMConnection. - */ -NMConnection *nm_connection_provider_add_connection (NMConnectionProvider *self, - NMConnection *connection, - gboolean save_to_disk, - GError **error); - -NMConnection *nm_connection_provider_get_connection_by_uuid (NMConnectionProvider *self, - const char *uuid); - -#endif /* __NETWORKMANAGER_CONNECTION_PROVIDER_H__ */ diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index 934727fa..7cf3e707 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -28,6 +28,7 @@ #include "nm-connectivity.h" #include "nm-config.h" +#include "nm-dispatcher.h" #include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMConnectivity, nm_connectivity, G_TYPE_OBJECT) @@ -96,6 +97,9 @@ update_state (NMConnectivity *self, NMConnectivityState state) nm_connectivity_state_to_string (state)); priv->state = state; g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE); + + /* Notify dispatcher scripts of a connectivity state change */ + nm_dispatcher_call_connectivity (DISPATCHER_ACTION_CONNECTIVITY_CHANGE, state); } } diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h index f037403c..10fcef97 100644 --- a/src/nm-connectivity.h +++ b/src/nm-connectivity.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_CONNECTIVITY_H__ #define __NETWORKMANAGER_CONNECTIVITY_H__ - -#include "nm-default.h" #include "nm-dbus-interface.h" #define NM_TYPE_CONNECTIVITY (nm_connectivity_get_type ()) diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index e9365c0c..6dfbb4ce 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -26,6 +26,7 @@ #include <errno.h> #include <fcntl.h> #include <string.h> +#include <poll.h> #include <unistd.h> #include <stdlib.h> #include <resolv.h> @@ -54,7 +55,7 @@ #endif G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int)); -int _nm_utils_testing = 0; +static int _nm_utils_testing = 0; gboolean nm_utils_get_testing_initialized () @@ -199,6 +200,27 @@ nm_ethernet_address_is_valid (gconstpointer addr, gssize len) return TRUE; } +gconstpointer +nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen) +{ + g_return_val_if_fail (src, NULL); + g_return_val_if_fail (dst, NULL); + + switch (family) { + case AF_INET: + g_return_val_if_fail (plen <= 32, NULL); + *((guint32 *) dst) = nm_utils_ip4_address_clear_host_address (*((guint32 *) src), plen); + break; + case AF_INET6: + g_return_val_if_fail (plen <= 128, NULL); + nm_utils_ip6_address_clear_host_address (dst, src, plen); + break; + default: + g_return_val_if_reached (NULL); + } + return dst; +} + /* nm_utils_ip4_address_clear_host_address: * @addr: source ip6 address * @plen: prefix length of network @@ -445,8 +467,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) gs_strfreev gchar **tokens = NULL; guint num_tokens; gchar *p; - gchar *endp; - char state = '\0'; + char state = ' '; gint64 ppid = 0; start_time = 0; @@ -457,7 +478,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) nm_sprintf_buf (filename, "/proc/%"G_GUINT64_FORMAT"/stat", (guint64) pid); if (!g_file_get_contents (filename, &contents, &length, NULL)) - goto out; + goto fail; /* start time is the token at index 19 after the '(process name)' entry - since only this * field can contain the ')' character, search backwards for this to avoid malicious @@ -465,10 +486,10 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) */ p = strrchr (contents, ')'); if (p == NULL) - goto out; + goto fail; p += 2; /* skip ') ' */ if (p - contents >= (int) length) - goto out; + goto fail; state = p[0]; @@ -477,23 +498,26 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) num_tokens = g_strv_length (tokens); if (num_tokens < 20) - goto out; + goto fail; - if (out_ppid) + if (out_ppid) { ppid = _nm_utils_ascii_str_to_int64 (tokens[1], 10, 1, G_MAXINT, 0); + if (ppid == 0) + goto fail; + } - errno = 0; - start_time = strtoull (tokens[19], &endp, 10); - if (*endp != '\0' || errno != 0) - start_time = 0; - -out: - if (out_state) - *out_state = state; - if (out_ppid) - *out_ppid = ppid; + start_time = _nm_utils_ascii_str_to_int64 (tokens[19], 10, 1, G_MAXINT64, 0); + if (start_time == 0) + goto fail; + NM_SET_OUT (out_state, state); + NM_SET_OUT (out_ppid, ppid); return start_time; + +fail: + NM_SET_OUT (out_state, ' '); + NM_SET_OUT (out_ppid, 0); + return 0; } /******************************************************************************************/ @@ -1248,8 +1272,10 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) { const GSList *iter; NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH; + guint hwaddr_len = 0; + guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX]; - g_return_val_if_fail (hwaddr != NULL, NM_MATCH_SPEC_NO_MATCH); + nm_assert (nm_utils_hwaddr_valid (hwaddr, -1)); for (iter = specs; iter; iter = g_slist_next (iter)) { const char *spec_str = iter->data; @@ -1270,7 +1296,15 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) else if (except) continue; - if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr, -1)) { + if (G_UNLIKELY (hwaddr_len == 0)) { + hwaddr_len = _nm_utils_hwaddr_length (hwaddr); + if (!hwaddr_len) + g_return_val_if_reached (NM_MATCH_SPEC_NO_MATCH); + if (!nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, hwaddr_len)) + nm_assert_not_reached (); + } + + if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len)) { if (except) return NM_MATCH_SPEC_NEG_MATCH; match = NM_MATCH_SPEC_MATCH; @@ -1900,6 +1934,33 @@ nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id) return ifname; } +/* nm_utils_new_infiniband_name: + * @name: the output-buffer where the value will be written. Must be + * not %NULL and point to a string buffer of at least IFNAMSIZ bytes. + * @parent_name: the parent interface name + * @p_key: the partition key. + * + * Returns: the infiniband name will be written to @name and @name + * is returned. + */ +const char * +nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key) +{ + g_return_val_if_fail (name, NULL); + g_return_val_if_fail (parent_name && parent_name[0], NULL); + g_return_val_if_fail (strlen (parent_name) < IFNAMSIZ, NULL); + + /* technically, p_key of 0x0000 and 0x8000 is not allowed either. But we don't + * want to assert against that in nm_utils_new_infiniband_name(). So be more + * resilient here, and accept those. */ + g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NULL); + + /* If parent+suffix is too long, kernel would just truncate + * the name. We do the same. See ipoib_vlan_add(). */ + g_snprintf (name, IFNAMSIZ, "%s.%04x", parent_name, p_key); + return name; +} + /** * nm_utils_read_resolv_conf_nameservers(): * @rc_contents: contents of a resolv.conf; or %NULL to read /etc/resolv.conf @@ -2651,6 +2712,123 @@ nm_utils_machine_id_read (void) /*****************************************************************************/ +/* taken from systemd's fd_wait_for_event(). Note that the timeout + * is here in nano-seconds, not micro-seconds. */ +int +nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns) +{ + struct pollfd pollfd = { + .fd = fd, + .events = event, + }; + struct timespec ts, *pts; + int r; + + if (timeout_ns < 0) + pts = NULL; + else { + ts.tv_sec = (time_t) (timeout_ns / NM_UTILS_NS_PER_SECOND); + ts.tv_nsec = (long int) (timeout_ns % NM_UTILS_NS_PER_SECOND); + pts = &ts; + } + + r = ppoll (&pollfd, 1, pts, NULL); + if (r < 0) + return -errno; + if (r == 0) + return 0; + return pollfd.revents; +} + +/* taken from systemd's loop_read() */ +ssize_t +nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll) +{ + uint8_t *p = buf; + ssize_t n = 0; + + g_return_val_if_fail (fd >= 0, -EINVAL); + g_return_val_if_fail (buf, -EINVAL); + + /* If called with nbytes == 0, let's call read() at least + * once, to validate the operation */ + + if (nbytes > (size_t) SSIZE_MAX) + return -EINVAL; + + do { + ssize_t k; + + k = read (fd, p, nbytes); + if (k < 0) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN && do_poll) { + + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via read() */ + + (void) nm_utils_fd_wait_for_event (fd, POLLIN, -1); + continue; + } + + return n > 0 ? n : -errno; + } + + if (k == 0) + return n; + + g_assert ((size_t) k <= nbytes); + + p += k; + nbytes -= k; + n += k; + } while (nbytes > 0); + + return n; +} + +/* taken from systemd's loop_read_exact() */ +int +nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll) +{ + ssize_t n; + + n = nm_utils_fd_read_loop (fd, buf, nbytes, do_poll); + if (n < 0) + return (int) n; + if ((size_t) n != nbytes) + return -EIO; + + return 0; +} + +/* taken from systemd's dev_urandom(). */ +int +nm_utils_read_urandom (void *p, size_t nbytes) +{ + int fd = -1; + int r; + +again: + fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + r = errno; + if (r == EINTR) + goto again; + return r == ENOENT ? -ENOSYS : -r; + } + + r = nm_utils_fd_read_loop_exact (fd, p, nbytes, TRUE); + close (fd); + + return r; +} + +/*****************************************************************************/ + guint8 * nm_utils_secret_key_read (gsize *out_key_len, GError **error) { @@ -2669,34 +2847,28 @@ nm_utils_secret_key_read (gsize *out_key_len, GError **error) key_len = 0; } } else { - int urandom = open ("/dev/urandom", O_RDONLY); + int r; mode_t key_mask; - if (urandom == -1) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Can't open /dev/urandom: %s", strerror (errno)); - key_len = 0; - goto out; - } - /* RFC7217 mandates the key SHOULD be at least 128 bits. * Let's use twice as much. */ key_len = 32; secret_key = g_malloc (key_len); + r = nm_utils_read_urandom (secret_key, key_len); + if (r < 0) { + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "Can't read /dev/urandom: %s", strerror (-r)); + key_len = 0; + goto out; + } + key_mask = umask (0077); - if (read (urandom, secret_key, key_len) == key_len) { - if (!g_file_set_contents (NMSTATEDIR "/secret_key", (char *) secret_key, key_len, error)) { - g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: "); - key_len = 0; - } - } else { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Could not obtain a secret"); + if (!g_file_set_contents (NMSTATEDIR "/secret_key", (char *) secret_key, key_len, error)) { + g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: "); key_len = 0; } umask (key_mask); - close (urandom); } out: @@ -2816,24 +2988,97 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, } return FALSE; } + +/*****************************************************************************/ + +/** + * nm_utils_ipv6_addr_set_interface_identifier: + * @addr: output token encoded as %in6_addr + * @iid: %NMUtilsIPv6IfaceId interface identifier + * + * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use + * with Linux platform). This only copies the lower 8 bytes, ignoring + * the /64 network prefix which is expected to be all-zero for a valid + * token. + */ void -nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, +nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr, const NMUtilsIPv6IfaceId iid) { memcpy (addr->s6_addr + 8, &iid.id_u8, 8); } +/** + * nm_utils_ipv6_interface_identifier_get_from_addr: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @addr: token encoded as %in6_addr + * + * Converts the %in6_addr encoded token (as used by Linux platform) to + * the interface identifier. + */ void -nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, +nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid, const struct in6_addr *addr) { memcpy (iid, addr->s6_addr + 8, 8); } +/** + * nm_utils_ipv6_interface_identifier_get_from_token: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @token: token encoded as string + * + * Converts the %in6_addr encoded token (as used in ip6 settings) to + * the interface identifier. + * + * Returns: %TRUE if the @token is a valid token, %FALSE otherwise + */ +gboolean +nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid, + const char *token) +{ + struct in6_addr i6_token; + + g_return_val_if_fail (token, FALSE); + + if (!inet_pton (AF_INET6, token, &i6_token)) + return FALSE; + + if (!_nm_utils_inet6_is_token (&i6_token)) + return FALSE; + + nm_utils_ipv6_interface_identifier_get_from_addr (iid, &i6_token); + return TRUE; +} + +/** + * nm_utils_inet6_interface_identifier_to_token: + * @iid: %NMUtilsIPv6IfaceId interface identifier + * @buf: the destination buffer or %NULL + * + * Converts the interface identifier to a string token. + * If the destination buffer it set, set it is used to store the + * resulting token, otherwise an internal static buffer is used. + * The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long. + * + * Returns: a statically allocated array. Do not g_free(). + */ +const char * +nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf) +{ + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, iid); + return nm_utils_inet6_ntop (&i6_token, buf); +} + +/*****************************************************************************/ + static gboolean -_set_stable_privacy (struct in6_addr *addr, +_set_stable_privacy (guint8 stable_type, + struct in6_addr *addr, const char *ifname, - const char *uuid, + const char *network_id, guint dad_counter, guint8 *secret_key, gsize key_len, @@ -2857,11 +3102,24 @@ _set_stable_privacy (struct in6_addr *addr, key_len = MIN (key_len, G_MAXUINT32); + if (stable_type != NM_UTILS_STABLE_TYPE_UUID) { + /* Preferably, we would always like to include the stable-type, + * but for backward compatibility reasons, we cannot for UUID. + * + * That is no real problem and it is still impossible to + * force a collision here, because of how the remaining + * fields are hashed. That is, as we also hash @key_len + * and the terminating '\0' of @network_id, it is unambigiously + * possible to revert the process and deduce the @stable_type. + */ + g_checksum_update (sum, &stable_type, sizeof (stable_type)); + } + g_checksum_update (sum, addr->s6_addr, 8); g_checksum_update (sum, (const guchar *) ifname, strlen (ifname) + 1); - if (!uuid) - uuid = ""; - g_checksum_update (sum, (const guchar *) uuid, strlen (uuid) + 1); + if (!network_id) + network_id = ""; + g_checksum_update (sum, (const guchar *) network_id, strlen (network_id) + 1); tmp[0] = htonl (dad_counter); tmp[1] = htonl (key_len); g_checksum_update (sum, (const guchar *) tmp, sizeof (tmp)); @@ -2887,15 +3145,20 @@ _set_stable_privacy (struct in6_addr *addr, * Returns: %TRUE on success, %FALSE if the address could not be generated. */ gboolean -nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, +nm_utils_ipv6_addr_set_stable_privacy (NMUtilsStableType stable_type, + struct in6_addr *addr, const char *ifname, - const char *uuid, + const char *network_id, guint dad_counter, GError **error) { gs_free guint8 *secret_key = NULL; gsize key_len = 0; + nm_assert (NM_IN_SET (stable_type, + NM_UTILS_STABLE_TYPE_UUID, + NM_UTILS_STABLE_TYPE_STABLE_ID)); + if (dad_counter >= RFC7217_IDGEN_RETRIES) { g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "Too many DAD collisions"); @@ -2906,10 +3169,151 @@ nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, if (!secret_key) return FALSE; - return _set_stable_privacy (addr, ifname, uuid, dad_counter, + return _set_stable_privacy (stable_type, addr, ifname, network_id, dad_counter, secret_key, key_len, error); } +/*****************************************************************************/ + +static void +_hw_addr_eth_complete (struct ether_addr *addr, + const char *current_mac_address, + const char *generate_mac_address_mask) +{ + struct ether_addr mask; + struct ether_addr oui; + struct ether_addr *ouis; + gsize ouis_len; + guint i; + + /* the second LSB of the first octet means + * "globally unique, OUI enforced, BIA (burned-in-address)" + * vs. "locally-administered". By default, set it to + * generate locally-administered addresses. + * + * Maybe be overwritten by a mask below. */ + addr->ether_addr_octet[0] |= 2; + + if (!generate_mac_address_mask || !*generate_mac_address_mask) + goto out; + if (!_nm_utils_generate_mac_address_mask_parse (generate_mac_address_mask, + &mask, + &ouis, + &ouis_len, + NULL)) + goto out; + + nm_assert ((ouis == NULL) ^ (ouis_len != 0)); + if (ouis) { + /* g_random_int() is good enough here. It uses a static GRand instance + * that is seeded from /dev/urandom. */ + oui = ouis[g_random_int () % ouis_len]; + g_free (ouis); + } else { + if (!nm_utils_hwaddr_aton (current_mac_address, &oui, ETH_ALEN)) + goto out; + } + + for (i = 0; i < ETH_ALEN; i++) { + const guint8 a = addr->ether_addr_octet[i]; + const guint8 o = oui.ether_addr_octet[i]; + const guint8 m = mask.ether_addr_octet[i]; + + addr->ether_addr_octet[i] = (a & ~m) | (o & m); + } + +out: + /* The LSB of the first octet must always be cleared, + * it means Unicast vs. Multicast */ + addr->ether_addr_octet[0] &= ~1; +} + +char * +nm_utils_hw_addr_gen_random_eth (const char *current_mac_address, + const char *generate_mac_address_mask) +{ + struct ether_addr bin_addr; + + if (nm_utils_read_urandom (&bin_addr, ETH_ALEN) < 0) + return NULL; + _hw_addr_eth_complete (&bin_addr, current_mac_address, generate_mac_address_mask); + return nm_utils_hwaddr_ntoa (&bin_addr, ETH_ALEN); +} + +static char * +_hw_addr_gen_stable_eth (NMUtilsStableType stable_type, + const char *stable_id, + const guint8 *secret_key, + gsize key_len, + const char *ifname, + const char *current_mac_address, + const char *generate_mac_address_mask) +{ + GChecksum *sum; + guint32 tmp; + guint8 digest[32]; + gsize len = sizeof (digest); + struct ether_addr bin_addr; + guint8 stable_type_uint8; + + nm_assert (stable_id); + nm_assert (NM_IN_SET (stable_type, + NM_UTILS_STABLE_TYPE_UUID, + NM_UTILS_STABLE_TYPE_STABLE_ID)); + nm_assert (secret_key); + + sum = g_checksum_new (G_CHECKSUM_SHA256); + if (!sum) + return NULL; + + key_len = MIN (key_len, G_MAXUINT32); + + stable_type_uint8 = stable_type; + g_checksum_update (sum, (const guchar *) &stable_type_uint8, sizeof (stable_type_uint8)); + + tmp = htonl ((guint32) key_len); + g_checksum_update (sum, (const guchar *) &tmp, sizeof (tmp)); + g_checksum_update (sum, (const guchar *) secret_key, key_len); + g_checksum_update (sum, (const guchar *) (ifname ?: ""), ifname ? (strlen (ifname) + 1) : 1); + g_checksum_update (sum, (const guchar *) stable_id, strlen (stable_id) + 1); + + g_checksum_get_digest (sum, digest, &len); + g_checksum_free (sum); + + g_return_val_if_fail (len == 32, NULL); + + memcpy (&bin_addr, digest, ETH_ALEN); + _hw_addr_eth_complete (&bin_addr, current_mac_address, generate_mac_address_mask); + return nm_utils_hwaddr_ntoa (&bin_addr, ETH_ALEN); +} + +char * +nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type, + const char *stable_id, + const char *ifname, + const char *current_mac_address, + const char *generate_mac_address_mask) +{ + gs_free guint8 *secret_key = NULL; + gsize key_len = 0; + + g_return_val_if_fail (stable_id, NULL); + + secret_key = nm_utils_secret_key_read (&key_len, NULL); + if (!secret_key) + return NULL; + + return _hw_addr_gen_stable_eth (stable_type, + stable_id, + secret_key, + key_len, + ifname, + current_mac_address, + generate_mac_address_mask); +} + +/*****************************************************************************/ + /** * nm_utils_setpgid: * @unused: unused @@ -3120,12 +3524,11 @@ nm_utils_lifetime_get (guint32 timestamp, } const char * -nm_utils_dnsmasq_status_to_string (int status, char *dest, guint size) +nm_utils_dnsmasq_status_to_string (int status, char *dest, gsize size) { - static char buffer[128]; - char *msg, *ret; - gs_free char *msg_free = NULL; - int len; + const char *msg; + + nm_utils_to_string_buffer_init (&dest, &size); if (status == 0) msg = "Success"; @@ -3139,22 +3542,15 @@ nm_utils_dnsmasq_status_to_string (int status, char *dest, guint size) msg = "Memory allocation failure"; else if (status == 5) msg = "Other problem"; - else if (status >= 11) - msg = msg_free = g_strdup_printf ("Lease script failed with error %d", status - 10); + else if (status >= 11) { + g_snprintf (dest, size, "Lease script failed with error %d", status - 10); + return dest; + } else msg = "Unknown problem"; - if (dest) { - ret = dest; - len = size; - } else { - ret = buffer; - len = sizeof (buffer); - } - - g_snprintf (ret, len, "%s (%d)", msg, status); - - return ret; + g_snprintf (dest, size, "%s (%d)", msg, status); + return dest; } /** diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index a1213d2a..3ef960bb 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -25,7 +25,6 @@ #include <stdio.h> #include <arpa/inet.h> -#include "nm-default.h" #include "nm-connection.h" /*****************************************************************************/ @@ -93,6 +92,7 @@ GETTER (void) \ gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); +gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen); in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen); const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen); gboolean nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen); @@ -275,7 +275,7 @@ _nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len) G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) > sizeof (char *)); \ _nm_utils_strbuf_init ((buf), sizeof (buf), (p_buf_ptr), (p_buf_len)); \ } G_STMT_END -void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) __attribute__((__format__ (__printf__, 3, 4))); +void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _nm_printf (3, 4); void nm_utils_strbuf_append_c (char **buf, gsize *len, char c); void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str); @@ -283,6 +283,7 @@ const char *nm_utils_get_ip_config_method (NMConnection *connection, GType ip_setting_type); char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id); +const char *nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key); GPtrArray *nm_utils_read_resolv_conf_nameservers (const char *rc_contents); GPtrArray *nm_utils_read_resolv_conf_dns_options (const char *rc_contents); @@ -308,6 +309,12 @@ const char *nm_utils_ip4_property_path (const char *ifname, const char *property gboolean nm_utils_is_specific_hostname (const char *name); +int nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns); +ssize_t nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll); +int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll); + +int nm_utils_read_urandom (void *p, size_t n); + char *nm_utils_machine_id_read (void); gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_uuid); @@ -333,23 +340,43 @@ struct _NMUtilsIPv6IfaceId { #define NM_UTILS_IPV6_IFACE_ID_INIT { { .id = 0 } } +void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr, + const NMUtilsIPv6IfaceId iid); + +void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid, + const struct in6_addr *addr); + +gboolean nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid, + const char *token); + +const char *nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, + char *buf); + 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, - const NMUtilsIPv6IfaceId iid); +typedef enum { /*< skip >*/ + NM_UTILS_STABLE_TYPE_UUID = 0, + NM_UTILS_STABLE_TYPE_STABLE_ID = 1, +} NMUtilsStableType; -gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, +gboolean nm_utils_ipv6_addr_set_stable_privacy (NMUtilsStableType id_type, + struct in6_addr *addr, const char *ifname, - const char *uuid, + const char *network_id, guint dad_counter, GError **error); -void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, - const struct in6_addr *addr); +char *nm_utils_hw_addr_gen_random_eth (const char *current_mac_address, + const char *generate_mac_address_mask); +char *nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type, + const char *stable_id, + const char *ifname, + const char *current_mac_address, + const char *generate_mac_address_mask); void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len); @@ -396,7 +423,7 @@ gboolean nm_utils_lifetime_get (guint32 timestamp, gboolean nm_utils_ip4_address_is_link_local (in_addr_t addr); -const char *nm_utils_dnsmasq_status_to_string (int status, char *dest, guint size); +const char *nm_utils_dnsmasq_status_to_string (int status, char *dest, gsize size); void nm_utils_get_reverse_dns_domains_ip4 (guint32 ip, guint8 plen, GPtrArray *domains); void nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GPtrArray *domains); diff --git a/src/nm-dcb.h b/src/nm-dcb.h index 86e6153d..8bc08470 100644 --- a/src/nm-dcb.h +++ b/src/nm-dcb.h @@ -21,7 +21,6 @@ #ifndef __NETWORKMANAGER_DCB_H__ #define __NETWORKMANAGER_DCB_H__ -#include "nm-default.h" #include "nm-setting-dcb.h" gboolean nm_dcb_enable (const char *iface, gboolean enable, GError **error); diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index 6f72ee84..2fd2c7db 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -200,7 +200,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry for (i = 0; i < routes->len; i++) { NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i); - route.rx.source = r->source; + route.rx.rt_source = r->rt_source; if (nm_platform_ip4_route_cmp (r, &route.r4) == 0) return TRUE; } @@ -208,7 +208,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry for (i = 0; i < routes->len; i++) { NMPlatformIP6Route *r = &g_array_index (routes, NMPlatformIP6Route, i); - route.rx.source = r->source; + route.rx.rt_source = r->rt_source; if (nm_platform_ip6_route_cmp (r, &route.r6) == 0) return TRUE; } @@ -289,7 +289,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g if (vtable->vt->is_ip4) { success = nm_platform_ip4_route_add (priv->platform, entry->route.rx.ifindex, - entry->route.rx.source, + entry->route.rx.rt_source, 0, 0, entry->route.r4.gateway, @@ -299,7 +299,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g } else { success = nm_platform_ip6_route_add (priv->platform, entry->route.rx.ifindex, - entry->route.rx.source, + entry->route.rx.rt_source, in6addr_any, 0, entry->route.r6.gateway, @@ -765,7 +765,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, * the device. */ memset (&rt, 0, sizeof (rt)); rt.rx.ifindex = ip_ifindex; - rt.rx.source = NM_IP_CONFIG_SOURCE_UNKNOWN; + rt.rx.rt_source = NM_IP_CONFIG_SOURCE_UNKNOWN; rt.rx.metric = G_MAXUINT32; default_route = &rt.rx; @@ -787,7 +787,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, if (vpn_config) { never_default = nm_ip4_config_get_never_default (vpn_config); rt.r4.ifindex = ip_ifindex; - rt.r4.source = NM_IP_CONFIG_SOURCE_VPN; + rt.r4.rt_source = NM_IP_CONFIG_SOURCE_VPN; rt.r4.gateway = nm_ip4_config_get_gateway (vpn_config); rt.r4.metric = nm_vpn_connection_get_ip4_route_metric (vpn); rt.r4.mss = nm_ip4_config_get_mss (vpn_config); @@ -802,7 +802,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, never_default = nm_ip6_config_get_never_default (vpn_config); rt.r6.ifindex = ip_ifindex; - rt.r6.source = NM_IP_CONFIG_SOURCE_VPN; + rt.r6.rt_source = NM_IP_CONFIG_SOURCE_VPN; rt.r6.gateway = int_gw ? *int_gw : in6addr_any; rt.r6.metric = nm_vpn_connection_get_ip6_route_metric (vpn); rt.r6.mss = nm_ip6_config_get_mss (vpn_config); diff --git a/src/nm-default-route-manager.h b/src/nm-default-route-manager.h index ca92814c..30f130a4 100644 --- a/src/nm-default-route-manager.h +++ b/src/nm-default-route-manager.h @@ -18,13 +18,10 @@ * Copyright (C) 2014 Red Hat, Inc. */ - -#include "nm-default.h" -#include "nm-connection.h" - #ifndef __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__ #define __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__ +#include "nm-connection.h" #define NM_TYPE_DEFAULT_ROUTE_MANAGER (nm_default_route_manager_get_type ()) #define NM_DEFAULT_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManager)) diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index 4959ed5d..df9be2e7 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -28,11 +28,13 @@ #include "nm-dispatcher-api.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" +#include "nm-connectivity.h" #include "nm-device.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" +#include "nm-manager.h" #include "nm-settings-connection.h" #include "nm-platform.h" #include "nm-core-internal.h" @@ -422,6 +424,7 @@ static const char *action_table[] = { [DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN, [DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE, [DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE, + [DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE }; static const char * @@ -449,6 +452,7 @@ _dispatcher_call (DispatcherAction action, NMSettingsConnection *settings_connection, NMConnection *applied_connection, NMDevice *device, + NMConnectivityState connectivity_state, const char *vpn_iface, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, @@ -482,8 +486,9 @@ _dispatcher_call (DispatcherAction action, _ensure_requests (); - /* All actions except 'hostname' require a device */ - if (action == DISPATCHER_ACTION_HOSTNAME) { + /* All actions except 'hostname' and 'connectivity-change' require a device */ + if ( action == DISPATCHER_ACTION_HOSTNAME + || action == DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { _LOGD ("(%u) dispatching action '%s'%s", reqid, action_to_string (action), blocking @@ -551,8 +556,9 @@ _dispatcher_call (DispatcherAction action, g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); - /* hostname actions only send the hostname */ - if (action != DISPATCHER_ACTION_HOSTNAME) { + /* hostname and connectivity-change actions don't send device data */ + if ( action != DISPATCHER_ACTION_HOSTNAME + && action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { fill_device_props (device, &device_props, &device_ip4_props, @@ -578,7 +584,7 @@ _dispatcher_call (DispatcherAction action, GVariantIter *results; ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action", - g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}sa{sv}a{sv}b)", + g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)", action_to_string (action), connection_dict, &connection_props, @@ -587,6 +593,7 @@ _dispatcher_call (DispatcherAction action, &device_ip6_props, device_dhcp4_props, device_dhcp6_props, + nm_connectivity_state_to_string (connectivity_state), vpn_iface ? vpn_iface : "", &vpn_ip4_props, &vpn_ip6_props, @@ -613,7 +620,7 @@ _dispatcher_call (DispatcherAction action, info->callback = callback; info->user_data = user_data; g_dbus_proxy_call (dispatcher_proxy, "Action", - g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}sa{sv}a{sv}b)", + g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)", action_to_string (action), connection_dict, &connection_props, @@ -622,6 +629,7 @@ _dispatcher_call (DispatcherAction action, &device_ip6_props, device_dhcp4_props, device_dhcp6_props, + nm_connectivity_state_to_string (connectivity_state), vpn_iface ? vpn_iface : "", &vpn_ip4_props, &vpn_ip6_props, @@ -671,8 +679,9 @@ nm_dispatcher_call (DispatcherAction action, gpointer user_data, guint *out_call_id) { - return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device, NULL, NULL, - NULL, callback, user_data, out_call_id); + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device, + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, + callback, user_data, out_call_id); } /** @@ -693,8 +702,8 @@ nm_dispatcher_call_sync (DispatcherAction action, NMConnection *applied_connection, NMDevice *device) { - return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device, NULL, NULL, - NULL, NULL, NULL, NULL); + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device, + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL); } /** @@ -728,8 +737,9 @@ nm_dispatcher_call_vpn (DispatcherAction action, gpointer user_data, guint *out_call_id) { - return _dispatcher_call (action, FALSE, settings_connection, applied_connection, parent_device, vpn_iface, - vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id); + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_ip4_config, + vpn_ip6_config, callback, user_data, out_call_id); } /** @@ -756,10 +766,28 @@ nm_dispatcher_call_vpn_sync (DispatcherAction action, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config) { - return _dispatcher_call (action, TRUE, settings_connection, applied_connection, parent_device, vpn_iface, + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL); } +/** + * nm_dispatcher_call_connectivity(): + * @action: the %DispatcherAction + * @connectivity_state: the #NMConnectivityState value + * + * This method does not block the caller. + * + * Returns: %TRUE if the action was dispatched, %FALSE on failure + */ +gboolean +nm_dispatcher_call_connectivity (DispatcherAction action, + NMConnectivityState connectivity_state) +{ + return _dispatcher_call (action, FALSE, NULL, NULL, NULL, connectivity_state, + NULL, NULL, NULL, NULL, NULL, NULL); +} + void nm_dispatcher_call_cancel (guint call_id) { diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h index 42dcdc46..62818c45 100644 --- a/src/nm-dispatcher.h +++ b/src/nm-dispatcher.h @@ -24,7 +24,6 @@ #include <stdio.h> -#include "nm-default.h" #include "nm-connection.h" typedef enum { @@ -38,7 +37,8 @@ typedef enum { DISPATCHER_ACTION_VPN_PRE_DOWN, DISPATCHER_ACTION_VPN_DOWN, DISPATCHER_ACTION_DHCP4_CHANGE, - DISPATCHER_ACTION_DHCP6_CHANGE + DISPATCHER_ACTION_DHCP6_CHANGE, + DISPATCHER_ACTION_CONNECTIVITY_CHANGE } DispatcherAction; typedef void (*DispatcherFunc) (guint call_id, gpointer user_data); @@ -75,6 +75,9 @@ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config); +gboolean nm_dispatcher_call_connectivity (DispatcherAction action, + NMConnectivityState state); + void nm_dispatcher_call_cancel (guint call_id); void nm_dispatcher_init (void); diff --git a/src/nm-enum-types.c b/src/nm-enum-types.c index b2f91dca..670502cf 100644 --- a/src/nm-enum-types.c +++ b/src/nm-enum-types.c @@ -6,21 +6,11 @@ #include "config.h" #include "nm-enum-types.h" +#include "nm-default.h" -#include "nm-device-bond.h" -#include "nm-device-bridge.h" -#include "nm-device-ethernet.h" -#include "nm-device-infiniband.h" -#include "nm-device-ip-tunnel.h" -#include "nm-device-macvlan.h" -#include "nm-device-tun.h" -#include "nm-device-veth.h" -#include "nm-device-vlan.h" -#include "nm-device-vxlan.h" -#include "nm-dhcp-dhclient.h" #include "nm-dhcp-dhclient-utils.h" -#include "nm-dhcp-dhcpcd.h" -#include "nm-dhcp-systemd.h" +#include "nm-checkpoint-manager.h" +#include "nm-checkpoint.h" #include "nm-device.h" #include "nm-lldp-listener.h" #include "nm-arping-manager.h" @@ -42,10 +32,8 @@ #include "nm-platform-utils.h" #include "nm-platform.h" #include "nm-linux-platform.h" -#include "nm-fake-platform.h" #include "wifi-utils-nl80211.h" #include "wifi-utils.h" -#include "nm-fake-rdisc.h" #include "nm-lndp-rdisc.h" #include "nm-rdisc.h" #include "nm-ppp-manager.h" @@ -74,7 +62,6 @@ #include "nm-bus-manager.h" #include "nm-config.h" #include "nm-config-data.h" -#include "nm-connection-provider.h" #include "nm-connectivity.h" #include "nm-dcb.h" #include "nm-route-manager.h" @@ -86,7 +73,6 @@ #include "nm-firewall-manager.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -#include "nm-logging.h" #include "nm-auth-manager.h" #include "nm-auth-subject.h" #include "nm-auth-utils.h" @@ -97,31 +83,10 @@ #include "nm-session-monitor.h" #include "nm-sleep-monitor.h" #include "nm-types.h" -#include "nm-core-utils.h" #include "NetworkManagerUtils.h" #include "wifi-utils-wext.h" GType -nm_vlan_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" }, - { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMVlanError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType nm_unman_flag_op_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -475,6 +440,27 @@ nm_supplicant_error_get_type (void) return g_define_type_id__volatile; } GType +nm_config_run_state_property_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CONFIG_STATE_PROPERTY_NONE, "NM_CONFIG_STATE_PROPERTY_NONE", "none" }, + { NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, "NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED", "networking-enabled" }, + { NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED, "NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED", "wifi-enabled" }, + { NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED, "NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED", "wwan-enabled" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMConfigRunStatePropertyType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_config_get_value_flags_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -551,6 +537,7 @@ nm_dispatcher_action_get_type (void) { DISPATCHER_ACTION_VPN_DOWN, "DISPATCHER_ACTION_VPN_DOWN", "vpn-down" }, { DISPATCHER_ACTION_DHCP4_CHANGE, "DISPATCHER_ACTION_DHCP4_CHANGE", "dhcp4-change" }, { DISPATCHER_ACTION_DHCP6_CHANGE, "DISPATCHER_ACTION_DHCP6_CHANGE", "dhcp6-change" }, + { DISPATCHER_ACTION_CONNECTIVITY_CHANGE, "DISPATCHER_ACTION_CONNECTIVITY_CHANGE", "connectivity-change" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -610,8 +597,14 @@ nm_ip_config_source_get_type (void) { static const GEnumValue values[] = { { NM_IP_CONFIG_SOURCE_UNKNOWN, "NM_IP_CONFIG_SOURCE_UNKNOWN", "nm-ip-config-source-unknown" }, - { _NM_IP_CONFIG_SOURCE_RTM_F_CLONED, "_NM_IP_CONFIG_SOURCE_RTM_F_CLONED", "-nm-ip-config-source-rtm-f-cloned" }, + { NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC, "NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC", "nm-ip-config-source-rtprot-unspec" }, + { NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT, "NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT", "nm-ip-config-source-rtprot-redirect" }, { NM_IP_CONFIG_SOURCE_RTPROT_KERNEL, "NM_IP_CONFIG_SOURCE_RTPROT_KERNEL", "nm-ip-config-source-rtprot-kernel" }, + { NM_IP_CONFIG_SOURCE_RTPROT_BOOT, "NM_IP_CONFIG_SOURCE_RTPROT_BOOT", "nm-ip-config-source-rtprot-boot" }, + { NM_IP_CONFIG_SOURCE_RTPROT_STATIC, "NM_IP_CONFIG_SOURCE_RTPROT_STATIC", "nm-ip-config-source-rtprot-static" }, + { NM_IP_CONFIG_SOURCE_RTPROT_RA, "NM_IP_CONFIG_SOURCE_RTPROT_RA", "nm-ip-config-source-rtprot-ra" }, + { NM_IP_CONFIG_SOURCE_RTPROT_DHCP, "NM_IP_CONFIG_SOURCE_RTPROT_DHCP", "nm-ip-config-source-rtprot-dhcp" }, + { _NM_IP_CONFIG_SOURCE_RTPROT_LAST, "_NM_IP_CONFIG_SOURCE_RTPROT_LAST", "-nm-ip-config-source-rtprot-last" }, { NM_IP_CONFIG_SOURCE_KERNEL, "NM_IP_CONFIG_SOURCE_KERNEL", "nm-ip-config-source-kernel" }, { NM_IP_CONFIG_SOURCE_SHARED, "NM_IP_CONFIG_SOURCE_SHARED", "nm-ip-config-source-shared" }, { NM_IP_CONFIG_SOURCE_IP4LL, "NM_IP_CONFIG_SOURCE_IP4LL", "nm-ip-config-source-ip4ll" }, @@ -644,7 +637,7 @@ nm_link_type_get_type (void) { NM_LINK_TYPE_INFINIBAND, "NM_LINK_TYPE_INFINIBAND", "infiniband" }, { NM_LINK_TYPE_OLPC_MESH, "NM_LINK_TYPE_OLPC_MESH", "olpc-mesh" }, { NM_LINK_TYPE_WIFI, "NM_LINK_TYPE_WIFI", "wifi" }, - { NM_LINK_TYPE_WWAN_ETHERNET, "NM_LINK_TYPE_WWAN_ETHERNET", "wwan-ethernet" }, + { NM_LINK_TYPE_WWAN_NET, "NM_LINK_TYPE_WWAN_NET", "wwan-net" }, { NM_LINK_TYPE_WIMAX, "NM_LINK_TYPE_WIMAX", "wimax" }, { NM_LINK_TYPE_DUMMY, "NM_LINK_TYPE_DUMMY", "dummy" }, { NM_LINK_TYPE_GRE, "NM_LINK_TYPE_GRE", "gre" }, @@ -730,49 +723,6 @@ nm_ip_config_merge_flags_get_type (void) return g_define_type_id__volatile; } -GType -nm_match_spec_match_type_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_MATCH_SPEC_NO_MATCH, "NM_MATCH_SPEC_NO_MATCH", "no-match" }, - { NM_MATCH_SPEC_MATCH, "NM_MATCH_SPEC_MATCH", "match" }, - { NM_MATCH_SPEC_NEG_MATCH, "NM_MATCH_SPEC_NEG_MATCH", "neg-match" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMMatchSpecMatchType"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_utils_test_flags_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GFlagsValue values[] = { - { NM_UTILS_TEST_NONE, "NM_UTILS_TEST_NONE", "nm-utils-test-none" }, - { _NM_UTILS_TEST_INITIALIZED, "_NM_UTILS_TEST_INITIALIZED", "-nm-utils-test-initialized" }, - { _NM_UTILS_TEST_GENERAL, "_NM_UTILS_TEST_GENERAL", "-nm-utils-test-general" }, - { NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK, "NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK", "nm-utils-test-no-keyfile-owner-check" }, - { _NM_UTILS_TEST_LAST, "_NM_UTILS_TEST_LAST", "-nm-utils-test-last" }, - { NM_UTILS_TEST_ALL, "NM_UTILS_TEST_ALL", "nm-utils-test-all" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_flags_register_static (g_intern_static_string ("NMUtilsTestFlags"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} diff --git a/src/nm-enum-types.h b/src/nm-enum-types.h index 36a9c270..09ffca60 100644 --- a/src/nm-enum-types.h +++ b/src/nm-enum-types.h @@ -10,8 +10,6 @@ #include <glib-object.h> G_BEGIN_DECLS -GType nm_vlan_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_VLAN_ERROR (nm_vlan_error_get_type ()) GType nm_unman_flag_op_get_type (void) G_GNUC_CONST; #define NM_TYPE_UNMAN_FLAG_OP (nm_unman_flag_op_get_type ()) GType nm_dhcp_state_get_type (void) G_GNUC_CONST; @@ -44,6 +42,8 @@ GType nm_supplicant_feature_get_type (void) G_GNUC_CONST; #define NM_TYPE_SUPPLICANT_FEATURE (nm_supplicant_feature_get_type ()) GType nm_supplicant_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_SUPPLICANT_ERROR (nm_supplicant_error_get_type ()) +GType nm_config_run_state_property_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CONFIG_RUN_STATE_PROPERTY_TYPE (nm_config_run_state_property_type_get_type ()) GType nm_config_get_value_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_CONFIG_GET_VALUE_FLAGS (nm_config_get_value_flags_get_type ()) GType nm_config_change_flags_get_type (void) G_GNUC_CONST; @@ -62,10 +62,6 @@ GType nm_pobject_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_POBJECT_TYPE (nm_pobject_type_get_type ()) GType nm_ip_config_merge_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_IP_CONFIG_MERGE_FLAGS (nm_ip_config_merge_flags_get_type ()) -GType nm_match_spec_match_type_get_type (void) G_GNUC_CONST; -#define NM_TYPE_MATCH_SPEC_MATCH_TYPE (nm_match_spec_match_type_get_type ()) -GType nm_utils_test_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_UTILS_TEST_FLAGS (nm_utils_test_flags_get_type ()) G_END_DECLS #endif /* __NM_ENUM_TYPES_H__ */ diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 10f7d23f..c4dbab87 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -257,12 +257,16 @@ nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, g_return_if_fail (NM_IS_EXPORTED_OBJECT_CLASS (object_class)); g_return_if_fail (g_type_is_a (dbus_skeleton_type, G_TYPE_DBUS_INTERFACE_SKELETON)); - classinfo = g_slice_new (NMExportedObjectClassInfo); - classinfo->skeleton_types = NULL; - classinfo->methods = g_array_new (FALSE, FALSE, sizeof (NMExportedObjectDBusMethodImpl)); - classinfo->properties = g_hash_table_new (g_str_hash, g_str_equal); - g_type_set_qdata (G_TYPE_FROM_CLASS (object_class), - nm_exported_object_class_info_quark (), classinfo); + classinfo = g_type_get_qdata (G_TYPE_FROM_CLASS (object_class), + nm_exported_object_class_info_quark ()); + if (!classinfo) { + classinfo = g_slice_new (NMExportedObjectClassInfo); + classinfo->skeleton_types = NULL; + classinfo->methods = g_array_new (FALSE, FALSE, sizeof (NMExportedObjectDBusMethodImpl)); + classinfo->properties = g_hash_table_new (g_str_hash, g_str_equal); + g_type_set_qdata (G_TYPE_FROM_CLASS (object_class), + nm_exported_object_class_info_quark (), classinfo); + } classinfo->skeleton_types = g_slist_prepend (classinfo->skeleton_types, GSIZE_TO_POINTER (dbus_skeleton_type)); @@ -342,8 +346,6 @@ nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, } } - g_assert_cmpint (n_method_signals, ==, classinfo->methods->len); - g_type_class_unref (dbus_object_class); } @@ -571,7 +573,9 @@ _create_export_path (NMExportedObjectClass *klass) g_hash_table_insert (prefix_counters, g_strdup (class_export_path), counter); } + NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") return g_strdup_printf (class_export_path, (*counter)++); + NM_PRAGMA_WARNING_REENABLE } return g_strdup (class_export_path); diff --git a/src/nm-exported-object.h b/src/nm-exported-object.h index c2c22804..7036e0d0 100644 --- a/src/nm-exported-object.h +++ b/src/nm-exported-object.h @@ -21,10 +21,6 @@ #ifndef NM_EXPORTED_OBJECT_H #define NM_EXPORTED_OBJECT_H -#include "nm-default.h" - -G_BEGIN_DECLS - /*****************************************************************************/ char *nm_exported_object_skeletonify_method_name (const char *dbus_method_name); @@ -79,6 +75,4 @@ GDBusInterfaceSkeleton *nm_exported_object_get_interface_by_type (NMExportedObje void _nm_exported_object_clear_and_unexport (NMExportedObject **location); #define nm_exported_object_clear_and_unexport(location) _nm_exported_object_clear_and_unexport ((NMExportedObject **) (location)) -G_END_DECLS - -#endif /* NM_EXPORTED_OBJECT_H */ +#endif /* NM_EXPORTED_OBJECT_H */ diff --git a/src/nm-firewall-manager.h b/src/nm-firewall-manager.h index a08ac8b8..92fac8e2 100644 --- a/src/nm-firewall-manager.h +++ b/src/nm-firewall-manager.h @@ -21,16 +21,11 @@ #ifndef __NETWORKMANAGER_FIREWALL_MANAGER_H__ #define __NETWORKMANAGER_FIREWALL_MANAGER_H__ -#include "nm-default.h" - #define FIREWALL_DBUS_SERVICE "org.fedoraproject.FirewallD1" #define FIREWALL_DBUS_PATH "/org/fedoraproject/FirewallD1" #define FIREWALL_DBUS_INTERFACE "org.fedoraproject.FirewallD1" #define FIREWALL_DBUS_INTERFACE_ZONE "org.fedoraproject.FirewallD1.zone" - -G_BEGIN_DECLS - #define NM_TYPE_FIREWALL_MANAGER (nm_firewall_manager_get_type ()) #define NM_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManager)) #define NM_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 20f7729a..49672cf5 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -66,6 +66,7 @@ static struct { int tempaddr; char *ifname; char *uuid; + char *stable_id; char *dhcp4_address; char *dhcp4_clientid; char *dhcp4_hostname; @@ -129,8 +130,9 @@ dhcp4_state_changed (NMDhcpClient *client, } static void -rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_data) +rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, gpointer user_data) { + NMRDiscConfigMap changed = changed_int; static NMIP6Config *rdisc_config = NULL; NMIP6Config *existing; static int system_support = -1; @@ -165,11 +167,9 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da if (changed & NM_RDISC_CONFIG_GATEWAYS) { /* Use the first gateway as ordered in router discovery cache. */ - if (rdisc->gateways->len) { - NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0); - - nm_ip6_config_set_gateway (rdisc_config, &gateway->address); - } else + if (rdata->gateways_n) + nm_ip6_config_set_gateway (rdisc_config, &rdata->gateways[0].address); + else nm_ip6_config_set_gateway (rdisc_config, NULL); } @@ -182,8 +182,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da * also counts static and temporary addresses when checking * max_addresses. **/ - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + for (i = 0; i < rdata->addresses_n; i++) { + const NMRDiscAddress *discovered_address = &rdata->addresses[i]; NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); @@ -194,7 +194,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.source = NM_IP_CONFIG_SOURCE_RDISC; + address.addr_source = NM_IP_CONFIG_SOURCE_RDISC; address.n_ifa_flags = ifa_flags; nm_ip6_config_add_address (rdisc_config, &address); @@ -205,25 +205,17 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da /* Rebuild route list from router discovery cache. */ nm_ip6_config_reset_routes (rdisc_config); - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i); - NMPlatformIP6Route route; - - /* Only accept non-default routes. The router has no idea what the - * local configuration or user preferences are, so sending routes - * with a prefix length of 0 is quite rude and thus ignored. - */ - if ( discovered_route->plen > 0 - && discovered_route->plen <= 128) { - memset (&route, 0, sizeof (route)); - route.network = discovered_route->network; - route.plen = discovered_route->plen; - route.gateway = discovered_route->gateway; - route.source = NM_IP_CONFIG_SOURCE_RDISC; - route.metric = global_opt.priority_v6; - - nm_ip6_config_add_route (rdisc_config, &route); - } + for (i = 0; i < rdata->routes_n; i++) { + const NMRDiscRoute *discovered_route = &rdata->routes[i]; + const NMPlatformIP6Route route = { + .network = discovered_route->network, + .plen = discovered_route->plen, + .gateway = discovered_route->gateway, + .rt_source = NM_IP_CONFIG_SOURCE_RDISC, + .metric = global_opt.priority_v6, + }; + + nm_ip6_config_add_route (rdisc_config, &route); } } @@ -232,12 +224,12 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da } if (changed & NM_RDISC_CONFIG_HOP_LIMIT) - nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdisc->hop_limit); + nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdata->hop_limit); if (changed & NM_RDISC_CONFIG_MTU) { char val[16]; - g_snprintf (val, sizeof (val), "%d", rdisc->mtu); + g_snprintf (val, sizeof (val), "%d", rdata->mtu); nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val); } @@ -278,8 +270,9 @@ do_early_setup (int *argc, char **argv[]) gint64 priority64_v6 = -1; GOptionEntry options[] = { /* Interface/IP config */ - { "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") }, + { "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), "eth0" }, + { "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), "661e8cd0-b618-46b8-9dc9-31a52baaa16b" }, + { "stable-id", '\0', 0, G_OPTION_ARG_STRING, &global_opt.stable_id, N_("Connection Token for Stable IDs"), "eth" }, { "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 }, @@ -469,9 +462,23 @@ main (int argc, char *argv[]) } if (global_opt.slaac) { + NMUtilsStableType stable_type = NM_UTILS_STABLE_TYPE_UUID; + const char *stable_id = global_opt.uuid; + nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, TRUE); - rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname, global_opt.uuid, global_opt.addr_gen_mode, NULL); + if ( global_opt.stable_id + && (global_opt.stable_id[0] >= '0' && global_opt.stable_id[0] <= '9') + && global_opt.stable_id[1] == ' ') { + /* strict parsing of --stable-id, which is the numeric stable-type + * and the ID, joined with one space. For now, only support stable-types + * from 0 to 9. */ + stable_type = (global_opt.stable_id[0] - '0'); + stable_id = &global_opt.stable_id[2]; + } + rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname, + stable_type, stable_id, + global_opt.addr_gen_mode, NULL); g_assert (rdisc); if (iid) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 0ae7d0d4..22d1d077 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -35,11 +35,7 @@ #include "nmdbus-ip4-config.h" -G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT) - -#define NM_IP4_CONFIG_GET_PRIVATE(o) ((o)->priv) - -typedef struct _NMIP4ConfigPrivate { +typedef struct { gboolean never_default; guint32 gateway; gboolean has_gateway; @@ -61,6 +57,30 @@ typedef struct _NMIP4ConfigPrivate { gint dns_priority; } NMIP4ConfigPrivate; +struct _NMIP4Config { + NMExportedObject parent; + NMIP4ConfigPrivate _priv; +}; + +struct _NMIP4ConfigClass { + NMExportedObjectClass parent; +}; + +G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT) + +#define NM_IP4_CONFIG_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMIP4Config *_self2 = (_self); \ + \ + nm_assert (NM_IS_IP4_CONFIG (_self)); \ + &_self->_priv; \ + }) + /* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */ G_STATIC_ASSERT (sizeof (uint) >= sizeof (guint32)); G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF); @@ -209,8 +229,8 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b) return p1 > p2 ? -1 : 1; /* Sort the addresses based on their source. */ - if (a1->source != a2->source) - return a1->source > a2->source ? -1 : 1; + if (a1->addr_source != a2->addr_source) + return a1->addr_source > a2->addr_source ? -1 : 1; if ((a1->label[0] == '\0') != (a2->label[0] == '\0')) return (a1->label[0] == '\0') ? -1 : 1; @@ -337,7 +357,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); int i; gs_unref_ptrarray GPtrArray *added_addresses = NULL; @@ -370,7 +390,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu nm_assert (addr->plen <= 32); route.ifindex = ifindex; - route.source = NM_IP_CONFIG_SOURCE_KERNEL; + route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; /* The destination network depends on the peer-address. */ route.network = nm_utils_ip4_address_clear_host_address (addr->peer_address, addr->plen); @@ -400,14 +420,6 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu const NMPlatformIP4Route *route; route = nm_ip4_config_get_route (config, i); - - /* Don't add the route if it's more specific than one of the subnets - * the device already has an IP address on. - */ - if ( route->gateway == 0 - && nm_ip4_config_destination_is_direct (config, route->network, route->plen)) - continue; - /* duplicates in @routes are no problem as route-manager handles them * gracefully (by ignoring them). */ g_array_append_vals (routes, route, 1); @@ -473,7 +485,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu nm_assert (address.plen <= 32); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; - address.source = NM_IP_CONFIG_SOURCE_USER; + address.addr_source = NM_IP_CONFIG_SOURCE_USER; label = nm_ip_address_get_attribute (s_addr, "label"); if (label) @@ -502,7 +514,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu route.metric = default_route_metric; else route.metric = nm_ip_route_get_metric (s_route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (config, &route); } @@ -612,7 +624,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) continue; /* Ignore routes provided by external sources */ - if (route->source != NM_IP_CONFIG_SOURCE_USER) + if (route->rt_source != nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER)) continue; s_route = nm_ip_route_new_binary (AF_INET, @@ -654,7 +666,8 @@ nm_ip4_config_create_setting (const NMIP4Config *config) void nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFlags merge_flags) { - NMIP4ConfigPrivate *dst_priv, *src_priv; + NMIP4ConfigPrivate *dst_priv; + const NMIP4ConfigPrivate *src_priv; guint32 i; g_return_if_fail (src != NULL); @@ -748,7 +761,7 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl static int _addresses_get_index (const NMIP4Config *self, const NMPlatformIP4Address *addr) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->addresses->len; i++) { @@ -763,7 +776,7 @@ _addresses_get_index (const NMIP4Config *self, const NMPlatformIP4Address *addr) static int _nameservers_get_index (const NMIP4Config *self, guint32 ns) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->nameservers->len; i++) { @@ -778,7 +791,7 @@ _nameservers_get_index (const NMIP4Config *self, guint32 ns) static int _routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->routes->len; i++) { @@ -794,7 +807,7 @@ _routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route) static int _domains_get_index (const NMIP4Config *self, const char *domain) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->domains->len; i++) { @@ -809,7 +822,7 @@ _domains_get_index (const NMIP4Config *self, const char *domain) static int _searches_get_index (const NMIP4Config *self, const char *search) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->searches->len; i++) { @@ -824,7 +837,7 @@ _searches_get_index (const NMIP4Config *self, const char *search) static int _dns_options_get_index (const NMIP4Config *self, const char *option) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->dns_options->len; i++) { @@ -839,7 +852,7 @@ _dns_options_get_index (const NMIP4Config *self, const char *option) static int _nis_servers_get_index (const NMIP4Config *self, guint32 nis_server) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->nis->len; i++) { @@ -854,7 +867,7 @@ _nis_servers_get_index (const NMIP4Config *self, guint32 nis_server) static int _wins_get_index (const NMIP4Config *self, guint32 wins_server) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->wins->len; i++) { @@ -1041,7 +1054,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev #endif gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal; guint i, num; - NMIP4ConfigPrivate *dst_priv, *src_priv; + NMIP4ConfigPrivate *dst_priv; + const NMIP4ConfigPrivate *src_priv; const NMPlatformIP4Address *dst_addr, *src_addr; const NMPlatformIP4Route *dst_route, *src_route; @@ -1398,7 +1412,7 @@ nm_ip4_config_set_never_default (NMIP4Config *config, gboolean never_default) gboolean nm_ip4_config_get_never_default (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->never_default; } @@ -1440,7 +1454,7 @@ nm_ip4_config_unset_gateway (NMIP4Config *config) gboolean nm_ip4_config_has_gateway (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->has_gateway; } @@ -1448,7 +1462,7 @@ nm_ip4_config_has_gateway (const NMIP4Config *config) guint32 nm_ip4_config_get_gateway (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->gateway; } @@ -1456,7 +1470,7 @@ nm_ip4_config_get_gateway (const NMIP4Config *config) gint64 nm_ip4_config_get_route_metric (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->route_metric; } @@ -1507,14 +1521,14 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) *item = *new; /* But restore highest priority source */ - item->source = MAX (item_old.source, new->source); + item->addr_source = MAX (item_old.addr_source, new->addr_source); /* for addresses that we read from the kernel, we keep the timestamps as defined * by the previous source (item_old). The reason is, that the other source configured the lifetimes * with "what should be" and the kernel values are "what turned out after configuring it". * * For other sources, the longer lifetime wins. */ - if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.source) + if ( (new->addr_source == NM_IP_CONFIG_SOURCE_KERNEL && new->addr_source != item_old.addr_source) || nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) { item->timestamp = item_old.timestamp; item->lifetime = item_old.lifetime; @@ -1547,7 +1561,7 @@ nm_ip4_config_del_address (NMIP4Config *config, guint i) guint nm_ip4_config_get_num_addresses (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->addresses->len; } @@ -1555,7 +1569,7 @@ nm_ip4_config_get_num_addresses (const NMIP4Config *config) const NMPlatformIP4Address * nm_ip4_config_get_address (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return &g_array_index (priv->addresses, NMPlatformIP4Address, i); } @@ -1600,7 +1614,7 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new) g_return_if_fail (new != NULL); g_return_if_fail (new->plen > 0 && new->plen <= 32); - g_assert (priv->ifindex); + g_return_if_fail (priv->ifindex > 0); for (i = 0; i < priv->routes->len; i++ ) { NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i); @@ -1608,10 +1622,10 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new) if (routes_are_duplicate (item, new, FALSE)) { if (nm_platform_ip4_route_cmp (item, new) == 0) return; - old_source = item->source; + old_source = item->rt_source; memcpy (item, new, sizeof (*item)); /* Restore highest priority source */ - item->source = MAX (old_source, new->source); + item->rt_source = MAX (old_source, new->rt_source); item->ifindex = priv->ifindex; goto NOTIFY; } @@ -1639,7 +1653,7 @@ nm_ip4_config_del_route (NMIP4Config *config, guint i) guint nm_ip4_config_get_num_routes (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->routes->len; } @@ -1647,7 +1661,7 @@ nm_ip4_config_get_num_routes (const NMIP4Config *config) const NMPlatformIP4Route * nm_ip4_config_get_route (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return &g_array_index (priv->routes, NMPlatformIP4Route, i); } @@ -1655,7 +1669,7 @@ nm_ip4_config_get_route (const NMIP4Config *config, guint i) const NMPlatformIP4Route * nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); guint i; NMPlatformIP4Route *best_route = NULL; @@ -1725,7 +1739,7 @@ nm_ip4_config_del_nameserver (NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_nameservers (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->nameservers->len; } @@ -1733,7 +1747,7 @@ nm_ip4_config_get_num_nameservers (const NMIP4Config *config) guint32 nm_ip4_config_get_nameserver (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_array_index (priv->nameservers, guint32, i); } @@ -1782,7 +1796,7 @@ nm_ip4_config_del_domain (NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_domains (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->domains->len; } @@ -1790,7 +1804,7 @@ nm_ip4_config_get_num_domains (const NMIP4Config *config) const char * nm_ip4_config_get_domain (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->domains, i); } @@ -1854,7 +1868,7 @@ nm_ip4_config_del_search (NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_searches (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->searches->len; } @@ -1862,7 +1876,7 @@ nm_ip4_config_get_num_searches (const NMIP4Config *config) const char * nm_ip4_config_get_search (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->searches, i); } @@ -1911,7 +1925,7 @@ nm_ip4_config_del_dns_option(NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_dns_options (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->dns_options->len; } @@ -1919,7 +1933,7 @@ nm_ip4_config_get_num_dns_options (const NMIP4Config *config) const char * nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->dns_options, i); } @@ -1958,7 +1972,7 @@ nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss) guint32 nm_ip4_config_get_mss (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->mss; } @@ -1999,7 +2013,7 @@ nm_ip4_config_del_nis_server (NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_nis_servers (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->nis->len; } @@ -2007,7 +2021,7 @@ nm_ip4_config_get_num_nis_servers (const NMIP4Config *config) guint32 nm_ip4_config_get_nis_server (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_array_index (priv->nis, guint32, i); } @@ -2024,7 +2038,7 @@ nm_ip4_config_set_nis_domain (NMIP4Config *config, const char *domain) const char * nm_ip4_config_get_nis_domain (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->nis_domain; } @@ -2072,7 +2086,7 @@ nm_ip4_config_del_wins (NMIP4Config *config, guint i) guint32 nm_ip4_config_get_num_wins (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->wins->len; } @@ -2080,7 +2094,7 @@ nm_ip4_config_get_num_wins (const NMIP4Config *config) guint32 nm_ip4_config_get_wins (const NMIP4Config *config, guint i) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return g_array_index (priv->wins, guint32, i); } @@ -2102,7 +2116,7 @@ nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu, NMIPConfigSource source guint32 nm_ip4_config_get_mtu (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->mtu; } @@ -2110,7 +2124,7 @@ nm_ip4_config_get_mtu (const NMIP4Config *config) NMIPConfigSource nm_ip4_config_get_mtu_source (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->mtu_source; } @@ -2128,7 +2142,7 @@ nm_ip4_config_set_metered (NMIP4Config *config, gboolean metered) gboolean nm_ip4_config_get_metered (const NMIP4Config *config) { - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); return priv->metered; } @@ -2245,10 +2259,7 @@ nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b) static void nm_ip4_config_init (NMIP4Config *config) { - NMIP4ConfigPrivate *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE (config, NM_TYPE_IP4_CONFIG, NMIP4ConfigPrivate); - config->priv = priv; + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); priv->addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address)); priv->routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route)); @@ -2282,7 +2293,7 @@ finalize (GObject *object) static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMIP4Config *config = NM_IP4_CONFIG (object); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -2473,8 +2484,6 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) GObjectClass *object_class = G_OBJECT_CLASS (config_class); NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); - g_type_class_add_private (config_class, sizeof (NMIP4ConfigPrivate)); - exported_object_class->export_path = NM_DBUS_PATH "/IP4Config/%u"; object_class->get_property = get_property; @@ -2482,72 +2491,72 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) object_class->finalize = finalize; obj_properties[PROP_IFINDEX] = - g_param_spec_int (NM_IP4_CONFIG_IFINDEX, "", "", - -1, G_MAXINT, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + g_param_spec_int (NM_IP4_CONFIG_IFINDEX, "", "", + -1, G_MAXINT, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESS_DATA] = - g_param_spec_variant (NM_IP4_CONFIG_ADDRESS_DATA, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_ADDRESS_DATA, "", "", + G_VARIANT_TYPE ("aa{sv}"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESSES] = - g_param_spec_variant (NM_IP4_CONFIG_ADDRESSES, "", "", - G_VARIANT_TYPE ("aau"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_ADDRESSES, "", "", + G_VARIANT_TYPE ("aau"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTE_DATA] = - g_param_spec_variant (NM_IP4_CONFIG_ROUTE_DATA, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_ROUTE_DATA, "", "", + G_VARIANT_TYPE ("aa{sv}"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTES] = - g_param_spec_variant (NM_IP4_CONFIG_ROUTES, "", "", - G_VARIANT_TYPE ("aau"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_ROUTES, "", "", + G_VARIANT_TYPE ("aau"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_GATEWAY] = - g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = - g_param_spec_variant (NM_IP4_CONFIG_NAMESERVERS, "", "", - G_VARIANT_TYPE ("au"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_NAMESERVERS, "", "", + G_VARIANT_TYPE ("au"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DOMAINS] = - g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_SEARCHES] = - g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DNS_OPTIONS] = - g_param_spec_boxed (NM_IP4_CONFIG_DNS_OPTIONS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP4_CONFIG_DNS_OPTIONS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DNS_PRIORITY] = - g_param_spec_int (NM_IP4_CONFIG_DNS_PRIORITY, "", "", - G_MININT32, G_MAXINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_int (NM_IP4_CONFIG_DNS_PRIORITY, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_WINS_SERVERS] = - g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVERS, "", "", - G_VARIANT_TYPE ("au"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVERS, "", "", + G_VARIANT_TYPE ("au"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index e88fb141..f302630a 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -31,18 +31,7 @@ #define NM_IS_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP4_CONFIG)) #define NM_IP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass)) -struct _NMIP4ConfigPrivate; - -struct _NMIP4Config { - NMExportedObject parent; - - /* private */ - struct _NMIP4ConfigPrivate *priv; -}; - -typedef struct { - NMExportedObjectClass parent; -} NMIP4ConfigClass; +typedef struct _NMIP4ConfigClass NMIP4ConfigClass; /* internal */ #define NM_IP4_CONFIG_IFINDEX "ifindex" diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 86447357..ac9e6cd1 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -28,17 +28,14 @@ #include "nm-utils.h" #include "nm-platform.h" +#include "nm-platform-utils.h" #include "nm-route-manager.h" #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nmdbus-ip6-config.h" -G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT) - -#define NM_IP6_CONFIG_GET_PRIVATE(o) ((o)->priv) - -typedef struct _NMIP6ConfigPrivate { +typedef struct { gboolean never_default; struct in6_addr gateway; GArray *addresses; @@ -53,6 +50,29 @@ typedef struct _NMIP6ConfigPrivate { gint dns_priority; } NMIP6ConfigPrivate; +struct _NMIP6Config { + NMExportedObject parent; + NMIP6ConfigPrivate _priv; +}; + +struct _NMIP6ConfigClass { + NMExportedObjectClass parent; +}; + +G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT) + +#define NM_IP6_CONFIG_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMIP6Config *_self2 = (_self); \ + \ + nm_assert (NM_IS_IP6_CONFIG (_self)); \ + &_self->_priv; \ + }) NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config, PROP_IFINDEX, @@ -242,8 +262,8 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data) } /* Sort the addresses based on their source. */ - if (a1->source != a2->source) - return a1->source > a2->source ? -1 : 1; + if (a1->addr_source != a2->addr_source) + return a1->addr_source > a2->addr_source ? -1 : 1; /* sort permanent addresses before non-permanent. */ perm1 = (a1->n_ifa_flags & IFA_F_PERMANENT); @@ -374,7 +394,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); int i; gboolean success; @@ -392,14 +412,6 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_fu for (i = 0; i < count; i++) { route = nm_ip6_config_get_route (config, i); - - /* Don't add the route if it's more specific than one of the subnets - * the device already has an IP address on. - */ - if ( IN6_IS_ADDR_UNSPECIFIED (&route->gateway) - && nm_ip6_config_destination_is_direct (config, &route->network, route->plen)) - continue; - g_array_append_vals (routes, route, 1); } @@ -459,7 +471,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu nm_assert (address.plen <= 128); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; - address.source = NM_IP_CONFIG_SOURCE_USER; + address.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (config, &address); } @@ -484,7 +496,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu route.metric = default_route_metric; else route.metric = nm_ip_route_get_metric (s_route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_route (config, &route); } @@ -602,7 +614,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) continue; /* Ignore routes provided by external sources */ - if (route->source != NM_IP_CONFIG_SOURCE_USER) + if (route->rt_source != nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER)) continue; s_route = nm_ip_route_new_binary (AF_INET6, @@ -643,7 +655,8 @@ nm_ip6_config_create_setting (const NMIP6Config *config) void nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags) { - NMIP6ConfigPrivate *dst_priv, *src_priv; + NMIP6ConfigPrivate *dst_priv; + const NMIP6ConfigPrivate *src_priv; guint32 i; g_return_if_fail (src != NULL); @@ -733,7 +746,7 @@ nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6 static int _addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->addresses->len; i++) { @@ -748,7 +761,7 @@ _addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr) static int _nameservers_get_index (const NMIP6Config *self, const struct in6_addr *ns) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->nameservers->len; i++) { @@ -763,7 +776,7 @@ _nameservers_get_index (const NMIP6Config *self, const struct in6_addr *ns) static int _routes_get_index (const NMIP6Config *self, const NMPlatformIP6Route *route) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->routes->len; i++) { @@ -778,7 +791,7 @@ _routes_get_index (const NMIP6Config *self, const NMPlatformIP6Route *route) static int _domains_get_index (const NMIP6Config *self, const char *domain) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->domains->len; i++) { @@ -793,7 +806,7 @@ _domains_get_index (const NMIP6Config *self, const char *domain) static int _searches_get_index (const NMIP6Config *self, const char *search) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->searches->len; i++) { @@ -808,7 +821,7 @@ _searches_get_index (const NMIP6Config *self, const char *search) static int _dns_options_get_index (const NMIP6Config *self, const char *option) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); guint i; for (i = 0; i < priv->dns_options->len; i++) { @@ -976,7 +989,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev #endif gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal; guint i, num; - NMIP6ConfigPrivate *dst_priv, *src_priv; + NMIP6ConfigPrivate *dst_priv; + const NMIP6ConfigPrivate *src_priv; const NMPlatformIP6Address *dst_addr, *src_addr; const NMPlatformIP6Route *dst_route, *src_route; @@ -1232,7 +1246,7 @@ nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_default) gboolean nm_ip6_config_get_never_default (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->never_default; } @@ -1257,7 +1271,7 @@ nm_ip6_config_set_gateway (NMIP6Config *config, const struct in6_addr *gateway) const struct in6_addr * nm_ip6_config_get_gateway (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return IN6_IS_ADDR_UNSPECIFIED (&priv->gateway) ? NULL : &priv->gateway; } @@ -1265,7 +1279,7 @@ nm_ip6_config_get_gateway (const NMIP6Config *config) gint64 nm_ip6_config_get_route_metric (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->route_metric; } @@ -1316,14 +1330,14 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) *item = *new; /* But restore highest priority source */ - item->source = MAX (item_old.source, new->source); + item->addr_source = MAX (item_old.addr_source, new->addr_source); /* for addresses that we read from the kernel, we keep the timestamps as defined * by the previous source (item_old). The reason is, that the other source configured the lifetimes * with "what should be" and the kernel values are "what turned out after configuring it". * * For other sources, the longer lifetime wins. */ - if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.source) + if ( (new->addr_source == NM_IP_CONFIG_SOURCE_KERNEL && new->addr_source != item_old.addr_source) || nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) { item->timestamp = item_old.timestamp; item->lifetime = item_old.lifetime; @@ -1356,7 +1370,7 @@ nm_ip6_config_del_address (NMIP6Config *config, guint i) guint nm_ip6_config_get_num_addresses (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->addresses->len; } @@ -1364,7 +1378,7 @@ nm_ip6_config_get_num_addresses (const NMIP6Config *config) const NMPlatformIP6Address * nm_ip6_config_get_address (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return &g_array_index (priv->addresses, NMPlatformIP6Address, i); } @@ -1379,7 +1393,7 @@ nm_ip6_config_address_exists (const NMIP6Config *config, const NMPlatformIP6Address * nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolean linklocal) { - NMIP6ConfigPrivate *priv; + const NMIP6ConfigPrivate *priv; guint i; g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); @@ -1399,6 +1413,47 @@ nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolea return NULL; } +/** + * nm_ip6_config_has_dad_pending_addresses + * @self: configuration containing the addresses to check + * @candidates: configuration with the list of addresses we are + * interested in + * + * Check whether there are addresses with DAD pending in @self, that + * are also contained in @candidates. + * + * Returns: %TRUE if at least one matching address was found, %FALSE + * otherwise + */ +gboolean +nm_ip6_config_has_any_dad_pending (const NMIP6Config *self, + const NMIP6Config *candidates) +{ + const NMPlatformIP6Address *addr, *addr_c; + guint i, j, num, num_c; + + num = nm_ip6_config_get_num_addresses (self); + + for (i = 0; i < num; i++) { + addr = nm_ip6_config_get_address (self, i); + if ( NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_DADFAILED) + && !NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + + num_c = nm_ip6_config_get_num_addresses (candidates); + + for (j = 0; j < num_c; j++) { + addr_c = nm_ip6_config_get_address (candidates, j); + if ( addresses_are_duplicate (addr, addr_c) + && addr->plen == addr_c->plen) + return TRUE; + } + } + } + + return FALSE; +} + /******************************************************************/ void @@ -1432,7 +1487,7 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) g_return_if_fail (new != NULL); g_return_if_fail (new->plen > 0 && new->plen <= 128); - g_assert (priv->ifindex); + g_return_if_fail (priv->ifindex > 0); for (i = 0; i < priv->routes->len; i++ ) { NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i); @@ -1440,10 +1495,10 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) if (routes_are_duplicate (item, new, FALSE)) { if (nm_platform_ip6_route_cmp (item, new) == 0) return; - old_source = item->source; + old_source = item->rt_source; *item = *new; /* Restore highest priority source */ - item->source = MAX (old_source, new->source); + item->rt_source = MAX (old_source, new->rt_source); item->ifindex = priv->ifindex; goto NOTIFY; } @@ -1471,7 +1526,7 @@ nm_ip6_config_del_route (NMIP6Config *config, guint i) guint nm_ip6_config_get_num_routes (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->routes->len; } @@ -1479,7 +1534,7 @@ nm_ip6_config_get_num_routes (const NMIP6Config *config) const NMPlatformIP6Route * nm_ip6_config_get_route (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return &g_array_index (priv->routes, NMPlatformIP6Route, i); } @@ -1487,7 +1542,7 @@ nm_ip6_config_get_route (const NMIP6Config *config, guint i) const NMPlatformIP6Route * nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); guint i; NMPlatformIP6Route *best_route = NULL; @@ -1518,7 +1573,7 @@ nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct const NMPlatformIP6Address * nm_ip6_config_get_subnet_for_host (const NMIP6Config *config, const struct in6_addr *host) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); guint i; NMPlatformIP6Address *subnet = NULL; struct in6_addr subnet2, host2; @@ -1585,7 +1640,7 @@ nm_ip6_config_del_nameserver (NMIP6Config *config, guint i) guint32 nm_ip6_config_get_num_nameservers (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->nameservers->len; } @@ -1593,7 +1648,7 @@ nm_ip6_config_get_num_nameservers (const NMIP6Config *config) const struct in6_addr * nm_ip6_config_get_nameserver (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return &g_array_index (priv->nameservers, struct in6_addr, i); } @@ -1642,7 +1697,7 @@ nm_ip6_config_del_domain (NMIP6Config *config, guint i) guint32 nm_ip6_config_get_num_domains (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->domains->len; } @@ -1650,7 +1705,7 @@ nm_ip6_config_get_num_domains (const NMIP6Config *config) const char * nm_ip6_config_get_domain (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->domains, i); } @@ -1714,7 +1769,7 @@ nm_ip6_config_del_search (NMIP6Config *config, guint i) guint32 nm_ip6_config_get_num_searches (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->searches->len; } @@ -1722,7 +1777,7 @@ nm_ip6_config_get_num_searches (const NMIP6Config *config) const char * nm_ip6_config_get_search (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->searches, i); } @@ -1771,7 +1826,7 @@ nm_ip6_config_del_dns_option (NMIP6Config *config, guint i) guint32 nm_ip6_config_get_num_dns_options (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->dns_options->len; } @@ -1779,7 +1834,7 @@ nm_ip6_config_get_num_dns_options (const NMIP6Config *config) const char * nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return g_ptr_array_index (priv->dns_options, i); } @@ -1818,7 +1873,7 @@ nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss) guint32 nm_ip6_config_get_mss (const NMIP6Config *config) { - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); return priv->mss; } @@ -1933,10 +1988,7 @@ nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b) static void nm_ip6_config_init (NMIP6Config *config) { - NMIP6ConfigPrivate *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE (config, NM_TYPE_IP6_CONFIG, NMIP6ConfigPrivate); - config->priv = priv; + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); priv->addresses = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Address)); priv->routes = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Route)); @@ -1985,7 +2037,7 @@ nameservers_to_gvalue (GArray *array, GValue *value) static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMIP6Config *config = NM_IP6_CONFIG (object); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); @@ -2159,8 +2211,6 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) GObjectClass *object_class = G_OBJECT_CLASS (config_class); NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); - g_type_class_add_private (config_class, sizeof (NMIP6ConfigPrivate)); - exported_object_class->export_path = NM_DBUS_PATH "/IP6Config/%u"; /* virtual methods */ @@ -2170,66 +2220,66 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) /* properties */ obj_properties[PROP_IFINDEX] = - g_param_spec_int (NM_IP6_CONFIG_IFINDEX, "", "", - -1, G_MAXINT, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + g_param_spec_int (NM_IP6_CONFIG_IFINDEX, "", "", + -1, G_MAXINT, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESS_DATA] = - g_param_spec_variant (NM_IP6_CONFIG_ADDRESS_DATA, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP6_CONFIG_ADDRESS_DATA, "", "", + G_VARIANT_TYPE ("aa{sv}"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESSES] = - g_param_spec_variant (NM_IP6_CONFIG_ADDRESSES, "", "", - G_VARIANT_TYPE ("a(ayuay)"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP6_CONFIG_ADDRESSES, "", "", + G_VARIANT_TYPE ("a(ayuay)"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTE_DATA] = - g_param_spec_variant (NM_IP6_CONFIG_ROUTE_DATA, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP6_CONFIG_ROUTE_DATA, "", "", + G_VARIANT_TYPE ("aa{sv}"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTES] = - g_param_spec_variant (NM_IP6_CONFIG_ROUTES, "", "", - G_VARIANT_TYPE ("a(ayuayu)"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP6_CONFIG_ROUTES, "", "", + G_VARIANT_TYPE ("a(ayuayu)"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_GATEWAY] = - g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = - g_param_spec_variant (NM_IP6_CONFIG_NAMESERVERS, "", "", - G_VARIANT_TYPE ("aay"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_IP6_CONFIG_NAMESERVERS, "", "", + G_VARIANT_TYPE ("aay"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DOMAINS] = - g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_SEARCHES] = - g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DNS_OPTIONS] = - g_param_spec_boxed (NM_IP6_CONFIG_DNS_OPTIONS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_boxed (NM_IP6_CONFIG_DNS_OPTIONS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DNS_PRIORITY] = - g_param_spec_int (NM_IP6_CONFIG_DNS_PRIORITY, "", "", - G_MININT32, G_MAXINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_int (NM_IP6_CONFIG_DNS_PRIORITY, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 010b1396..c3f8d9f8 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -33,18 +33,7 @@ #define NM_IS_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP6_CONFIG)) #define NM_IP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass)) -struct _NMIP6ConfigPrivate; - -struct _NMIP6Config { - NMExportedObject parent; - - /* private */ - struct _NMIP6ConfigPrivate *priv; -}; - -typedef struct { - NMExportedObjectClass parent; -} NMIP6ConfigClass; +typedef struct _NMIP6ConfigClass NMIP6ConfigClass; /* internal */ #define NM_IP6_CONFIG_IFINDEX "ifindex" @@ -101,6 +90,8 @@ const NMPlatformIP6Address *nm_ip6_config_get_address (const NMIP6Config *config const NMPlatformIP6Address *nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolean linklocal); gboolean nm_ip6_config_address_exists (const NMIP6Config *config, const NMPlatformIP6Address *address); gboolean nm_ip6_config_addresses_sort (NMIP6Config *config, NMSettingIP6ConfigPrivacy use_temporary); +gboolean nm_ip6_config_has_any_dad_pending (const NMIP6Config *self, + const NMIP6Config *candidates); /* Routes */ void nm_ip6_config_reset_routes (NMIP6Config *config); diff --git a/src/nm-logging.c b/src/nm-logging.c index 935b34a8..3db8d20c 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -32,11 +32,6 @@ #include <strings.h> #include <string.h> -#if defined (NO_SYSTEMD_JOURNAL) && defined (SYSTEMD_JOURNAL) -#undef SYSTEMD_JOURNAL -#define SYSTEMD_JOURNAL 0 -#endif - #if SYSTEMD_JOURNAL #define SD_JOURNAL_SUPPRESS_LOCATION #include <systemd/sd-journal.h> @@ -45,38 +40,6 @@ #include "nm-errors.h" #include "nm-core-utils.h" -typedef enum { - LOG_FORMAT_FLAG_NONE = 0, - LOG_FORMAT_FLAG_TIMESTAMP_DEBUG = (1LL << 0), - LOG_FORMAT_FLAG_TIMESTAMP_INFO = (1LL << 1), - LOG_FORMAT_FLAG_TIMESTAMP_ERROR = (1LL << 2), - LOG_FORMAT_FLAG_LOCATION_DEBUG = (1LL << 3), - LOG_FORMAT_FLAG_LOCATION_INFO = (1LL << 4), - LOG_FORMAT_FLAG_LOCATION_ERROR = (1LL << 5), - LOG_FORMAT_FLAG_ALIGN_LOCATION = (1LL << 6), - - _LOG_FORMAT_FLAG_TIMESTAMP = LOG_FORMAT_FLAG_TIMESTAMP_DEBUG | - LOG_FORMAT_FLAG_TIMESTAMP_INFO | - LOG_FORMAT_FLAG_TIMESTAMP_ERROR, - _LOG_FORMAT_FLAG_LOCATION = LOG_FORMAT_FLAG_LOCATION_DEBUG | - LOG_FORMAT_FLAG_LOCATION_INFO | - LOG_FORMAT_FLAG_LOCATION_ERROR, - - _LOG_FORMAT_FLAG_LEVEL_DEBUG = LOG_FORMAT_FLAG_TIMESTAMP_DEBUG | - LOG_FORMAT_FLAG_LOCATION_DEBUG, - _LOG_FORMAT_FLAG_LEVEL_INFO = LOG_FORMAT_FLAG_TIMESTAMP_INFO | - LOG_FORMAT_FLAG_LOCATION_INFO, - _LOG_FORMAT_FLAG_LEVEL_ERROR = LOG_FORMAT_FLAG_TIMESTAMP_ERROR | - LOG_FORMAT_FLAG_LOCATION_ERROR, - - _LOG_FORMAT_FLAG_SYSLOG = _LOG_FORMAT_FLAG_TIMESTAMP | - LOG_FORMAT_FLAG_LOCATION_DEBUG | - LOG_FORMAT_FLAG_LOCATION_ERROR | - LOG_FORMAT_FLAG_ALIGN_LOCATION, - - _LOG_FORMAT_FLAG_DEFAULT = _LOG_FORMAT_FLAG_TIMESTAMP, -} LogFormatFlags; - void (*_nm_logging_clear_platform_logging_cache) (void); static void @@ -93,16 +56,32 @@ typedef struct { typedef struct { const char *name; const char *level_str; + + /* nm-logging uses syslog internally. Note that the three most-verbose syslog levels + * are LOG_DEBUG, LOG_INFO and LOG_NOTICE. Journal already highlights LOG_NOTICE + * as special. + * + * On the other hand, we have three levels LOGL_TRACE, LOGL_DEBUG and LOGL_INFO, + * which are regular messages not to be highlighted. For that reason, we must map + * LOGL_TRACE and LOGL_DEBUG both to syslog level LOG_DEBUG. */ int syslog_level; + GLogLevelFlags g_log_level; - LogFormatFlags log_format_level; } LogLevelDesc; +NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL] = { + /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); + * + * Note: LOGD_VPN_PLUGIN is special and must be disabled for + * DEBUG and TRACE levels. */ + [LOGL_INFO] = LOGD_DEFAULT, + [LOGL_WARN] = LOGD_DEFAULT, + [LOGL_ERR] = LOGD_DEFAULT, +}; + static struct { NMLogLevel log_level; - NMLogDomain logging[_LOGL_N_REAL]; - gboolean logging_set_up; - LogFormatFlags log_format_flags; + bool uses_syslog:1; enum { LOG_BACKEND_GLIB, LOG_BACKEND_SYSLOG, @@ -111,22 +90,22 @@ static struct { char *logging_domains_to_string; const LogLevelDesc level_desc[_LOGL_N]; -#define _DOMAIN_DESC_LEN 37 +#define _DOMAIN_DESC_LEN 38 /* Would be nice to use C99 flexible array member here, * but that feature doesn't seem well supported. */ const LogDesc domain_desc[_DOMAIN_DESC_LEN]; } global = { + /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); */ .log_level = LOGL_INFO, .log_backend = LOG_BACKEND_GLIB, - .log_format_flags = _LOG_FORMAT_FLAG_DEFAULT, .level_desc = { - [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG }, - [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG }, - [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_INFO, _LOG_FORMAT_FLAG_LEVEL_INFO }, - [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_MESSAGE, _LOG_FORMAT_FLAG_LEVEL_INFO }, - [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_MESSAGE, _LOG_FORMAT_FLAG_LEVEL_ERROR }, - [_LOGL_OFF] = { "OFF", NULL, 0, 0, 0 }, - [_LOGL_KEEP] = { "KEEP", NULL, 0, 0, 0 }, + [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, }, + [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, }, + [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_INFO, }, + [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_MESSAGE, }, + [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_MESSAGE, }, + [_LOGL_OFF] = { "OFF", NULL, 0, 0, }, + [_LOGL_KEEP] = { "KEEP", NULL, 0, 0, }, }, .domain_desc = { { LOGD_PLATFORM, "PLATFORM" }, @@ -165,6 +144,7 @@ static struct { { LOGD_DISPATCH, "DISPATCH" }, { LOGD_AUDIT, "AUDIT" }, { LOGD_SYSTEMD, "SYSTEMD" }, + { LOGD_VPN_PLUGIN,"VPN_PLUGIN" }, { 0, NULL } /* keep _DOMAIN_DESC_LEN in sync */ }, @@ -185,19 +165,6 @@ static char *_domains_to_string (gboolean include_level_override); /************************************************************************/ -static void -_ensure_initialized (void) -{ - if (G_UNLIKELY (!global.logging_set_up)) { - int errsv = errno; - - nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); - - /* must ensure that errno is not modified. */ - errno = errsv; - } -} - static gboolean match_log_level (const char *level, NMLogLevel *out_level, @@ -224,7 +191,7 @@ nm_logging_setup (const char *level, GError **error) { GString *unrecognized = NULL; - NMLogDomain new_logging[G_N_ELEMENTS (global.logging)]; + NMLogDomain new_logging[G_N_ELEMENTS (_nm_logging_enabled_state)]; NMLogLevel new_log_level = global.log_level; char **tmp, **iter; int i; @@ -235,13 +202,8 @@ nm_logging_setup (const char *level, g_return_val_if_fail (!error || !*error, FALSE); /* domains */ - if (!domains || !*domains) { - domains = global.logging_set_up - ? (domains_free = _domains_to_string (FALSE)) - : LOGD_DEFAULT_STRING; - } - - global.logging_set_up = TRUE; + if (!domains || !*domains) + domains = (domains_free = _domains_to_string (FALSE)); for (i = 0; i < G_N_ELEMENTS (new_logging); i++) new_logging[i] = 0; @@ -253,7 +215,7 @@ nm_logging_setup (const char *level, if (new_log_level == _LOGL_KEEP) { new_log_level = global.log_level; for (i = 0; i < G_N_ELEMENTS (new_logging); i++) - new_logging[i] = global.logging[i]; + new_logging[i] = _nm_logging_enabled_state[i]; } } @@ -264,6 +226,11 @@ nm_logging_setup (const char *level, NMLogDomain bits; char *p; + /* LOGD_VPN_PLUGIN is protected, that is, when setting ALL or DEFAULT, + * it does not enable the verbose levels DEBUG and TRACE, because that + * may expose sensitive data. */ + NMLogDomain protect = LOGD_NONE; + if (!strlen (*iter)) continue; @@ -280,11 +247,13 @@ nm_logging_setup (const char *level, bits = 0; /* Check for combined domains */ - if (!g_ascii_strcasecmp (*iter, LOGD_ALL_STRING)) + if (!g_ascii_strcasecmp (*iter, LOGD_ALL_STRING)) { bits = LOGD_ALL; - else if (!g_ascii_strcasecmp (*iter, LOGD_DEFAULT_STRING)) + protect = LOGD_VPN_PLUGIN; + } else if (!g_ascii_strcasecmp (*iter, LOGD_DEFAULT_STRING)) { bits = LOGD_DEFAULT; - else if (!g_ascii_strcasecmp (*iter, LOGD_DHCP_STRING)) + protect = LOGD_VPN_PLUGIN; + } else if (!g_ascii_strcasecmp (*iter, LOGD_DHCP_STRING)) bits = LOGD_DHCP; else if (!g_ascii_strcasecmp (*iter, LOGD_IP_STRING)) bits = LOGD_IP; @@ -321,13 +290,17 @@ nm_logging_setup (const char *level, if (domain_log_level == _LOGL_KEEP) { for (i = 0; i < G_N_ELEMENTS (new_logging); i++) - new_logging[i] = (new_logging[i] & ~bits) | (global.logging[i] & bits); + new_logging[i] = (new_logging[i] & ~bits) | (_nm_logging_enabled_state[i] & bits); } else { for (i = 0; i < G_N_ELEMENTS (new_logging); i++) { if (i < domain_log_level) new_logging[i] &= ~bits; - else + else { new_logging[i] |= bits; + if ( protect + && i < LOGL_INFO) + new_logging[i] &= ~protect; + } } } } @@ -339,7 +312,7 @@ nm_logging_setup (const char *level, global.log_level = new_log_level; for (i = 0; i < G_N_ELEMENTS (new_logging); i++) - global.logging[i] = new_logging[i]; + _nm_logging_enabled_state[i] = new_logging[i]; if ( had_platform_debug && _nm_logging_clear_platform_logging_cache @@ -384,8 +357,6 @@ nm_logging_all_levels_to_string (void) const char * nm_logging_domains_to_string (void) { - _ensure_initialized (); - if (G_UNLIKELY (!global.logging_domains_to_string)) global.logging_domains_to_string = _domains_to_string (TRUE); @@ -406,7 +377,7 @@ _domains_to_string (gboolean include_level_override) str = g_string_sized_new (75); for (diter = &global.domain_desc[0]; diter->name; diter++) { /* If it's set for any lower level, it will also be set for LOGL_ERR */ - if (!(diter->num & global.logging[LOGL_ERR])) + if (!(diter->num & _nm_logging_enabled_state[LOGL_ERR])) continue; if (str->len) @@ -418,15 +389,15 @@ _domains_to_string (gboolean include_level_override) /* Check if it's logging at a lower level than the default. */ for (i = 0; i < global.log_level; i++) { - if (diter->num & global.logging[i]) { + if (diter->num & _nm_logging_enabled_state[i]) { g_string_append_printf (str, ":%s", global.level_desc[i].name); break; } } /* Check if it's logging at a higher level than the default. */ - if (!(diter->num & global.logging[global.log_level])) { - for (i = global.log_level + 1; i < G_N_ELEMENTS (global.logging); i++) { - if (diter->num & global.logging[i]) { + if (!(diter->num & _nm_logging_enabled_state[global.log_level])) { + for (i = global.log_level + 1; i < G_N_ELEMENTS (_nm_logging_enabled_state); i++) { + if (diter->num & _nm_logging_enabled_state[i]) { g_string_append_printf (str, ":%s", global.level_desc[i].name); break; } @@ -459,20 +430,29 @@ nm_logging_all_domains_to_string (void) return str->str; } -gboolean -nm_logging_enabled (NMLogLevel level, NMLogDomain domain) +/** + * nm_logging_get_level: + * @domain: find the lowest enabled logging level for the + * given domain. If this is a set of multiple + * domains, the most verbose level will be returned. + * + * Returns: the lowest (most verbose) logging level for the + * give @domain, or %_LOGL_OFF if it is disabled. + **/ +NMLogLevel +nm_logging_get_level (NMLogDomain domain) { - if ((guint) level >= G_N_ELEMENTS (global.logging)) - g_return_val_if_reached (FALSE); - - /* This function is guaranteed not to modify errno. */ - _ensure_initialized (); + NMLogLevel sl = _LOGL_OFF; - return !!(global.logging[level] & domain); + G_STATIC_ASSERT (LOGL_TRACE == 0); + while ( sl > LOGL_TRACE + && nm_logging_enabled (sl - 1, domain)) + sl--; + return sl; } #if SYSTEMD_JOURNAL -__attribute__((__format__ (__printf__, 4, 5))) +_nm_printf (4, 5) static void _iovec_set_format (struct iovec *iov, gboolean *iov_free, int i, const char *format, ...) { @@ -512,15 +492,12 @@ _nm_log_impl (const char *file, char *msg; char *fullmsg; char s_buf_timestamp[64]; - char s_buf_location[1024]; GTimeVal tv; - if ((guint) level >= G_N_ELEMENTS (global.logging)) + if ((guint) level >= G_N_ELEMENTS (_nm_logging_enabled_state)) g_return_if_reached (); - _ensure_initialized (); - - if (!(global.logging[level] & domain)) + if (!(_nm_logging_enabled_state[level] & domain)) return; /* Make sure that %m maps to the specified error */ @@ -534,51 +511,8 @@ _nm_log_impl (const char *file, msg = g_strdup_vprintf (fmt, args); va_end (args); - if (NM_FLAGS_ANY (global.log_format_flags, global.level_desc[level].log_format_level & _LOG_FORMAT_FLAG_TIMESTAMP)) { - g_get_current_time (&tv); - nm_sprintf_buf (s_buf_timestamp, " [%ld.%04ld]", tv.tv_sec, (tv.tv_usec + 50) / 100); - } else - s_buf_timestamp[0] = '\0'; - - s_buf_location[0] = '\0'; - if (NM_FLAGS_ANY (global.log_format_flags, global.level_desc[level].log_format_level & _LOG_FORMAT_FLAG_LOCATION)) { -#define MAX_LEN_FILE 37 -#define MAX_LEN_FUNC 26 - gsize l = sizeof (s_buf_location); - char *p = s_buf_location, *p_buf; - gsize len; - char s_buf[MAX (MAX_LEN_FILE, MAX_LEN_FUNC) + 30]; - - if (file) { - if (NM_FLAGS_HAS (global.log_format_flags, LOG_FORMAT_FLAG_ALIGN_LOCATION)) { - /* left-align the "[file:line]" string, but truncate from left to MAX_LEN_FILE chars. */ - len = strlen (file); - nm_sprintf_buf (s_buf, "[%s:%u]", - len > MAX_LEN_FILE ? &file[len - MAX_LEN_FILE] : file, - line); - len = strlen (s_buf); - if (len > MAX_LEN_FILE) { - p_buf = &s_buf[len - MAX_LEN_FILE]; - p_buf[0] = '['; - } else - p_buf = s_buf; - nm_utils_strbuf_append (&p, &l, " %-"G_STRINGIFY (MAX_LEN_FILE)"s", p_buf); - } else - nm_utils_strbuf_append (&p, &l, " [%s:%u]", file, line); - } - if (func) { - if (NM_FLAGS_HAS (global.log_format_flags, LOG_FORMAT_FLAG_ALIGN_LOCATION)) { - /* left-align the "func():" string, but truncate from left to MAX_LEN_FUNC chars. */ - len = strlen (func); - nm_sprintf_buf (s_buf, "%s():", - len > MAX_LEN_FUNC ? &func[len - MAX_LEN_FUNC] : func); - len = strlen (s_buf); - nm_utils_strbuf_append (&p, &l, " %-"G_STRINGIFY (MAX_LEN_FUNC)"s", - len > MAX_LEN_FUNC ? &s_buf[len - MAX_LEN_FUNC] : s_buf); - } else - nm_utils_strbuf_append (&p, &l, " %s():", func); - } - } + g_get_current_time (&tv); + nm_sprintf_buf (s_buf_timestamp, " [%ld.%04ld]", tv.tv_sec, (tv.tv_usec + 50) / 100); switch (global.log_backend) { #if SYSTEMD_JOURNAL @@ -596,10 +530,9 @@ _nm_log_impl (const char *file, _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", global.level_desc[level].syslog_level); _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=" - "%-7s%s%s %s", + "%-7s%s %s", global.level_desc[level].level_str, s_buf_timestamp, - s_buf_location, msg); _iovec_set_literal_string (iov, iov_free, i_field++, "SYSLOG_IDENTIFIER=" G_LOG_DOMAIN); _iovec_set_format (iov, iov_free, i_field++, "SYSLOG_PID=%ld", (long) getpid ()); @@ -609,7 +542,7 @@ _nm_log_impl (const char *file, const char *s_domain_1 = NULL; GString *s_domain_all = NULL; NMLogDomain dom_all = domain; - NMLogDomain dom = dom_all & global.logging[level]; + NMLogDomain dom = dom_all & _nm_logging_enabled_state[level]; for (diter = &global.domain_desc[0]; diter->name; diter++) { if (!NM_FLAGS_HAS (dom_all, diter->num)) @@ -646,7 +579,8 @@ _nm_log_impl (const char *file, _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_DOMAINS=%s", s_domain_1); } _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_LEVEL=%s", global.level_desc[level].name); - _iovec_set_format (iov, iov_free, i_field++, "CODE_FUNC=%s", func ?: ""); + if (func) + _iovec_set_format (iov, iov_free, i_field++, "CODE_FUNC=%s", func); _iovec_set_format (iov, iov_free, i_field++, "CODE_FILE=%s", file ?: ""); _iovec_set_format (iov, iov_free, i_field++, "CODE_LINE=%u", line); _iovec_set_format (iov, iov_free, i_field++, "TIMESTAMP_MONOTONIC=%lld.%06lld", (long long) (now / NM_UTILS_NS_PER_SECOND), (long long) ((now % NM_UTILS_NS_PER_SECOND) / 1000)); @@ -667,10 +601,9 @@ _nm_log_impl (const char *file, break; #endif default: - fullmsg = g_strdup_printf ("%-7s%s%s %s", + fullmsg = g_strdup_printf ("%-7s%s %s", global.level_desc[level].level_str, s_buf_timestamp, - s_buf_location, msg); if (global.log_backend == LOG_BACKEND_SYSLOG) @@ -744,25 +677,28 @@ nm_log_handler (const gchar *log_domain, } } +gboolean +nm_logging_syslog_enabled (void) +{ + return global.uses_syslog; +} + void nm_logging_syslog_openlog (const char *logging_backend) { - LogFormatFlags log_format_flags; - if (global.log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); if (!logging_backend) logging_backend = ""NM_CONFIG_LOGGING_BACKEND_DEFAULT; - log_format_flags = _LOG_FORMAT_FLAG_DEFAULT; - if (strcmp (logging_backend, "debug") == 0) { global.log_backend = LOG_BACKEND_SYSLOG; openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); #if SYSTEMD_JOURNAL } else if (strcmp (logging_backend, "syslog") != 0) { global.log_backend = LOG_BACKEND_JOURNAL; + global.uses_syslog = TRUE; /* ensure we read a monotonic timestamp. Reading the timestamp the first * time causes a logging message. We don't want to do that during _nm_log_impl. */ @@ -770,11 +706,10 @@ nm_logging_syslog_openlog (const char *logging_backend) #endif } else { global.log_backend = LOG_BACKEND_SYSLOG; + global.uses_syslog = TRUE; openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); } - global.log_format_flags = log_format_flags; - g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, nm_log_handler, diff --git a/src/nm-logging.h b/src/nm-logging.h index 27f89f5d..9e2b0108 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -65,12 +65,14 @@ typedef enum { /*< skip >*/ LOGD_DISPATCH = (1LL << 33), LOGD_AUDIT = (1LL << 34), LOGD_SYSTEMD = (1LL << 35), + LOGD_VPN_PLUGIN = (1LL << 36), __LOGD_MAX, - LOGD_ALL = ((__LOGD_MAX - 1LL) << 1) - 1LL, + LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL), LOGD_DEFAULT = LOGD_ALL & ~( LOGD_DBUS_PROPS | LOGD_WIFI_SCAN | + LOGD_VPN_PLUGIN | 0), /* aliases: */ @@ -101,12 +103,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__) +//#define _NM_LOG_FUNC G_STRFUNC +#define _NM_LOG_FUNC NULL + /* 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__); \ + _nm_log_impl (__FILE__, __LINE__, \ + _NM_LOG_FUNC, \ + (level), \ + (domain), \ + (error), \ + ""__VA_ARGS__); \ } G_STMT_END /* nm_log() only evaluates it's argument list after checking @@ -154,11 +164,21 @@ void _nm_log_impl (const char *file, NMLogDomain domain, int error, const char *fmt, - ...) __attribute__((__format__ (__printf__, 7, 8))); + ...) _nm_printf (7, 8); const char *nm_logging_level_to_string (void); const char *nm_logging_domains_to_string (void); -gboolean nm_logging_enabled (NMLogLevel level, NMLogDomain domain); + +extern NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL]; +static inline gboolean +nm_logging_enabled (NMLogLevel level, NMLogDomain domain) +{ + nm_assert (((guint) level) < G_N_ELEMENTS (_nm_logging_enabled_state)); + return (((guint) level) < G_N_ELEMENTS (_nm_logging_enabled_state)) + && !!(_nm_logging_enabled_state[level] & domain); +} + +NMLogLevel nm_logging_get_level (NMLogDomain domain); const char *nm_logging_all_levels_to_string (void); const char *nm_logging_all_domains_to_string (void); @@ -168,6 +188,7 @@ gboolean nm_logging_setup (const char *level, char **bad_domains, GError **error); void nm_logging_syslog_openlog (const char *logging_backend); +gboolean nm_logging_syslog_enabled (void); /*****************************************************************************/ diff --git a/src/nm-manager.c b/src/nm-manager.c index 8277f6b0..5794bb9a 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -21,13 +21,14 @@ #include "nm-default.h" +#include "nm-manager.h" + #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <unistd.h> -#include "nm-manager.h" #include "nm-common-macros.h" #include "nm-bus-manager.h" #include "nm-vpn-manager.h" @@ -46,13 +47,14 @@ #include "nm-sleep-monitor.h" #include "nm-connectivity.h" #include "nm-policy.h" -#include "nm-connection-provider.h" #include "nm-session-monitor.h" #include "nm-activation-request.h" #include "nm-core-internal.h" #include "nm-config.h" #include "nm-audit-manager.h" #include "nm-dbus-compat.h" +#include "nm-checkpoint.h" +#include "nm-checkpoint-manager.h" #include "NetworkManagerUtils.h" #include "nmdbus-manager.h" @@ -91,15 +93,13 @@ typedef struct { gboolean sw_enabled; gboolean hw_enabled; RfKillType rtype; + NMConfigRunStatePropertyType key; const char *desc; - const char *key; const char *prop; const char *hw_prop; } RadioState; typedef struct { - char *state_file; - GSList *active_connections; GSList *authorizing_connections; guint ac_cleanup_id; @@ -121,6 +121,8 @@ typedef struct { } prop_filter; NMRfkillManager *rfkill_mgr; + NMCheckpointManager *checkpoint_mgr; + NMSettings *settings; char *hostname; @@ -132,6 +134,8 @@ typedef struct { NMSleepMonitor *sleep_monitor; + NMAuthManager *auth_mgr; + GSList *auth_chains; GHashTable *sleep_devices; @@ -145,7 +149,27 @@ typedef struct { gboolean devices_inited; } NMManagerPrivate; -#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate)) +struct _NMManager { + NMExportedObject parent; + NMManagerPrivate _priv; +}; + +typedef struct { + NMExportedObjectClass parent; +} NMManagerClass; + +#define NM_MANAGER_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMManager *_self2 = (_self); \ + \ + nm_assert (NM_IS_MANAGER (_self)); \ + &_self->_priv; \ + }) G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT) @@ -168,7 +192,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; NM_GOBJECT_PROPERTIES_DEFINE (NMManager, PROP_VERSION, PROP_STATE, - PROP_STATE_FILE, PROP_STARTUP, PROP_NETWORKING_ENABLED, PROP_WIRELESS_ENABLED, @@ -402,7 +425,7 @@ find_ac_for_connection (NMManager *manager, NMConnection *connection) } /* Filter out connections that are already active. - * nm_settings_get_connections() returns sorted list. We need to preserve the + * nm_settings_get_connections_sorted() returns sorted list. We need to preserve the * order so that we didn't change auto-activation order (recent timestamps * are first). * Caller is responsible for freeing the returned list with g_slist_free(). @@ -411,7 +434,7 @@ GSList * nm_manager_get_activatable_connections (NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - GSList *all_connections = nm_settings_get_connections (priv->settings); + GSList *all_connections = nm_settings_get_connections_sorted (priv->settings); GSList *connections = NULL, *iter; NMSettingsConnection *connection; @@ -559,7 +582,7 @@ impl_manager_reload (NMManager *self, /************************************************************************/ -static NMDevice * +NMDevice * nm_manager_get_device_by_path (NMManager *manager, const char *path) { GSList *iter; @@ -589,7 +612,7 @@ nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex) } static NMDevice * -find_device_by_hw_addr (NMManager *manager, const char *hwaddr) +find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr) { GSList *iter; const char *device_addr; @@ -598,7 +621,7 @@ find_device_by_hw_addr (NMManager *manager, const char *hwaddr) if (nm_utils_hwaddr_valid (hwaddr, -1)) { for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - device_addr = nm_device_get_hw_address (NM_DEVICE (iter->data)); + device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data), FALSE); if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1)) return NM_DEVICE (iter->data); } @@ -906,7 +929,7 @@ check_if_startup_complete (NMManager *self) g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self); } - if (nm_config_get_configure_and_quit (nm_config_get ())) + if (nm_config_get_configure_and_quit (priv->config)) g_signal_emit (self, signals[CONFIGURE_QUIT], 0); } @@ -939,28 +962,12 @@ remove_device (NMManager *self, nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE)); if (allow_unmanage && nm_device_get_managed (device, FALSE)) { - unmanage = TRUE; - if (!quitting) { + if (quitting) + unmanage = nm_device_unmanage_on_quit (device); + else { /* the device is already gone. Unmanage it. */ - } else { - /* Leave certain devices alone when quitting so their configuration - * can be taken over when NM restarts. This ensures connectivity while - * NM is stopped. - */ - if (nm_device_uses_assumed_connection (device)) { - /* An assume connection must be left alone */ - unmanage = FALSE; - } else if (!nm_device_get_act_request (device)) { - /* a device without any active connection is either UNAVAILABLE or DISCONNECTED - * state. Since we don't know whether the device was upped by NetworkManager, - * we must leave it up on exit. */ - unmanage = FALSE; - } else if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (device))) { - /* The device has no layer 3 configuration. Leave it up. */ - unmanage = FALSE; - } else if (nm_device_can_assume_active_connection (device)) - unmanage = FALSE; + unmanage = TRUE; } if (unmanage) { @@ -968,7 +975,7 @@ remove_device (NMManager *self, nm_device_set_unmanaged_by_quitting (device); else nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED); - } else if (quitting && nm_config_get_configure_and_quit (nm_config_get ())) { + } else if (quitting && nm_config_get_configure_and_quit (priv->config)) { nm_device_spawn_iface_helper (device); } } @@ -1048,7 +1055,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM return parent; /* Maybe a hardware address */ - parent = find_device_by_hw_addr (self, parent_name); + parent = find_device_by_permanent_hw_addr (self, parent_name); if (parent) return parent; @@ -1224,7 +1231,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) } /* Create backing resources if the device has any autoconnect connections */ - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *candidate = iter->data; NMSettingConnection *s_con; @@ -1259,7 +1266,7 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device) g_return_if_fail (device); - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *candidate = iter->data; gs_free_error GError *error = NULL; @@ -1328,7 +1335,7 @@ system_unmanaged_devices_changed_cb (NMSettings *settings, unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); for (iter = priv->devices; iter; iter = g_slist_next (iter)) - nm_device_set_unmanaged_by_user_config (NM_DEVICE (iter->data), unmanaged_specs); + nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data), unmanaged_specs); } static void @@ -1367,54 +1374,6 @@ system_hostname_changed_cb (NMSettings *settings, /* General NMManager stuff */ /*******************************************************************/ -/* Store value into key-file; supported types: boolean, int, string */ -static gboolean -write_value_to_state_file (const char *filename, - const char *group, - const char *key, - GType value_type, - gpointer value, - GError **error) -{ - GKeyFile *key_file; - char *data; - gsize len = 0; - gboolean ret = FALSE; - - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (group != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (value_type == G_TYPE_BOOLEAN || - value_type == G_TYPE_INT || - value_type == G_TYPE_STRING, - FALSE); - - key_file = g_key_file_new (); - - g_key_file_set_list_separator (key_file, ','); - g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL); - switch (value_type) { - case G_TYPE_BOOLEAN: - g_key_file_set_boolean (key_file, group, key, *((gboolean *) value)); - break; - case G_TYPE_INT: - g_key_file_set_integer (key_file, group, key, *((gint *) value)); - break; - case G_TYPE_STRING: - g_key_file_set_string (key_file, group, key, *((const gchar **) value)); - break; - } - - data = g_key_file_to_data (key_file, &len, NULL); - if (data) { - ret = g_file_set_contents (filename, data, len, error); - g_free (data); - } - g_key_file_free (key_file); - - return ret; -} - static gboolean radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable) { @@ -2043,7 +2002,7 @@ add_device (NMManager *self, NMDevice *device, GError **error) type_desc = nm_device_get_type_desc (device); g_assert (type_desc); - nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings)); + nm_device_set_unmanaged_by_user_settings (device, nm_settings_get_unmanaged_specs (priv->settings)); nm_device_set_unmanaged_flags (device, NM_UNMANAGED_SLEEPING, @@ -2098,11 +2057,12 @@ factory_component_added_cb (NMDeviceFactory *factory, GObject *component, gpointer user_data) { + NMManager *self = user_data; GSList *iter; - g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE); + g_return_val_if_fail (self, FALSE); - for (iter = NM_MANAGER_GET_PRIVATE (user_data)->devices; iter; iter = iter->next) { + for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) { if (nm_device_notify_component_added ((NMDevice *) iter->data, component)) return TRUE; } @@ -2178,6 +2138,9 @@ platform_link_added (NMManager *self, if (!ignore) { _LOGW (LOGD_HW, "%s: factory failed to create device: %s", plink->name, error->message); + } else { + _LOGD (LOGD_HW, "%s: factory failed to create device: %s", + plink->name, error->message); } return; } @@ -2185,7 +2148,7 @@ platform_link_added (NMManager *self, if (device == NULL) { switch (plink->type) { - case NM_LINK_TYPE_WWAN_ETHERNET: + case NM_LINK_TYPE_WWAN_NET: case NM_LINK_TYPE_BNEP: case NM_LINK_TYPE_OLPC_MESH: case NM_LINK_TYPE_TEAM: @@ -2740,7 +2703,7 @@ find_slaves (NMManager *manager, * even if a slave was already active, it might be deactivated during * master reactivation. */ - all_connections = nm_settings_get_connections (priv->settings); + all_connections = nm_settings_get_connections_sorted (priv->settings); for (iter = all_connections; iter; iter = iter->next) { NMSettingsConnection *master_connection = NULL; NMDevice *master_device = NULL; @@ -3474,7 +3437,7 @@ _activation_auth_done (NMActiveConnection *active, g_dbus_method_invocation_return_value (context, g_variant_new ("(o)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)))); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE, NULL, subject, NULL); g_object_unref (active); return; @@ -3486,7 +3449,7 @@ _activation_auth_done (NMActiveConnection *active, } g_assert (error); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL, subject, error->message); _internal_activation_failed (self, active, error->message); @@ -3574,7 +3537,7 @@ impl_manager_activate_connection (NMManager *self, error: if (connection) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL, subject, error->message); } g_clear_object (&active); @@ -3623,6 +3586,7 @@ activation_add_done (NMSettings *settings, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, nm_active_connection_get_settings_connection (active), TRUE, + NULL, nm_active_connection_get_subject (active), NULL); return; @@ -3637,6 +3601,7 @@ activation_add_done (NMSettings *settings, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, + NULL, nm_active_connection_get_subject (active), error->message); g_clear_error (&local); @@ -3681,6 +3646,7 @@ _add_and_activate_auth_done (NMActiveConnection *active, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, + NULL, nm_active_connection_get_subject (active), error->message); g_dbus_method_invocation_take_error (context, error); @@ -3732,7 +3698,7 @@ impl_manager_add_and_activate_connection (NMManager *self, if (!subject) goto error; - all_connections = nm_settings_get_connections (priv->settings); + all_connections = nm_settings_get_connections_sorted (priv->settings); if (vpn) { /* Try to fill the VPN's connection setting and name at least */ if (!nm_connection_get_setting_vpn (connection)) { @@ -3782,7 +3748,7 @@ impl_manager_add_and_activate_connection (NMManager *self, return; error: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, subject, error->message); + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, NULL, subject, error->message); g_clear_object (&connection); g_slist_free (all_connections); g_clear_object (&subject); @@ -3878,6 +3844,7 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, nm_active_connection_get_settings_connection (active), !error, + NULL, nm_auth_chain_get_subject (chain), error ? error->message : NULL); } @@ -3951,7 +3918,7 @@ impl_manager_deactivate_connection (NMManager *self, done: if (error) { if (connection) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL, subject, error->message); } g_dbus_method_invocation_take_error (context, error); @@ -4291,21 +4258,9 @@ static void _internal_enable (NMManager *self, gboolean enable) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *error = NULL; - /* Update "NetworkingEnabled" key in state file */ - if (priv->state_file) { - if (!write_value_to_state_file (priv->state_file, - "main", "NetworkingEnabled", - G_TYPE_BOOLEAN, (gpointer) &enable, - &error)) { - /* Not a hard error */ - _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s", - priv->state_file, - error->message); - g_clear_error (&error); - } - } + nm_config_state_set (priv->config, TRUE, FALSE, + NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, enable); _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)", enable ? "enable" : "disable", @@ -4457,7 +4412,10 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN); get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); + get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS); get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_RELOAD); + get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK); + get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS); g_dbus_method_invocation_return_value (context, g_variant_new ("(a{ss})", &results)); @@ -4495,7 +4453,10 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_RELOAD, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, FALSE); } static void @@ -4513,30 +4474,24 @@ impl_manager_set_logging (NMManager *self, const char *level, const char *domains) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GError *error = NULL; - gulong caller_uid = G_MAXULONG; - if (!nm_bus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Failed to get request UID."); - goto done; - } - - if (0 != caller_uid) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Permission denied"); - goto done; - } + /* The permission is already enforced by the D-Bus daemon, but we ensure + * that the caller is still alive so that clients are forced to wait and + * we'll be able to switch to polkit without breaking behavior. + */ + if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), + context, + G_MAXULONG, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED)) + return; if (nm_logging_setup (level, domains, NULL, &error)) { _LOGI (LOGD_CORE, "logging: level '%s' domains '%s'", nm_logging_level_to_string (), nm_logging_domains_to_string ()); } -done: if (error) g_dbus_method_invocation_take_error (context, error); else @@ -4693,7 +4648,7 @@ nm_manager_start (NMManager *self, GError **error) * connection-added signals thus devices have to be created manually. */ _LOGD (LOGD_CORE, "creating virtual devices..."); - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = iter->next) connection_changed (self, NM_CONNECTION (iter->data)); g_slist_free (connections); @@ -4956,6 +4911,10 @@ prop_set_auth_done_cb (NMAuthChain *chain, /* ... but set the property on the @object itself. It would be correct to set the property * on the skeleton interface, but as it is now, the result is the same. */ g_object_set (object, pfd->glib_propname, value, NULL); + } else if (!strcmp (pfd->glib_propname, NM_DEVICE_STATISTICS_REFRESH_RATE_MS)) { + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)); + /* the same here */ + g_object_set (object, pfd->glib_propname, (guint) g_variant_get_uint32 (value), NULL); } else { g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); /* the same here */ @@ -5090,6 +5049,15 @@ prop_filter (GDBusConnection *connection, } else return message; interface_type = NMDBUS_TYPE_DEVICE_SKELETON; + } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE_STATISTICS)) { + if (!strcmp (propname, "RefreshRateMs")) { + glib_propname = NM_DEVICE_STATISTICS_REFRESH_RATE_MS; + permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS; + audit_op = NM_AUDIT_OP_STATISTICS; + expected_type = G_VARIANT_TYPE ("u"); + } else + return message; + interface_type = NMDBUS_TYPE_DEVICE_SKELETON; } else return message; @@ -5169,8 +5137,176 @@ _set_prop_filter (NMManager *self, GDBusConnection *connection) /******************************************************************************/ +static NMCheckpointManager * +_checkpoint_mgr_get (NMManager *self, gboolean create_as_needed) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + if (G_UNLIKELY (!priv->checkpoint_mgr) && create_as_needed) + priv->checkpoint_mgr = nm_checkpoint_manager_new (self); + return priv->checkpoint_mgr; +} + +static void +checkpoint_auth_done_cb (NMAuthChain *chain, + GError *auth_error, + GDBusMethodInvocation *context, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + char *op, *checkpoint_path = NULL, **devices; + NMCheckpoint *checkpoint; + NMAuthCallResult result; + guint32 timeout, flags; + GVariant *variant = NULL; + GError *error = NULL; + const char *arg = NULL; + + op = nm_auth_chain_get_data (chain, "audit-op"); + priv->auth_chains = g_slist_remove (priv->auth_chains, chain); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK); + + if ( nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_DESTROY) + || nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_ROLLBACK)) + arg = checkpoint_path = nm_auth_chain_get_data (chain, "checkpoint_path"); + + if (auth_error) { + error = g_error_new (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "checkpoint check request failed: %s", + auth_error->message); + } else if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Not authorized to checkpoint/rollback"); + } else { + if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_CREATE)) { + timeout = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "timeout")); + flags = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "flags")); + devices = nm_auth_chain_get_data (chain, "devices"); + + checkpoint = nm_checkpoint_manager_create (_checkpoint_mgr_get (self, TRUE), + (const char *const *) devices, + timeout, + (NMCheckpointCreateFlags) flags, + &error); + if (checkpoint) { + arg = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint)); + variant = g_variant_new ("(o)", arg); + } + } else if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_DESTROY)) { + nm_checkpoint_manager_destroy (_checkpoint_mgr_get (self, TRUE), + checkpoint_path, &error); + } else if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_ROLLBACK)) { + nm_checkpoint_manager_rollback (_checkpoint_mgr_get (self, TRUE), + checkpoint_path, &variant, &error); + } else + g_return_if_reached (); + } + + nm_audit_log_checkpoint_op (op, arg ?: "", !error, nm_auth_chain_get_subject (chain), + error ? error->message : NULL); + + if (error) + g_dbus_method_invocation_take_error (context, error); + else + g_dbus_method_invocation_return_value (context, variant); + + + nm_auth_chain_unref (chain); +} + static void -authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data) +impl_manager_checkpoint_create (NMManager *self, + GDBusMethodInvocation *context, + const char *const *devices, + guint32 rollback_timeout, + guint32 flags) +{ + NMManagerPrivate *priv; + NMAuthChain *chain; + GError *error = NULL; + + G_STATIC_ASSERT_EXPR (sizeof (flags) <= sizeof (NMCheckpointCreateFlags)); + g_return_if_fail (NM_IS_MANAGER (self)); + priv = NM_MANAGER_GET_PRIVATE (self); + + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); + g_dbus_method_invocation_take_error (context, error); + return; + } + + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL); + nm_auth_chain_set_data (chain, "devices", g_strdupv ((char **) devices), (GDestroyNotify) g_strfreev); + nm_auth_chain_set_data (chain, "flags", GUINT_TO_POINTER (flags), NULL); + nm_auth_chain_set_data (chain, "timeout", GUINT_TO_POINTER (rollback_timeout), NULL); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); +} + +static void +impl_manager_checkpoint_destroy (NMManager *self, + GDBusMethodInvocation *context, + const char *checkpoint_path) +{ + NMManagerPrivate *priv; + GError *error = NULL; + NMAuthChain *chain; + + g_return_if_fail (NM_IS_MANAGER (self)); + priv = NM_MANAGER_GET_PRIVATE (self); + + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); + g_dbus_method_invocation_take_error (context, error); + return; + } + + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_DESTROY, NULL); + nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); +} + +static void +impl_manager_checkpoint_rollback (NMManager *self, + GDBusMethodInvocation *context, + const char *checkpoint_path) +{ + NMManagerPrivate *priv; + GError *error = NULL; + NMAuthChain *chain; + + g_return_if_fail (NM_IS_MANAGER (self)); + priv = NM_MANAGER_GET_PRIVATE (self); + + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); + g_dbus_method_invocation_take_error (context, error); + return; + } + + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_ROLLBACK, NULL); + nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); +} + +/******************************************************************************/ + +static void +auth_mgr_changed (NMAuthManager *auth_manager, gpointer user_data) { /* Let clients know they should re-check their authorization */ g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); @@ -5245,7 +5381,6 @@ manager_radio_user_toggled (NMManager *self, gboolean enabled) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *error = NULL; gboolean old_enabled, new_enabled; /* Don't touch devices if asleep/networking disabled */ @@ -5259,17 +5394,8 @@ manager_radio_user_toggled (NMManager *self, } /* Update enabled key in state file */ - if (priv->state_file) { - if (!write_value_to_state_file (priv->state_file, - "main", rstate->key, - G_TYPE_BOOLEAN, (gpointer) &enabled, - &error)) { - _LOGW (LOGD_CORE, "writing to state file %s failed: %s", - priv->state_file, - error->message); - g_clear_error (&error); - } - } + nm_config_state_set (priv->config, TRUE, FALSE, + rstate->key, enabled); /* When the user toggles the radio, their request should override any * daemon (like ModemManager) enabled state that can be changed. For WWAN @@ -5331,34 +5457,22 @@ nm_manager_get (void) return singleton_instance; } -NMConnectionProvider * -nm_connection_provider_get (void) +NMSettings * +nm_settings_get (void) { - NMConnectionProvider *p; - g_return_val_if_fail (singleton_instance, NULL); - p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings); - g_return_val_if_fail (p, NULL); - return p; + return NM_MANAGER_GET_PRIVATE (singleton_instance)->settings; } NMManager * -nm_manager_setup (const char *state_file, - gboolean initial_net_enabled, - gboolean initial_wifi_enabled, - gboolean initial_wwan_enabled) +nm_manager_setup (void) { NMManager *self; g_return_val_if_fail (!singleton_instance, singleton_instance); - self = g_object_new (NM_TYPE_MANAGER, - NM_MANAGER_NETWORKING_ENABLED, initial_net_enabled, - NM_MANAGER_WIRELESS_ENABLED, initial_wifi_enabled, - NM_MANAGER_WWAN_ENABLED, initial_wwan_enabled, - NM_MANAGER_STATE_FILE, state_file, - NULL); + self = g_object_new (NM_TYPE_MANAGER, NULL); nm_assert (NM_IS_MANAGER (self)); singleton_instance = self; @@ -5376,6 +5490,7 @@ constructed (GObject *object) NMManager *self = NM_MANAGER (object); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMConfigData *config_data; + const NMConfigState *state; G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object); @@ -5421,9 +5536,16 @@ constructed (GObject *object) g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE, G_CALLBACK (connectivity_changed), self); + state = nm_config_state_get (priv->config); + + priv->net_enabled = state->net_enabled; + + priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = state->wifi_enabled; + priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = state->wwan_enabled; + priv->rfkill_mgr = nm_rfkill_manager_new (); g_signal_connect (priv->rfkill_mgr, - "rfkill-changed", + NM_RFKILL_MANAGER_SIGNAL_RFKILL_CHANGED, G_CALLBACK (rfkill_manager_rfkill_changed_cb), self); @@ -5447,14 +5569,14 @@ nm_manager_init (NMManager *self) memset (priv->radio_states, 0, sizeof (priv->radio_states)); priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE; - priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled"; + priv->radio_states[RFKILL_TYPE_WLAN].key = NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED; priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED; priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED; priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi"; priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN; priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE; - priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled"; + priv->radio_states[RFKILL_TYPE_WWAN].key = NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED; priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED; priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED; priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN"; @@ -5479,12 +5601,12 @@ nm_manager_init (NMManager *self) G_CALLBACK (sleeping_cb), self); /* Listen for authorization changes */ - g_signal_connect (nm_auth_manager_get (), + priv->auth_mgr = g_object_ref (nm_auth_manager_get ()); + g_signal_connect (priv->auth_mgr, NM_AUTH_MANAGER_SIGNAL_CHANGED, - G_CALLBACK (authority_changed_cb), + G_CALLBACK (auth_mgr_changed), self); - /* Monitor the firmware directory */ if (strlen (KERNEL_FIRMWARE_DIR)) { file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/"); @@ -5617,33 +5739,15 @@ set_property (GObject *object, guint prop_id, GError *error = NULL; switch (prop_id) { - case PROP_STATE_FILE: - /* construct-only */ - priv->state_file = g_value_dup_string (value); - break; - case PROP_NETWORKING_ENABLED: - /* construct-only */ - priv->net_enabled = g_value_get_boolean (value); - break; case PROP_WIRELESS_ENABLED: - if (!priv->rfkill_mgr) { - /* called during object construction. */ - priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = g_value_get_boolean (value); - } else { - manager_radio_user_toggled (NM_MANAGER (object), - &priv->radio_states[RFKILL_TYPE_WLAN], - g_value_get_boolean (value)); - } + manager_radio_user_toggled (NM_MANAGER (object), + &priv->radio_states[RFKILL_TYPE_WLAN], + g_value_get_boolean (value)); break; case PROP_WWAN_ENABLED: - if (!priv->rfkill_mgr) { - /* called during object construction. */ - priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = g_value_get_boolean (value); - } else { - manager_radio_user_toggled (NM_MANAGER (object), - &priv->radio_states[RFKILL_TYPE_WWAN], - g_value_get_boolean (value)); - } + manager_radio_user_toggled (NM_MANAGER (object), + &priv->radio_states[RFKILL_TYPE_WWAN], + g_value_get_boolean (value)); break; case PROP_WIMAX_ENABLED: /* WIMAX is depreacted. This does nothing. */ @@ -5681,9 +5785,17 @@ dispose (GObject *object) g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref); priv->auth_chains = NULL; - g_signal_handlers_disconnect_by_func (nm_auth_manager_get (), - G_CALLBACK (authority_changed_cb), - manager); + if (priv->checkpoint_mgr) { + nm_checkpoint_manager_destroy_all (priv->checkpoint_mgr, NULL); + g_clear_pointer (&priv->checkpoint_mgr, nm_checkpoint_manager_unref); + } + + if (priv->auth_mgr) { + g_signal_handlers_disconnect_by_func (priv->auth_mgr, + G_CALLBACK (auth_mgr_changed), + manager); + g_clear_object (&priv->auth_mgr); + } g_assert (priv->devices == NULL); @@ -5721,7 +5833,6 @@ dispose (GObject *object) g_clear_object (&priv->settings); } - g_clear_pointer (&priv->state_file, g_free); g_clear_object (&priv->vpn_manager); /* Unregister property filter */ @@ -5766,8 +5877,6 @@ nm_manager_class_init (NMManagerClass *manager_class) GObjectClass *object_class = G_OBJECT_CLASS (manager_class); NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class); - g_type_class_add_private (manager_class, sizeof (NMManagerPrivate)); - exported_object_class->export_path = NM_DBUS_PATH; /* virtual methods */ @@ -5783,13 +5892,6 @@ nm_manager_class_init (NMManagerClass *manager_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATE_FILE] = - g_param_spec_string (NM_MANAGER_STATE_FILE, "", "", - NULL, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATE] = g_param_spec_uint (NM_MANAGER_STATE, "", "", 0, NM_STATE_DISCONNECTED, 0, @@ -5805,14 +5907,13 @@ nm_manager_class_init (NMManagerClass *manager_class) obj_properties[PROP_NETWORKING_ENABLED] = g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_WIRELESS_ENABLED] = g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "", TRUE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] = @@ -5825,7 +5926,6 @@ nm_manager_class_init (NMManagerClass *manager_class) g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "", TRUE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); obj_properties[PROP_WWAN_HARDWARE_ENABLED] = @@ -5945,8 +6045,7 @@ nm_manager_class_init (NMManagerClass *manager_class) g_signal_new (NM_MANAGER_DEVICE_ADDED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, device_added), - NULL, NULL, NULL, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, NM_TYPE_DEVICE); /* Emitted for both realized devices and placeholder devices */ @@ -5962,8 +6061,7 @@ nm_manager_class_init (NMManagerClass *manager_class) g_signal_new (NM_MANAGER_DEVICE_REMOVED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, device_removed), - NULL, NULL, NULL, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, NM_TYPE_DEVICE); /* Emitted for both realized devices and placeholder devices */ @@ -5978,8 +6076,7 @@ nm_manager_class_init (NMManagerClass *manager_class) g_signal_new (NM_MANAGER_STATE_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, state_changed), - NULL, NULL, NULL, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT); signals[CHECK_PERMISSIONS] = @@ -6026,6 +6123,9 @@ nm_manager_class_init (NMManagerClass *manager_class) "GetLogging", impl_manager_get_logging, "CheckConnectivity", impl_manager_check_connectivity, "state", impl_manager_get_state, + "CheckpointCreate", impl_manager_checkpoint_create, + "CheckpointDestroy", impl_manager_checkpoint_destroy, + "CheckpointRollback", impl_manager_checkpoint_rollback, NULL); } diff --git a/src/nm-manager.h b/src/nm-manager.h index 5401b002..d7aabff1 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -55,7 +55,6 @@ /* Not exported */ #define NM_MANAGER_HOSTNAME "hostname" #define NM_MANAGER_SLEEPING "sleeping" -#define NM_MANAGER_STATE_FILE "state-file" /* signals */ #define NM_MANAGER_CHECK_PERMISSIONS "check-permissions" @@ -72,26 +71,10 @@ #define NM_MANAGER_INTERNAL_DEVICE_REMOVED "internal-device-removed" -struct _NMManager { - NMExportedObject parent; -}; - -typedef struct { - NMExportedObjectClass parent; - - /* Signals */ - void (*device_added) (NMManager *manager, NMDevice *device); - void (*device_removed) (NMManager *manager, NMDevice *device); - void (*state_changed) (NMManager *manager, guint state); -} NMManagerClass; - GType nm_manager_get_type (void); /* nm_manager_setup() should only be used by main.c */ -NMManager * nm_manager_setup (const char *state_file, - gboolean initial_net_enabled, - gboolean initial_wifi_enabled, - gboolean initial_wwan_enabled); +NMManager * nm_manager_setup (void); NMManager * nm_manager_get (void); @@ -108,6 +91,8 @@ const GSList * nm_manager_get_devices (NMManager *manager); NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex); +NMDevice * nm_manager_get_device_by_path (NMManager *manager, + const char *path); char * nm_manager_get_connection_iface (NMManager *self, NMConnection *connection, diff --git a/src/nm-multi-index.h b/src/nm-multi-index.h index 1e1e8fda..fb102574 100644 --- a/src/nm-multi-index.h +++ b/src/nm-multi-index.h @@ -21,11 +21,6 @@ #ifndef __NM_MULTI_INDEX__ #define __NM_MULTI_INDEX__ -#include "nm-default.h" - -G_BEGIN_DECLS - - typedef struct { char _dummy; } NMMultiIndexId; @@ -106,7 +101,5 @@ void nm_multi_index_id_iter_init (NMMultiIndexIdIter *iter, gboolean nm_multi_index_id_iter_next (NMMultiIndexIdIter *iter, void **out_value); -G_END_DECLS - #endif /* __NM_MULTI_INDEX__ */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 9613ad82..5fa46259 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -180,38 +180,35 @@ _set_hostname (NMPolicy *self, if (new_hostname) g_clear_object (&priv->lookup_addr); - /* Don't change the hostname or update DNS this is the first time we're - * trying to change the hostname, and it's not actually changing. - */ if ( priv->orig_hostname && (priv->hostname_changed == FALSE) - && g_strcmp0 (priv->orig_hostname, new_hostname) == 0) - return; - - /* Don't change the hostname or update DNS if the hostname isn't actually - * going to change. - */ - if (g_strcmp0 (priv->cur_hostname, new_hostname) == 0) - return; - - g_free (priv->cur_hostname); - priv->cur_hostname = g_strdup (new_hostname); - priv->hostname_changed = TRUE; + && g_strcmp0 (priv->orig_hostname, new_hostname) == 0) { + /* Don't change the hostname or update DNS this is the first time we're + * trying to change the hostname, and it's not actually changing. + */ + } else if (g_strcmp0 (priv->cur_hostname, new_hostname) == 0) { + /* Don't change the hostname or update DNS if the hostname isn't actually + * going to change. + */ + } else { + g_free (priv->cur_hostname); + priv->cur_hostname = g_strdup (new_hostname); + priv->hostname_changed = TRUE; - /* Notify the DNS manager of the hostname change so that the domain part, if - * present, can be added to the search list. - */ - nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname); + /* Notify the DNS manager of the hostname change so that the domain part, if + * present, can be added to the search list. + */ + nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname); + } /* Finally, set kernel hostname */ - - if (!priv->cur_hostname) + if (!new_hostname) name = FALLBACK_HOSTNAME4; - else if (!priv->cur_hostname[0]) { + else if (!new_hostname[0]) { g_warn_if_reached (); name = FALLBACK_HOSTNAME4; } else - name = priv->cur_hostname; + name = new_hostname; old_hostname[HOST_NAME_MAX] = '\0'; errno = 0; @@ -862,7 +859,7 @@ reset_autoconnect_all (NMPolicy *self, NMDevice *device) } else _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections"); - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { if (!device || nm_device_check_connection_compatible (device, iter->data)) { nm_settings_connection_reset_autoconnect_retries (iter->data); @@ -880,7 +877,7 @@ reset_autoconnect_for_failed_secrets (NMPolicy *self) _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections with failed secrets"); - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data); @@ -908,7 +905,7 @@ block_autoconnect_for_device (NMPolicy *self, NMDevice *device) if (!nm_device_is_software (device)) return; - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { if (nm_device_check_connection_compatible (device, iter->data)) { nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data), @@ -991,7 +988,7 @@ reset_connections_retries (gpointer user_data) min_stamp = 0; now = nm_utils_get_monotonic_timestamp_s (); - connections = nm_settings_get_connections (priv->settings); + connections = nm_settings_get_connections_sorted (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data); @@ -1023,8 +1020,10 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); const char *master_device, *master_uuid_settings = NULL, *master_uuid_applied = NULL; - GSList *connections, *iter; + gs_free_slist GSList *connections = NULL; + GSList *iter; NMActRequest *req; + gboolean internal_activation = FALSE; master_device = nm_device_get_iface (device); g_assert (master_device); @@ -1032,6 +1031,7 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) req = nm_device_get_act_request (device); if (req) { NMConnection *con; + NMAuthSubject *subject; con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); if (con) @@ -1042,9 +1042,14 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) if (!g_strcmp0 (master_uuid_settings, master_uuid_applied)) master_uuid_settings = NULL; } + + subject = nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)); + internal_activation = subject && nm_auth_subject_is_internal (subject); } - connections = nm_settings_get_connections (priv->settings); + if (!internal_activation) + connections = nm_settings_get_connections_sorted (priv->settings); + for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *slave; NMSettingConnection *s_slave_con; @@ -1065,8 +1070,6 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) nm_settings_connection_reset_autoconnect_retries (NM_SETTINGS_CONNECTION (slave)); } - g_slist_free (connections); - schedule_activate_all (self); } @@ -1312,6 +1315,7 @@ device_ip4_config_changed (NMDevice *device, } update_ip4_dns (self, priv->dns_manager); update_ip4_routing (self, TRUE); + update_system_hostname (self, priv->default_device4, priv->default_device6); } else { /* Old configs get removed immediately */ if (old_config) @@ -1346,6 +1350,7 @@ device_ip6_config_changed (NMDevice *device, } update_ip6_dns (self, priv->dns_manager); update_ip6_routing (self, TRUE); + update_system_hostname (self, priv->default_device4, priv->default_device6); } else { /* Old configs get removed immediately */ if (old_config) diff --git a/src/nm-policy.h b/src/nm-policy.h index 476ddf1d..ce900ba6 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -22,8 +22,6 @@ #ifndef __NETWORKMANAGER_POLICY_H__ #define __NETWORKMANAGER_POLICY_H__ -#include "nm-default.h" - #define NM_TYPE_POLICY (nm_policy_get_type ()) #define NM_POLICY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_POLICY, NMPolicy)) #define NM_POLICY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_POLICY, NMPolicyClass)) diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c index 16742656..453a3b9b 100644 --- a/src/nm-rfkill-manager.c +++ b/src/nm-rfkill-manager.c @@ -395,7 +395,7 @@ dispose (GObject *object) priv->killswitches = NULL; } - G_OBJECT_CLASS (nm_rfkill_manager_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_rfkill_manager_parent_class)->dispose (object); } static void @@ -410,7 +410,7 @@ nm_rfkill_manager_class_init (NMRfkillManagerClass *klass) /* Signals */ signals[RFKILL_CHANGED] = - g_signal_new ("rfkill-changed", + g_signal_new (NM_RFKILL_MANAGER_SIGNAL_RFKILL_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMRfkillManagerClass, rfkill_changed), diff --git a/src/nm-rfkill-manager.h b/src/nm-rfkill-manager.h index 0084364c..3aca8f50 100644 --- a/src/nm-rfkill-manager.h +++ b/src/nm-rfkill-manager.h @@ -19,12 +19,11 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ - -#include "nm-default.h" - #ifndef __NETWORKMANAGER_RFKILL_MANAGER_H__ #define __NETWORKMANAGER_RFKILL_MANAGER_H__ +#define NM_RFKILL_MANAGER_SIGNAL_RFKILL_CHANGED "rfkill-changed" + typedef enum { /*< skip >*/ RFKILL_UNBLOCKED = 0, RFKILL_SOFT_BLOCKED = 1, diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c index 05e28c74..2d4c7d95 100644 --- a/src/nm-route-manager.c +++ b/src/nm-route-manager.c @@ -873,7 +873,7 @@ next: || !_route_equals_ignoring_ifindex (vtable, cur_plat_route, cur_ipx_route, *p_effective_metric)) { if (!vtable->vt->route_add (priv->platform, ifindex, cur_ipx_route, *p_effective_metric)) { - if (cur_ipx_route->rx.source < NM_IP_CONFIG_SOURCE_USER) { + if (cur_ipx_route->rx.rt_source < NM_IP_CONFIG_SOURCE_USER) { _LOGD (vtable->vt->addr_family, "ignore error adding IPv%c route to kernel: %s", vtable->vt->is_ip4 ? '4' : '6', @@ -1024,7 +1024,7 @@ _ip4_device_routes_ip4_route_changed (NMPlatform *platform, if (change_type == NM_PLATFORM_SIGNAL_REMOVED) return; - if ( route->source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL + if ( route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL || route->metric != 0) { /* we don't have an automatically created device route at hand. Bail out early. */ return; diff --git a/src/nm-route-manager.h b/src/nm-route-manager.h index 1f4b8174..8e2746d9 100644 --- a/src/nm-route-manager.h +++ b/src/nm-route-manager.h @@ -18,9 +18,6 @@ * Copyright (C) 2015 Red Hat, Inc. */ - -#include "nm-default.h" - #ifndef __NETWORKMANAGER_ROUTE_MANAGER_H__ #define __NETWORKMANAGER_ROUTE_MANAGER_H__ diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index 46709427..279a8886 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -279,45 +279,6 @@ ck_finalize (NMSessionMonitor *monitor) NM_DEFINE_SINGLETON_GETTER (NMSessionMonitor, nm_session_monitor_get, NM_TYPE_SESSION_MONITOR); /** - * nm_session_monitor_connect: - * @self: the session monitor - * @callback: The callback. - * @user_data: User data for the callback. - * - * Connect a callback to the session monitor. - * - * Returns: Handler ID to be used with nm_session_monitor_disconnect(). - */ -gulong -nm_session_monitor_connect (NMSessionMonitor *self, - NMSessionCallback callback, - gpointer user_data) -{ - g_return_val_if_fail (NM_IS_SESSION_MONITOR (self), 0); - - return g_signal_connect (self, - NM_SESSION_MONITOR_CHANGED, - G_CALLBACK (callback), - user_data); -} - -/** - * nm_session_monitor_disconnect: - * @self: the session monitor - * @handler_id: Handler ID returned by nm_session_monitor-connect(). - * - * Disconnect callback from the session handler. - */ -void -nm_session_monitor_disconnect (NMSessionMonitor *self, - gulong handler_id) -{ - g_return_if_fail (NM_IS_SESSION_MONITOR (self)); - - g_signal_handler_disconnect (self, handler_id); -} - -/** * nm_session_monitor_uid_to_user: * @uid: UID. * @out_user: Return location for user name. diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h index af50b71b..3751d7db 100644 --- a/src/nm-session-monitor.h +++ b/src/nm-session-monitor.h @@ -21,11 +21,6 @@ #ifndef __NETWORKMANAGER_SESSION_MONITOR_H__ #define __NETWORKMANAGER_SESSION_MONITOR_H__ - -#include "nm-default.h" - -G_BEGIN_DECLS - #define NM_TYPE_SESSION_MONITOR (nm_session_monitor_get_type ()) #define NM_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_SESSION_MONITOR, NMSessionMonitor)) #define NM_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), NM_TYPE_SESSION_MONITOR, NMSessionMonitorClass)) @@ -43,19 +38,11 @@ GType nm_session_monitor_get_type (void) G_GNUC_CONST; NMSessionMonitor *nm_session_monitor_get (void); -gulong nm_session_monitor_connect (NMSessionMonitor *self, - NMSessionCallback callback, - gpointer user_data); -void nm_session_monitor_disconnect (NMSessionMonitor *self, - gulong handler_id); - gboolean nm_session_monitor_uid_to_user (uid_t uid, const char **out_user); gboolean nm_session_monitor_user_to_uid (const char *user, uid_t *out_uid); gboolean nm_session_monitor_session_exists (NMSessionMonitor *self, uid_t uid, gboolean active); -G_END_DECLS - #endif /* __NETWORKMANAGER_SESSION_MONITOR_H__ */ diff --git a/src/nm-sleep-monitor.h b/src/nm-sleep-monitor.h index 140f964f..d54aebbc 100644 --- a/src/nm-sleep-monitor.h +++ b/src/nm-sleep-monitor.h @@ -20,8 +20,6 @@ #ifndef __NETWORKMANAGER_SLEEP_MONITOR_H__ #define __NETWORKMANAGER_SLEEP_MONITOR_H__ -G_BEGIN_DECLS - #define NM_TYPE_SLEEP_MONITOR (nm_sleep_monitor_get_type ()) #define NM_SLEEP_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_SLEEP_MONITOR, NMSleepMonitor)) #define NM_SLEEP_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), NM_TYPE_SLEEP_MONITOR, NMSleepMonitorClass)) @@ -42,7 +40,5 @@ NMSleepMonitorInhibitorHandle *nm_sleep_monitor_inhibit_take (NMSleepMonitor void nm_sleep_monitor_inhibit_release (NMSleepMonitor *self, NMSleepMonitorInhibitorHandle *handle); -G_END_DECLS - #endif /* __NETWORKMANAGER_SLEEP_MONITOR_H__ */ diff --git a/src/nm-test-utils-core.h b/src/nm-test-utils-core.h new file mode 100644 index 00000000..f5118398 --- /dev/null +++ b/src/nm-test-utils-core.h @@ -0,0 +1,296 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2014 - 2016 Red Hat, Inc. + */ + +#ifndef __NM_TEST_UTILS_CORE_H__ +#define __NM_TEST_UTILS_CORE_H__ + +#include "NetworkManagerUtils.h" +#include "nm-keyfile-internal.h" + +#define _NMTST_INSIDE_CORE 1 + +#include "nm-utils/nm-test-utils.h" + +/*****************************************************************************/ + +inline static void +nmtst_init_with_logging (int *argc, char ***argv, const char *log_level, const char *log_domains) +{ + __nmtst_init (argc, argv, FALSE, log_level, log_domains, NULL); +} +inline static void +nmtst_init_assert_logging (int *argc, char ***argv, const char *log_level, const char *log_domains) +{ + gboolean set_logging; + + __nmtst_init (argc, argv, TRUE, NULL, NULL, &set_logging); + + if (!set_logging) { + gboolean success; + + success = nm_logging_setup (log_level, log_domains, NULL, NULL); + g_assert (success); + } +} + +/*****************************************************************************/ + +#ifdef __NETWORKMANAGER_PLATFORM_H__ + +inline static NMPlatformIP4Address * +nmtst_platform_ip4_address (const char *address, const char *peer_address, guint plen) +{ + static NMPlatformIP4Address addr; + + g_assert (plen <= 32); + + memset (&addr, 0, sizeof (addr)); + addr.address = nmtst_inet4_from_string (address); + if (peer_address) + addr.peer_address = nmtst_inet4_from_string (peer_address); + else + addr.peer_address = addr.address; + addr.plen = plen; + + return &addr; +} + +inline static NMPlatformIP4Address * +nmtst_platform_ip4_address_full (const char *address, const char *peer_address, guint plen, + int ifindex, NMIPConfigSource source, guint32 timestamp, + guint32 lifetime, guint32 preferred, guint32 flags, + const char *label) +{ + NMPlatformIP4Address *addr = nmtst_platform_ip4_address (address, peer_address, plen); + + G_STATIC_ASSERT (IFNAMSIZ == sizeof (addr->label)); + g_assert (!label || strlen (label) < IFNAMSIZ); + + addr->ifindex = ifindex; + addr->addr_source = source; + addr->timestamp = timestamp; + addr->lifetime = lifetime; + addr->preferred = preferred; + addr->n_ifa_flags = flags; + if (label) + g_strlcpy (addr->label, label, sizeof (addr->label)); + + return addr; +} + +inline static NMPlatformIP6Address * +nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen) +{ + static NMPlatformIP6Address addr; + + g_assert (plen <= 128); + + memset (&addr, 0, sizeof (addr)); + addr.address = *nmtst_inet6_from_string (address); + addr.peer_address = *nmtst_inet6_from_string (peer_address); + addr.plen = plen; + + return &addr; +} + +inline static NMPlatformIP6Address * +nmtst_platform_ip6_address_full (const char *address, const char *peer_address, guint plen, + int ifindex, NMIPConfigSource source, guint32 timestamp, + guint32 lifetime, guint32 preferred, guint32 flags) +{ + NMPlatformIP6Address *addr = nmtst_platform_ip6_address (address, peer_address, plen); + + addr->ifindex = ifindex; + addr->addr_source = source; + addr->timestamp = timestamp; + addr->lifetime = lifetime; + addr->preferred = preferred; + addr->n_ifa_flags = flags; + + return addr; +} + +inline static NMPlatformIP4Route * +nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway) +{ + static NMPlatformIP4Route route; + + g_assert (plen <= 32); + + memset (&route, 0, sizeof (route)); + route.network = nmtst_inet4_from_string (network); + route.plen = plen; + route.gateway = nmtst_inet4_from_string (gateway); + + return &route; +} + +inline static NMPlatformIP4Route * +nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway, + int ifindex, NMIPConfigSource source, + guint metric, guint mss, + guint8 scope, + const char *pref_src) +{ + NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway); + + route->ifindex = ifindex; + route->rt_source = source; + route->metric = metric; + route->mss = mss; + route->scope_inv = nm_platform_route_scope_inv (scope); + route->pref_src = nmtst_inet4_from_string (pref_src); + + return route; +} + +inline static NMPlatformIP6Route * +nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway) +{ + static NMPlatformIP6Route route; + + nm_assert (plen <= 128); + + memset (&route, 0, sizeof (route)); + route.network = *nmtst_inet6_from_string (network); + route.plen = plen; + route.gateway = *nmtst_inet6_from_string (gateway); + + return &route; +} + +inline static NMPlatformIP6Route * +nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway, + int ifindex, NMIPConfigSource source, + guint metric, guint mss) +{ + NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway); + + route->ifindex = ifindex; + route->rt_source = source; + route->metric = metric; + route->mss = mss; + + return route; +} + +inline static int +_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b); +} + +inline static void +nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gsize len, gboolean ignore_order) +{ + gsize i; + gs_free const NMPlatformIP4Route *c_a = NULL, *c_b = NULL; + + g_assert (a); + g_assert (b); + + if (ignore_order) { + a = c_a = g_memdup (a, sizeof (NMPlatformIP4Route) * len); + b = c_b = g_memdup (b, sizeof (NMPlatformIP4Route) * len); + g_qsort_with_data (c_a, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL); + g_qsort_with_data (c_b, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL); + } + + for (i = 0; i < len; i++) { + if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) { + char buf[sizeof (_nm_utils_to_string_buffer)]; + + g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (long unsigned) i, + nm_platform_ip4_route_to_string (&a[i], NULL, 0), + nm_platform_ip4_route_to_string (&b[i], buf, sizeof (buf))); + g_assert_not_reached (); + } + } +} + +inline static int +_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b); +} + +inline static void +nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gsize len, gboolean ignore_order) +{ + gsize i; + gs_free const NMPlatformIP6Route *c_a = NULL, *c_b = NULL; + + g_assert (a); + g_assert (b); + + if (ignore_order) { + a = c_a = g_memdup (a, sizeof (NMPlatformIP6Route) * len); + b = c_b = g_memdup (b, sizeof (NMPlatformIP6Route) * len); + g_qsort_with_data (c_a, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL); + g_qsort_with_data (c_b, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL); + } + + for (i = 0; i < len; i++) { + if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) { + char buf[sizeof (_nm_utils_to_string_buffer)]; + + g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (long unsigned) i, + nm_platform_ip6_route_to_string (&a[i], NULL, 0), + nm_platform_ip6_route_to_string (&b[i], buf, sizeof (buf))); + g_assert_not_reached (); + } + } +} + +#endif + + +#ifdef __NETWORKMANAGER_IP4_CONFIG_H__ + +inline static NMIP4Config * +nmtst_ip4_config_clone (NMIP4Config *config) +{ + NMIP4Config *copy = nm_ip4_config_new (-1); + + g_assert (copy); + g_assert (config); + nm_ip4_config_replace (copy, config, NULL); + return copy; +} + +#endif + + +#ifdef __NETWORKMANAGER_IP6_CONFIG_H__ + +inline static NMIP6Config * +nmtst_ip6_config_clone (NMIP6Config *config) +{ + NMIP6Config *copy = nm_ip6_config_new (-1); + + g_assert (copy); + g_assert (config); + nm_ip6_config_replace (copy, config, NULL); + return copy; +} + +#endif + +#endif /* __NM_TEST_UTILS_CORE_H__ */ diff --git a/src/nm-types.h b/src/nm-types.h index 997723e6..1fbf043e 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -54,13 +54,20 @@ typedef struct _NMLldpListener NMLldpListener; typedef enum { /* In priority order; higher number == higher priority */ - NM_IP_CONFIG_SOURCE_UNKNOWN, - /* platform internal flag used to mark routes with RTM_F_CLONED. */ - _NM_IP_CONFIG_SOURCE_RTM_F_CLONED, + NM_IP_CONFIG_SOURCE_UNKNOWN = 0, - /* routes from platform with protocol RTPROT_KERNEL. */ - NM_IP_CONFIG_SOURCE_RTPROT_KERNEL, + /* for routes, the source is mapped to the uint8 field rtm_protocol. + * Reserve the range [1,0x100] for native RTPROT values. */ + + NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC = 1 + 0, + NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT = 1 + 1, + NM_IP_CONFIG_SOURCE_RTPROT_KERNEL = 1 + 2, + NM_IP_CONFIG_SOURCE_RTPROT_BOOT = 1 + 3, + NM_IP_CONFIG_SOURCE_RTPROT_STATIC = 1 + 4, + NM_IP_CONFIG_SOURCE_RTPROT_RA = 1 + 9, + NM_IP_CONFIG_SOURCE_RTPROT_DHCP = 1 + 16, + _NM_IP_CONFIG_SOURCE_RTPROT_LAST = 1 + 0xFF, NM_IP_CONFIG_SOURCE_KERNEL, NM_IP_CONFIG_SOURCE_SHARED, @@ -73,6 +80,12 @@ typedef enum { NM_IP_CONFIG_SOURCE_USER, } NMIPConfigSource; +inline static gboolean +NM_IS_IP_CONFIG_SOURCE_RTPROT (NMIPConfigSource source) +{ + return source > NM_IP_CONFIG_SOURCE_UNKNOWN && source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST; +} + /* platform */ typedef struct _NMPlatform NMPlatform; typedef struct _NMPlatformIP4Address NMPlatformIP4Address; @@ -102,7 +115,7 @@ typedef enum { NM_LINK_TYPE_INFINIBAND, NM_LINK_TYPE_OLPC_MESH, NM_LINK_TYPE_WIFI, - NM_LINK_TYPE_WWAN_ETHERNET, /* WWAN pseudo-ethernet */ + NM_LINK_TYPE_WWAN_NET, /* WWAN kernel netdevice */ NM_LINK_TYPE_WIMAX, /* Software types */ diff --git a/src/platform/Makefile.in b/src/platform/Makefile.in index a528da66..bf094348 100644 --- a/src/platform/Makefile.in +++ b/src/platform/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/platform ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -225,6 +226,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -281,13 +283,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -299,6 +302,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -359,6 +364,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -394,6 +401,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 7b545076..8a4f69b6 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -31,9 +31,10 @@ #include "nm-utils.h" #include "nm-core-utils.h" +#include "nm-platform-utils.h" #include "nmp-object.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /*********************************************************************************************/ @@ -505,7 +506,7 @@ link_set_noarp (NMPlatform *platform, int ifindex) return TRUE; } -static gboolean +static NMPlatformError link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t len) { NMFakePlatformLink *device = link_get (platform, ifindex); @@ -514,7 +515,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t || len == 0 || len > NM_UTILS_HWADDR_LEN_MAX || !addr) - g_return_val_if_reached (FALSE); + g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); if ( device->link.addr.len != len || ( len > 0 @@ -524,7 +525,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t link_changed (platform, link_get (platform, ifindex), TRUE); } - return TRUE; + return NM_PLATFORM_ERROR_SUCCESS; } static gboolean @@ -709,12 +710,13 @@ static gboolean infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) { NMFakePlatformLink *device, *parent_device; - gs_free char *name = NULL; + char name[IFNAMSIZ]; parent_device = link_get (platform, parent); g_return_val_if_fail (parent_device != NULL, FALSE); - name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); + nm_utils_new_infiniband_name (name, parent_device->link.name, p_key); + if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link)) return FALSE; @@ -726,7 +728,6 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP device->lnk->lnk_infiniband.p_key = p_key; device->lnk->lnk_infiniband.mode = "datagram"; device->link.parent = parent; - return TRUE; } @@ -739,7 +740,7 @@ infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) parent_device = link_get (platform, parent); g_return_val_if_fail (parent_device != NULL, FALSE); - name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); + nm_utils_new_infiniband_name (name, parent_device->link.name, p_key); return link_delete (platform, nm_platform_link_get_ifindex (platform, name)); } @@ -911,7 +912,7 @@ ip4_address_add (NMPlatform *platform, int i; memset (&address, 0, sizeof (address)); - address.source = NM_IP_CONFIG_SOURCE_KERNEL; + address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = peer_addr; @@ -962,7 +963,7 @@ ip6_address_add (NMPlatform *platform, int i; memset (&address, 0, sizeof (address)); - address.source = NM_IP_CONFIG_SOURCE_KERNEL; + address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = (IN6_IS_ADDR_UNSPECIFIED (&peer_addr) || IN6_ARE_ADDR_EQUAL (&addr, &peer_addr)) ? in6addr_any : peer_addr; @@ -1207,9 +1208,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, scope = gateway == 0 ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; memset (&route, 0, sizeof (route)); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; - route.source = source; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source); route.network = nm_utils_ip4_address_clear_host_address (network, plen); route.plen = plen; route.gateway = gateway; @@ -1273,9 +1273,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, metric = nm_utils_ip6_route_metric_normalize (metric); memset (&route, 0, sizeof (route)); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; - route.source = source; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source); nm_utils_ip6_address_clear_host_address (&route.network, &network, plen); route.plen = plen; route.gateway = gateway; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f6f7be80..98c4e461 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -176,6 +176,11 @@ * Forward declarations and enums ******************************************************************/ +typedef enum { + INFINIBAND_ACTION_CREATE_CHILD, + INFINIBAND_ACTION_DELETE_CHILD, +} InfinibandAction; + enum { DELAYED_ACTION_IDX_REFRESH_ALL_LINKS, DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES, @@ -303,23 +308,6 @@ _support_user_ipv6ll_detect (struct nlattr **tb) * Various utilities ******************************************************************/ -static void -clear_host_address (int family, const void *network, guint8 plen, void *dst) -{ - g_return_if_fail (network); - - switch (family) { - case AF_INET: - *((in_addr_t *) dst) = nm_utils_ip4_address_clear_host_address (*((in_addr_t *) network), plen); - break; - case AF_INET6: - nm_utils_ip6_address_clear_host_address ((struct in6_addr *) dst, (const struct in6_addr *) network, plen); - break; - default: - g_assert_not_reached (); - } -} - static int _vlan_qos_mapping_cmp_from (gconstpointer a, gconstpointer b, gpointer user_data) { @@ -372,7 +360,7 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_INFINIBAND, "infiniband", NULL, NULL }, { NM_LINK_TYPE_OLPC_MESH, "olpc-mesh", NULL, NULL }, { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" }, - { NM_LINK_TYPE_WWAN_ETHERNET, "wwan", NULL, "wwan" }, + { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" }, { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" }, { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL }, @@ -588,12 +576,17 @@ _lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_fro #define DEVTYPE_PREFIX "DEVTYPE=" static char * -_linktype_read_devtype (const char *sysfs_path) +_linktype_read_devtype (const char *ifname) { - gs_free char *uevent = g_strdup_printf ("%s/uevent", sysfs_path); + char uevent[NM_STRLEN ("/sys/class/net/123456789012345/uevent\0") + 100 /*safety*/]; char *contents = NULL; char *cont, *end; + nm_sprintf_buf (uevent, + "/sys/class/net/%s/uevent", + NM_ASSERT_VALID_PATH_COMPONENT (ifname)); + nm_assert (strlen (uevent) < sizeof (uevent) - 1); + if (!g_file_get_contents (uevent, &contents, NULL, NULL)) return NULL; for (cont = contents; cont; cont = end) { @@ -690,9 +683,8 @@ _linktype_get_type (NMPlatform *platform, return NM_LINK_TYPE_IP6TNL; if (ifname) { + char anycast_mask[NM_STRLEN ("/sys/class/net/123456789012345/anycast_mask\0") + 100 /*safety*/]; gs_free char *driver = NULL; - gs_free char *sysfs_path = NULL; - gs_free char *anycast_mask = NULL; gs_free char *devtype = NULL; /* Fallback OVS detection for kernel <= 3.16 */ @@ -709,12 +701,15 @@ _linktype_get_type (NMPlatform *platform, } } - sysfs_path = g_strdup_printf ("/sys/class/net/%s", ifname); - anycast_mask = g_strdup_printf ("%s/anycast_mask", sysfs_path); + nm_sprintf_buf (anycast_mask, + "/sys/class/net/%s/anycast_mask", + NM_ASSERT_VALID_PATH_COMPONENT (ifname)); + nm_assert (strlen (anycast_mask) < sizeof (anycast_mask) - 1); + if (g_file_test (anycast_mask, G_FILE_TEST_EXISTS)) return NM_LINK_TYPE_OLPC_MESH; - devtype = _linktype_read_devtype (sysfs_path); + devtype = _linktype_read_devtype (ifname); for (i = 0; devtype && i < G_N_ELEMENTS (linktypes); i++) { if (g_strcmp0 (devtype, linktypes[i].devtype) == 0) { if (linktypes[i].nm_type == NM_LINK_TYPE_BNEP) { @@ -729,10 +724,19 @@ _linktype_get_type (NMPlatform *platform, } /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ - if (wifi_utils_is_wifi (ifname, sysfs_path)) + if (wifi_utils_is_wifi (ifname)) return NM_LINK_TYPE_WIFI; if (arptype == ARPHRD_ETHER) { + /* Misc non-upstream WWAN drivers. rmnet is Qualcomm's proprietary + * modem interface, ccmni is MediaTek's. FIXME: these drivers should + * really set devtype=WWAN. + */ + if (g_str_has_prefix (ifname, "rmnet") || + g_str_has_prefix (ifname, "rev_rmnet") || + g_str_has_prefix (ifname, "ccmni")) + return NM_LINK_TYPE_WWAN_NET; + /* Standard wired ethernet interfaces don't report an rtnl_link_type, so * only allow fallback to Ethernet if no type is given. This should * prevent future virtual network drivers from being treated as Ethernet @@ -803,9 +807,10 @@ _nl_nlmsg_type_to_str (guint16 type, char *buf, gsize len) static gboolean _parse_af_inet6 (NMPlatform *platform, struct nlattr *attr, - NMUtilsIPv6IfaceId *out_iid, - guint8 *out_iid_is_valid, - guint8 *out_addr_gen_mode_inv) + NMUtilsIPv6IfaceId *out_token, + gboolean *out_token_valid, + guint8 *out_addr_gen_mode_inv, + gboolean *out_addr_gen_mode_valid) { static struct nla_policy policy[IFLA_INET6_MAX+1] = { [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, @@ -819,7 +824,8 @@ _parse_af_inet6 (NMPlatform *platform, struct nlattr *tb[IFLA_INET6_MAX+1]; int err; struct in6_addr i6_token; - gboolean iid_is_valid = FALSE; + gboolean token_valid = FALSE; + gboolean addr_gen_mode_valid = FALSE; guint8 i6_addr_gen_mode_inv = 0; gboolean success = FALSE; @@ -836,8 +842,7 @@ _parse_af_inet6 (NMPlatform *platform, if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) { nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr)); - if (!IN6_IS_ADDR_UNSPECIFIED (&i6_token)) - iid_is_valid = TRUE; + token_valid = TRUE; } /* Hack to detect support addrgenmode of the kernel. We only parse @@ -852,21 +857,18 @@ _parse_af_inet6 (NMPlatform *platform, * to signal "unset". */ goto errout; } + addr_gen_mode_valid = TRUE; } success = TRUE; - if (iid_is_valid) { - out_iid->id_u8[7] = i6_token.s6_addr[15]; - out_iid->id_u8[6] = i6_token.s6_addr[14]; - out_iid->id_u8[5] = i6_token.s6_addr[13]; - out_iid->id_u8[4] = i6_token.s6_addr[12]; - out_iid->id_u8[3] = i6_token.s6_addr[11]; - out_iid->id_u8[2] = i6_token.s6_addr[10]; - out_iid->id_u8[1] = i6_token.s6_addr[9]; - out_iid->id_u8[0] = i6_token.s6_addr[8]; - *out_iid_is_valid = TRUE; - } - *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; + if (token_valid) { + *out_token_valid = token_valid; + nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token); + } + if (addr_gen_mode_valid) { + *out_addr_gen_mode_valid = addr_gen_mode_valid; + *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; + } errout: return success; } @@ -1441,6 +1443,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean lnk_data_complete_from_cache = TRUE; + gboolean af_inet6_token_valid = FALSE; + gboolean af_inet6_addr_gen_mode_valid = FALSE; if (!nlmsg_valid_hdr (nlh, sizeof (*ifi))) return NULL; @@ -1472,6 +1476,15 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr nl_info_data = li[IFLA_INFO_DATA]; } + if (tb[IFLA_STATS64]) { + struct rtnl_link_stats64 *stats = nla_data (tb[IFLA_STATS64]); + + obj->link.rx_packets = stats->rx_packets; + obj->link.rx_bytes = stats->rx_bytes; + obj->link.tx_packets = stats->tx_packets; + obj->link.tx_bytes = stats->tx_bytes; + } + obj->link.n_ifi_flags = ifi->ifi_flags; obj->link.connected = NM_FLAGS_HAS (obj->link.n_ifi_flags, IFF_LOWER_UP); obj->link.arptype = ifi->ifi_type; @@ -1517,9 +1530,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case AF_INET6: _parse_af_inet6 (platform, af_attr, - &obj->link.inet6_token.iid, - &obj->link.inet6_token.is_valid, - &obj->link.inet6_addr_gen_mode_inv); + &obj->link.inet6_token, + &af_inet6_token_valid, + &obj->link.inet6_addr_gen_mode_inv, + &af_inet6_addr_gen_mode_valid); break; } } @@ -1561,7 +1575,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr if ( completed_from_cache && ( lnk_data_complete_from_cache - || address_complete_from_cache)) { + || address_complete_from_cache + || !af_inet6_token_valid + || !af_inet6_addr_gen_mode_valid + || !tb[IFLA_STATS64])) { _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); if (link_cached) { if ( lnk_data_complete_from_cache @@ -1580,6 +1597,16 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr } if (address_complete_from_cache) obj->link.addr = link_cached->link.addr; + if (!af_inet6_token_valid) + obj->link.inet6_token = link_cached->link.inet6_token; + if (!af_inet6_addr_gen_mode_valid) + obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv; + if (!tb[IFLA_STATS64]) { + obj->link.rx_packets = link_cached->link.rx_packets; + obj->link.rx_bytes = link_cached->link.rx_bytes; + obj->link.tx_packets = link_cached->link.tx_packets; + obj->link.tx_bytes = link_cached->link.tx_bytes; + } } } @@ -1666,7 +1693,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) } } - obj->ip_address.source = NM_IP_CONFIG_SOURCE_KERNEL; + obj->ip_address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; obj->ip_address.n_ifa_flags = tb[IFA_FLAGS] ? nla_get_u32 (tb[IFA_FLAGS]) @@ -1896,9 +1923,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) * * This happens, because this route is not nmp_object_is_alive(). * */ - obj->ip_route.source = _NM_IP_CONFIG_SOURCE_RTM_F_CLONED; - } else - obj->ip_route.source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); + obj->ip_route.rt_cloned = TRUE; + } + + obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); obj_result = obj; obj = NULL; @@ -1951,7 +1979,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m static gboolean _nl_msg_new_link_set_afspec (struct nl_msg *msg, - int addr_gen_mode) + int addr_gen_mode, + NMUtilsIPv6IfaceId *iid) { struct nlattr *af_spec; struct nlattr *af_attr; @@ -1961,11 +1990,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg, if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC))) goto nla_put_failure; - if (addr_gen_mode >= 0) { + if (addr_gen_mode >= 0 || iid) { if (!(af_attr = nla_nest_start (msg, AF_INET6))) goto nla_put_failure; - NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + if (addr_gen_mode >= 0) + NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + + if (iid) { + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid); + NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token); + } nla_nest_end (msg, af_attr); } @@ -2258,7 +2295,7 @@ _nl_msg_new_route (int nlmsg_type, .rtm_family = family, .rtm_tos = 0, .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ - .rtm_protocol = nmp_utils_ip_config_source_to_rtprot (source), + .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source), .rtm_scope = scope, .rtm_type = RTN_UNICAST, .rtm_flags = 0, @@ -2282,7 +2319,7 @@ _nl_msg_new_route (int nlmsg_type, addr_len = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); - clear_host_address (family, network, plen, &network_clean); + nm_utils_ipx_address_clear_host_address (family, &network_clean, network, plen); NLA_PUT (msg, RTA_DST, addr_len, &network_clean); NLA_PUT_U32 (msg, RTA_PRIORITY, metric); @@ -2485,6 +2522,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) gsize len; char *actual; gs_free char *actual_free = NULL; + int errsv; g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); @@ -2495,18 +2533,22 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) /* Don't write to suspicious locations */ g_assert (!strstr (path, "/../")); - if (!nm_platform_netns_push (platform, &netns)) + if (!nm_platform_netns_push (platform, &netns)) { + errno = ENETDOWN; return FALSE; + } fd = open (path, O_WRONLY | O_TRUNC); if (fd == -1) { - if (errno == ENOENT) { + errsv = errno; + if (errsv == ENOENT) { _LOGD ("sysctl: failed to open '%s': (%d) %s", - path, errno, strerror (errno)); + path, errsv, strerror (errsv)); } else { _LOGE ("sysctl: failed to open '%s': (%d) %s", - path, errno, strerror (errno)); + path, errsv, strerror (errsv)); } + errno = errsv; return FALSE; } @@ -2527,26 +2569,43 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) actual[len] = '\0'; /* Try to write the entire value three times if a partial write occurs */ + errsv = 0; for (tries = 0, nwrote = 0; tries < 3 && nwrote != len; tries++) { nwrote = write (fd, actual, len); if (nwrote == -1) { - if (errno == EINTR) { + errsv = errno; + if (errsv == EINTR) { _LOGD ("sysctl: interrupted, will try again"); continue; } break; } } - if (nwrote == -1 && errno != EEXIST) { + if (nwrote == -1 && errsv != EEXIST) { _LOGE ("sysctl: failed to set '%s' to '%s': (%d) %s", - path, value, errno, strerror (errno)); + path, value, errsv, strerror (errsv)); } else if (nwrote < len) { _LOGE ("sysctl: failed to set '%s' to '%s' after three attempts", path, value); } - close (fd); - return (nwrote == len); + if (nwrote != len) { + if (close (fd) != 0) { + if (errsv != 0) + errno = errsv; + } else if (errsv != 0) + errno = errsv; + else + errno = EIO; + return FALSE; + } + if (close (fd) != 0) { + /* errno is already properly set. */ + return FALSE; + } + + /* success. errno is undefined (no need to set). */ + return TRUE; } static GSList *sysctl_clear_cache_list; @@ -3689,6 +3748,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event case RTM_NEWLINK: case RTM_NEWADDR: case RTM_NEWROUTE: + case RTM_GETLINK: cache_op = nmp_cache_update_netlink (priv->cache, obj, &obj_cache, &was_visible, cache_pre_hook, platform); cache_post (platform, msghdr, cache_op, obj, obj_cache); @@ -3724,6 +3784,16 @@ cache_lookup_link (NMPlatform *platform, int ifindex) return obj_cache; } +const NMPlatformObject *const* +nm_linux_platform_lookup (NMPlatform *platform, const NMPCacheId *cache_id, guint *out_len) +{ + g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), NULL); + g_return_val_if_fail (cache_id, NULL); + + return nmp_cache_lookup_multi (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, + cache_id, out_len); +} + static GArray * link_get_all (NMPlatform *platform) { @@ -4036,6 +4106,9 @@ retry: } else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) { log_detail = ", firmware not found"; result = NM_PLATFORM_ERROR_NO_FIRMWARE; + } else if (NM_IN_SET (-((int) seq_result), ENODEV)) { + log_level = LOGL_DEBUG; + result = NM_PLATFORM_ERROR_NOT_FOUND; } else { log_level = LOGL_ERR; result = NM_PLATFORM_ERROR_UNSPECIFIED; @@ -4272,7 +4345,7 @@ link_get_udev_device (NMPlatform *platform, int ifindex) return obj_cache ? (GObject *) obj_cache->_link.udev.device : NULL; } -static gboolean +static NMPlatformError link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -4280,7 +4353,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable if (!_support_user_ipv6ll_get ()) { _LOGD ("link: change %d: user-ipv6ll: not supported", ifindex); - return FALSE; + return NM_PLATFORM_ERROR_OPNOTSUPP; } _LOGD ("link: change %d: user-ipv6ll: set IPv6 address generation mode to %s", @@ -4294,8 +4367,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable 0, 0); if ( !nlmsg - || !_nl_msg_new_link_set_afspec (nlmsg, - mode)) + || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) + g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + + return do_change_link (platform, ifindex, nlmsg); +} + +static gboolean +link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + _LOGD ("link: change %d: token: set IPv6 address generation token to %s", + ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL)); + + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0); + if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid)) g_return_val_if_reached (FALSE); return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; @@ -4338,14 +4425,14 @@ link_supports_vlans (NMPlatform *platform, int ifindex) return nmp_utils_ethtool_supports_vlans (obj->link.name); } -static gboolean +static NMPlatformError link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; gs_free char *mac = NULL; if (!address || !length) - g_return_val_if_reached (FALSE); + g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); _LOGD ("link: change %d: address: %s (%lu bytes)", ifindex, (mac = nm_utils_hwaddr_ntoa (address, length)), @@ -4358,13 +4445,13 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size 0, 0); if (!nlmsg) - return FALSE; + g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); NLA_PUT (nlmsg, IFLA_ADDRESS, length, address); - return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; + return do_change_link (platform, ifindex, nlmsg); nla_put_failure: - g_return_val_if_reached (FALSE); + g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); } static gboolean @@ -5095,57 +5182,67 @@ link_release (NMPlatform *platform, int master, int slave) /******************************************************************/ static gboolean -_infiniband_partition_action (NMPlatform *platform, int parent, int p_key, const char *action, char **ifname) +_infiniband_partition_action (NMPlatform *platform, + InfinibandAction action, + int parent, + int p_key, + const NMPlatformLink **out_link) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const NMPObject *obj_parent; - gs_free char *path = NULL; - gs_free char *id = NULL; + const NMPObject *obj; + char path[NM_STRLEN ("/sys/class/net/%s/%s") + IFNAMSIZ + 100]; + char id[20]; + char name[IFNAMSIZ]; + gboolean success; + + nm_assert (NM_IN_SET (action, INFINIBAND_ACTION_CREATE_CHILD, INFINIBAND_ACTION_DELETE_CHILD)); + nm_assert (p_key > 0 && p_key <= 0xffff && p_key != 0x8000); obj_parent = nmp_cache_lookup_link (priv->cache, parent); - if (!obj_parent || !obj_parent->link.name[0]) - g_return_val_if_reached (FALSE); + if (!obj_parent || !obj_parent->link.name[0]) { + errno = ENOENT; + return FALSE; + } + + nm_sprintf_buf (path, + "/sys/class/net/%s/%s", + NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name), + (action == INFINIBAND_ACTION_CREATE_CHILD + ? "create_child" + : "delete_child")); + nm_sprintf_buf (id, "0x%04x", p_key); + success = nm_platform_sysctl_set (platform, path, id); + if (!success) { + if ( action == INFINIBAND_ACTION_DELETE_CHILD + && errno == ENODEV) + return TRUE; + return FALSE; + } - *ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key); + nm_utils_new_infiniband_name (name, obj_parent->link.name, p_key); + do_request_link (platform, 0, name); - path = g_strdup_printf ("/sys/class/net/%s/%s", - NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name), - action); - id = g_strdup_printf ("0x%04x", p_key); + if (action == INFINIBAND_ACTION_DELETE_CHILD) + return TRUE; - return nm_platform_sysctl_set (platform, path, id); + obj = nmp_cache_lookup_link_full (priv->cache, 0, name, FALSE, + NM_LINK_TYPE_INFINIBAND, NULL, NULL); + if (out_link) + *out_link = obj ? &obj->link : NULL; + return !!obj; } - static gboolean infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) { - const NMPObject *obj; - gs_free char *ifname = NULL; - - if (!_infiniband_partition_action (platform, parent, p_key, "create_child", &ifname)) - return FALSE; - - do_request_link (platform, 0, ifname); - - obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, - 0, ifname, FALSE, NM_LINK_TYPE_INFINIBAND, NULL, NULL); - if (out_link) - *out_link = obj ? &obj->link : NULL; - return !!obj; + return _infiniband_partition_action (platform, INFINIBAND_ACTION_CREATE_CHILD, parent, p_key, out_link); } static gboolean infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) { - gs_free char *ifname = NULL; - - if (!_infiniband_partition_action (platform, parent, p_key, "delete_child", &ifname)) { - if (errno != ENODEV) - return FALSE; - } - - return TRUE; + return _infiniband_partition_action (platform, INFINIBAND_ACTION_DELETE_CHILD, parent, p_key, NULL); } /******************************************************************/ @@ -5587,7 +5684,7 @@ ipx_route_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type, NM nm_assert (NMP_OBJECT_GET_CLASS (NMP_OBJECT_UP_CAST (routes[i])) == klass); if ( with_rtprot_kernel - || routes[i]->source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) + || routes[i]->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) g_array_append_vals (array, routes[i], 1); } return array; @@ -6421,6 +6518,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_udev_device = link_get_udev_device; platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_token = link_set_token; platform_class->link_set_address = link_set_address; platform_class->link_get_permanent_address = link_get_permanent_address; diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index 4ae2fd14..3b2a440e 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -52,4 +52,10 @@ NMPlatform *nm_linux_platform_new (gboolean netns_support); void nm_linux_platform_setup (void); +struct _NMPCacheId; + +const NMPlatformObject *const *nm_linux_platform_lookup (NMPlatform *platform, + const struct _NMPCacheId *cache_id, + guint *out_len); + #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index b4542adf..068801ee 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -144,8 +144,7 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, struct ethtool_perm_addr e; guint8 _extra_data[NM_UTILS_HWADDR_LEN_MAX + 1]; } edata; - static const guint8 zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; - static guint8 ones[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; + guint i; if (!ifname) return FALSE; @@ -157,18 +156,23 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, if (!ethtool_get (ifname, &edata.e)) return FALSE; - g_assert (edata.e.size <= NM_UTILS_HWADDR_LEN_MAX); - - /* Some drivers might return a permanent address of all zeros. - * Reject that (rh#1264024) */ - if (memcmp (edata.e.data, zeros, edata.e.size) == 0) + if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + if (edata.e.size < 1) return FALSE; - /* Some drivers return a permanent address of all ones. Reject that too */ - if (G_UNLIKELY (ones[0] != 0xFF)) - memset (ones, 0xFF, sizeof (ones)); - if (memcmp (edata.e.data, ones, edata.e.size) == 0) + if (NM_IN_SET (edata.e.data[0], 0, 0xFF)) { + /* Some drivers might return a permanent address of all zeros. + * Reject that (rh#1264024) + * + * Some drivers return a permanent address of all ones. Reject that too */ + for (i = 1; i < edata.e.size; i++) { + if (edata.e.data[0] != edata.e.data[i]) + goto not_all_0or1; + } return FALSE; + } +not_all_0or1: memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; @@ -433,14 +437,35 @@ nmp_utils_device_exists (const char *name) return g_file_test (sysdir, G_FILE_TEST_EXISTS); } -guint -nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source) +NMIPConfigSource +nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) { - switch (source) { - case NM_IP_CONFIG_SOURCE_UNKNOWN: + return ((int) rtprot) + 1; +} + +NMIPConfigSource +nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) +{ + /* when adding a route to kernel for a give @source, the resulting route + * will be put into the cache with a source of NM_IP_CONFIG_SOURCE_RTPROT_*. + * This function returns that. */ + return nmp_utils_ip_config_source_from_rtprot (nmp_utils_ip_config_source_coerce_to_rtprot (source)); +} + +guint8 +nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) +{ + /* when adding a route to kernel, we coerce the @source field + * to rtm_protocol. This is not lossless as we map different + * source values to the same RTPROT uint8 value. */ + if (source <= NM_IP_CONFIG_SOURCE_UNKNOWN) return RTPROT_UNSPEC; + + if (source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST) + return source - 1; + + switch (source) { case NM_IP_CONFIG_SOURCE_KERNEL: - case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: return RTPROT_KERNEL; case NM_IP_CONFIG_SOURCE_DHCP: return RTPROT_DHCP; @@ -453,18 +478,32 @@ nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source) } NMIPConfigSource -nmp_utils_ip_config_source_from_rtprot (guint rtprot) +nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) { - switch (rtprot) { - case RTPROT_UNSPEC: + /* When we receive a route from kernel and put it into the platform cache, + * we preserve the protocol field by converting it to a NMIPConfigSource + * via nmp_utils_ip_config_source_from_rtprot(). + * + * However, that is not the inverse of nmp_utils_ip_config_source_coerce_to_rtprot(). + * Instead, to go back to the original value, you need another step: + * nmp_utils_ip_config_source_coerce_from_rtprot (nmp_utils_ip_config_source_from_rtprot (rtprot)). + * + * This might partly restore the original source value, but of course that + * is not really possible because nmp_utils_ip_config_source_coerce_to_rtprot() + * is not injective. + * */ + switch (source) { + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: return NM_IP_CONFIG_SOURCE_UNKNOWN; - case RTPROT_KERNEL: - return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; - case RTPROT_REDIRECT: + + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: return NM_IP_CONFIG_SOURCE_KERNEL; - case RTPROT_RA: + + case NM_IP_CONFIG_SOURCE_RTPROT_RA: return NM_IP_CONFIG_SOURCE_RDISC; - case RTPROT_DHCP: + + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: return NM_IP_CONFIG_SOURCE_DHCP; default: @@ -472,3 +511,50 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot) } } +const char * +nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len) +{ + const char *s = NULL; + nm_utils_to_string_buffer_init (&buf, &len); \ + + if (!len) + return buf; + + switch (source) { + case NM_IP_CONFIG_SOURCE_UNKNOWN: s = "unknown"; break; + + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: s = "rt-unspec"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: s = "rt-redirect"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: s = "rt-kernel"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_BOOT: s = "rt-boot"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_STATIC: s = "rt-static"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: s = "rt-dhcp"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_RA: s = "rt-ra"; break; + + case NM_IP_CONFIG_SOURCE_KERNEL: s = "kernel"; break; + case NM_IP_CONFIG_SOURCE_SHARED: s = "shared"; break; + case NM_IP_CONFIG_SOURCE_IP4LL: s = "ipv4ll"; break; + case NM_IP_CONFIG_SOURCE_PPP: s = "ppp"; break; + case NM_IP_CONFIG_SOURCE_WWAN: s = "wwan"; break; + case NM_IP_CONFIG_SOURCE_VPN: s = "vpn"; break; + case NM_IP_CONFIG_SOURCE_DHCP: s = "dhcp"; break; + case NM_IP_CONFIG_SOURCE_RDISC: s = "rdisc"; break; + case NM_IP_CONFIG_SOURCE_USER: s = "user"; break; + default: + break; + } + + if (source >= 1 && source <= 0x100) { + if (s) + g_snprintf (buf, len, "%s", s); + else + g_snprintf (buf, len, "rt-%d", ((int) source) - 1); + } else { + if (s) + g_strlcpy (buf, s, len); + else + g_snprintf (buf, len, "(%d)", source); + } + return buf; +} + diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index f2594747..456c0865 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -54,7 +54,10 @@ const char *nmp_utils_udev_get_driver (GUdevDevice *device); gboolean nmp_utils_device_exists (const char *name); -guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source); -NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot); +NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) _nm_const; +guint8 nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const; +const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len); #endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 26ac766d..9dace699 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -205,6 +205,7 @@ NM_UTILS_LOOKUP_STR_DEFINE (_nm_platform_error_to_string, NMPlatformError, NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_WRONG_TYPE, "wrong-type"), NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NOT_SLAVE, "not-slave"), NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NO_FIRMWARE, "no-firmware"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_OPNOTSUPP, "not-supported"), NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT), ); @@ -387,6 +388,20 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint ba /******************************************************************/ +static int +_link_get_all_presort (gconstpointer p_a, + gconstpointer p_b) +{ + const NMPlatformLink *a = p_a; + const NMPlatformLink *b = p_b; + + if (a->ifindex < b->ifindex) + return -1; + if (a->ifindex > b->ifindex) + return 1; + return 0; +} + /** * nm_platform_link_get_all: * self: platform instance @@ -409,15 +424,17 @@ nm_platform_link_get_all (NMPlatform *self) if (!links || links->len == 0) return links; + /* first sort the links by their ifindex. Below we will sort further by moving + * children/slaves to the end. */ + g_array_sort (links, _link_get_all_presort); + unseen = g_hash_table_new (g_direct_hash, g_direct_equal); for (i = 0; i < links->len; i++) { item = &g_array_index (links, NMPlatformLink, i); - _LOGt ("link-get: %3d: %s", i, nm_platform_link_to_string (item, NULL, 0)); - - nm_assert (item->ifindex > 0 && !g_hash_table_contains (unseen, GINT_TO_POINTER (item->ifindex))); - - g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL); + nm_assert (item->ifindex > 0); + if (!nm_g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL)) + nm_assert_not_reached (); } #ifndef G_DISABLE_ASSERT @@ -468,8 +485,6 @@ nm_platform_link_get_all (NMPlatform *self) if (item->parent > 0 && g_hash_table_contains (unseen, GINT_TO_POINTER (item->parent))) continue; - _LOGt ("link-get: add %3d -> %3d: %s", i, j, nm_platform_link_to_string (item, NULL, 0)); - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); g_array_index (result, NMPlatformLink, j++) = *item; item->ifindex = 0; @@ -481,8 +496,6 @@ nm_platform_link_get_all (NMPlatform *self) * This can happen for veth pairs where each peer is parent of the other end. */ item = &g_array_index (links, NMPlatformLink, first_idx); - _LOGt ("link-get: add (loop) %3d -> %3d: %s", first_idx, j, nm_platform_link_to_string (item, NULL, 0)); - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); g_array_index (result, NMPlatformLink, j++) = *item; item->ifindex = 0; @@ -888,33 +901,25 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex) } /** - * nm_platform_link_get_ipv6_token: + * nm_platform_link_set_ipv6_token: * @self: platform instance * @ifindex: Interface index * @iid: Tokenized interface identifier * - * Returns IPv6 tokenized interface identifier. If the platform or OS doesn't - * support IPv6 tokenized interface identifiers, or the token is not set - * this call will fail and return %FALSE. + * Sets then IPv6 tokenized interface identifier. * * Returns: %TRUE a tokenized identifier was available */ gboolean -nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid) +nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) { - const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex >= 0, FALSE); - g_return_val_if_fail (iid, FALSE); + g_return_val_if_fail (iid.id, FALSE); - - pllink = nm_platform_link_get (self, ifindex); - if (pllink && pllink->inet6_token.is_valid) { - *iid = pllink->inet6_token.iid; - return TRUE; - } + if (klass->link_set_token) + return klass->link_set_token (self, ifindex, iid); return FALSE; } @@ -977,18 +982,16 @@ nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex) * platform or OS doesn't support changing the IPv6LL address mode, this call * will fail and return %FALSE. * - * Returns: %TRUE if the operation was successful, %FALSE if it failed. + * Returns: %NM_PLATFORM_ERROR_SUCCESS if the operation was successful or an error code otherwise. */ -gboolean +NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); - if (klass->link_set_user_ipv6ll_enabled) - return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); - return FALSE; + return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); } /** @@ -999,16 +1002,18 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea * * Set interface MAC address. */ -gboolean +NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (address, FALSE); - g_return_val_if_fail (length > 0, FALSE); + g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (address, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (length > 0, NM_PLATFORM_ERROR_BUG); - _LOGD ("link: setting '%s' (%d) hardware address", nm_platform_link_get_name (self, ifindex), ifindex); + _LOGD ("link: setting %s (%d) hardware address", + nm_strquote_a (20, nm_platform_link_get_name (self, ifindex)), + ifindex); return klass->link_set_address (self, ifindex, address, length); } @@ -1895,21 +1900,27 @@ _infiniband_add_add_or_delete (NMPlatform *self, gboolean add, const NMPlatformLink **out_link) { - gs_free char *parent_name = NULL; - gs_free char *name = NULL; + char name[IFNAMSIZ]; + const NMPlatformLink *parent_link; NMPlatformError plerr; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (parent >= 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (p_key >= 0, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NM_PLATFORM_ERROR_BUG); + + /* the special keys 0x0000 and 0x8000 are not allowed. */ + if (NM_IN_SET (p_key, 0, 0x8000)) + return NM_PLATFORM_ERROR_UNSPECIFIED; - parent_name = g_strdup (nm_platform_link_get_name (self, parent)); - if ( !parent_name - || nm_platform_link_get_type (self, parent) != NM_LINK_TYPE_INFINIBAND) + parent_link = nm_platform_link_get (self, parent); + if (!parent_link) + return NM_PLATFORM_ERROR_NOT_FOUND; + + if (parent_link->type != NM_LINK_TYPE_INFINIBAND) return NM_PLATFORM_ERROR_WRONG_TYPE; - name = g_strdup_printf ("%s.%04x", parent_name, p_key); + nm_utils_new_infiniband_name (name, parent_link->name, p_key); if (add) { plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); @@ -1917,7 +1928,7 @@ _infiniband_add_add_or_delete (NMPlatform *self, return plerr; _LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d", - name, parent_name, parent, p_key); + name, parent_link->name, parent, p_key); if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; } else { @@ -2894,7 +2905,7 @@ nm_platform_ip4_route_add (NMPlatform *self, NMPlatformIP4Route route = { 0 }; route.ifindex = ifindex; - route.source = source; + route.rt_source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -2921,7 +2932,7 @@ nm_platform_ip6_route_add (NMPlatform *self, NMPlatformIP6Route route = { 0 }; route.ifindex = ifindex; - route.source = source; + route.rt_source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -3012,38 +3023,6 @@ nm_platform_vlan_qos_mapping_to_string (const char *name, } static const char * -source_to_string (NMIPConfigSource source) -{ - switch (source) { - case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: - return "rtprot-kernel"; - case _NM_IP_CONFIG_SOURCE_RTM_F_CLONED: - return "rtm-f-cloned"; - case NM_IP_CONFIG_SOURCE_KERNEL: - return "kernel"; - case NM_IP_CONFIG_SOURCE_SHARED: - return "shared"; - case NM_IP_CONFIG_SOURCE_IP4LL: - return "ipv4ll"; - case NM_IP_CONFIG_SOURCE_PPP: - return "ppp"; - case NM_IP_CONFIG_SOURCE_WWAN: - return "wwan"; - case NM_IP_CONFIG_SOURCE_VPN: - return "vpn"; - case NM_IP_CONFIG_SOURCE_DHCP: - return "dhcp"; - case NM_IP_CONFIG_SOURCE_RDISC: - return "rdisc"; - case NM_IP_CONFIG_SOURCE_USER: - return "user"; - default: - break; - } - return "unknown"; -} - -static const char * _lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) { if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT) @@ -3081,7 +3060,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) GString *str_flags; char str_addrmode[30]; gs_free char *str_addr = NULL; - gs_free char *str_inet6_token = NULL; + char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; const char *str_link_type; if (!nm_utils_to_string_buffer_init_null (link, &buf, &len)) @@ -3118,8 +3097,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) if (link->addr.len) str_addr = nm_utils_hwaddr_ntoa (link->addr.data, MIN (link->addr.len, sizeof (link->addr.data))); - if (link->inet6_token.is_valid) - str_inet6_token = nm_utils_hwaddr_ntoa (&link->inet6_token.iid, sizeof (link->inet6_token.iid)); str_link_type = nm_link_type_to_string (link->type); @@ -3138,6 +3115,8 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) "%s%s" /* addr */ "%s%s" /* inet6_token */ "%s%s" /* driver */ + " rx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT + " tx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT , link->ifindex, link->name, @@ -3153,10 +3132,12 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "", str_addr ? " addr " : "", str_addr ? str_addr : "", - str_inet6_token ? " inet6token " : "", - str_inet6_token ? str_inet6_token : "", + link->inet6_token.id ? " inet6token " : "", + link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "", link->driver ? " driver " : "", - link->driver ? link->driver : ""); + link->driver ? link->driver : "", + link->rx_packets, link->rx_bytes, + link->tx_packets, link->tx_bytes); g_string_free (str_flags, TRUE); return buf; } @@ -3471,7 +3452,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu char s_peer[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; char str_label[32]; - char str_lft[30], str_pref[30], str_time[50]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; gint32 now = nm_utils_get_monotonic_timestamp_s (); @@ -3510,7 +3491,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu str_dev, _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), str_label, - source_to_string (address->source)); + nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source))); g_free (str_peer); return buf; } @@ -3582,7 +3563,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; char s_address[INET6_ADDRSTRLEN]; char s_peer[INET6_ADDRSTRLEN]; - char str_lft[30], str_pref[30], str_time[50]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; char str_dev[TO_STRING_DEV_BUF_SIZE]; char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; @@ -3616,7 +3597,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu str_peer ? str_peer : "", str_dev, _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), - source_to_string (address->source)); + nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source))); g_free (str_peer); return buf; } @@ -3639,7 +3620,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; char s_pref_src[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; - char str_scope[30]; + char str_scope[30], s_source[50]; if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) return buf; @@ -3656,6 +3637,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi " metric %"G_GUINT32_FORMAT " mss %"G_GUINT32_FORMAT " src %s" /* source */ + "%s" /* cloned */ "%s%s" /* scope */ "%s%s" /* pref-src */ "", @@ -3665,7 +3647,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi str_dev, route->metric, route->mss, - source_to_string (route->source), + nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), + route->rt_cloned ? " cloned" : "", route->scope_inv ? " scope " : "", route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "", route->pref_src ? " pref-src " : "", @@ -3689,7 +3672,7 @@ const char * nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len) { char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50]; if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) return buf; @@ -3706,6 +3689,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi " metric %"G_GUINT32_FORMAT " mss %"G_GUINT32_FORMAT " src %s" /* source */ + "%s" /* cloned */ "", s_network, route->plen, @@ -3713,7 +3697,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi str_dev, route->metric, route->mss, - source_to_string (route->source)); + nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), + route->rt_cloned ? " cloned" : ""); return buf; } @@ -3808,13 +3793,15 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) _CMP_FIELD (a, b, arptype); _CMP_FIELD (a, b, addr.len); _CMP_FIELD (a, b, inet6_addr_gen_mode_inv); - _CMP_FIELD (a, b, inet6_token.is_valid); _CMP_FIELD_STR_INTERNED (a, b, kind); _CMP_FIELD_STR_INTERNED (a, b, driver); if (a->addr.len) _CMP_FIELD_MEMCMP_LEN (a, b, addr.data, a->addr.len); - if (a->inet6_token.is_valid) - _CMP_FIELD_MEMCMP (a, b, inet6_token.iid); + _CMP_FIELD_MEMCMP (a, b, inet6_token); + _CMP_FIELD (a, b, rx_packets); + _CMP_FIELD (a, b, rx_bytes); + _CMP_FIELD (a, b, tx_packets); + _CMP_FIELD (a, b, tx_bytes); return 0; } @@ -3935,10 +3922,10 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD (a, b, address); _CMP_FIELD (a, b, plen); _CMP_FIELD (a, b, peer_address); + _CMP_FIELD (a, b, addr_source); _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); @@ -3954,14 +3941,12 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD_MEMCMP (a, b, address); - + _CMP_FIELD (a, b, plen); p_a = nm_platform_ip6_address_get_peer (a); p_b = nm_platform_ip6_address_get_peer (b); _CMP_DIRECT_MEMCMP (p_a, p_b, sizeof (*p_a)); - - _CMP_FIELD (a, b, plen); + _CMP_FIELD (a, b, addr_source); _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); @@ -3974,14 +3959,15 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD (a, b, network); _CMP_FIELD (a, b, plen); - _CMP_FIELD (a, b, gateway); _CMP_FIELD (a, b, metric); + _CMP_FIELD (a, b, gateway); + _CMP_FIELD (a, b, rt_source); _CMP_FIELD (a, b, mss); _CMP_FIELD (a, b, scope_inv); _CMP_FIELD (a, b, pref_src); + _CMP_FIELD (a, b, rt_cloned); return 0; } @@ -3990,12 +3976,13 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD_MEMCMP (a, b, network); _CMP_FIELD (a, b, plen); - _CMP_FIELD_MEMCMP (a, b, gateway); _CMP_FIELD (a, b, metric); + _CMP_FIELD_MEMCMP (a, b, gateway); + _CMP_FIELD (a, b, rt_source); _CMP_FIELD (a, b, mss); + _CMP_FIELD (a, b, rt_cloned); return 0; } @@ -4128,7 +4115,7 @@ _vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout { return nm_platform_ip4_route_add (self, ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.source, + route->rx.rt_source, route->r4.network, route->rx.plen, route->r4.gateway, @@ -4142,7 +4129,7 @@ _vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout { return nm_platform_ip6_route_add (self, ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.source, + route->rx.rt_source, route->r6.network, route->rx.plen, route->r6.gateway, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 19724f1c..fc6965e9 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -49,8 +49,6 @@ /******************************************************************/ -typedef struct _NMPlatform NMPlatform; - /* workaround for older libnl version, that does not define these flags. */ #ifndef IFA_F_MANAGETEMPADDR #define IFA_F_MANAGETEMPADDR 0x100 @@ -90,6 +88,7 @@ typedef enum { /*< skip >*/ NM_PLATFORM_ERROR_WRONG_TYPE, NM_PLATFORM_ERROR_NOT_SLAVE, NM_PLATFORM_ERROR_NO_FIRMWARE, + NM_PLATFORM_ERROR_OPNOTSUPP, } NMPlatformError; @@ -98,6 +97,11 @@ typedef struct { guint8 addr_ptr[1]; in_addr_t addr4; struct in6_addr addr6; + + /* NMIPAddr is really a union for IP addresses. + * However, as ethernet addresses fit in here nicely, ruse + * it also for an ethernet MAC address. */ + guint8 addr_eth[6 /*ETH_ALEN*/]; }; } NMIPAddr; @@ -144,17 +148,20 @@ struct _NMPlatformLink { guint8 len; } addr; - /* rtnl_link_inet6_get_token() */ - struct { - NMUtilsIPv6IfaceId iid; - guint8 is_valid; - } inet6_token; + /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */ + NMUtilsIPv6IfaceId inet6_token; /* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse * to have a default of 0 -- meaning: unspecified. That way, a struct * initialized with memset(0) has and unset value.*/ guint8 inet6_addr_gen_mode_inv; + /* Statistics */ + guint64 rx_packets; + guint64 rx_bytes; + guint64 tx_packets; + guint64 tx_bytes; + /* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters, * where we coerce the link as disconnect if it has no slaves. */ bool connected:1; @@ -200,7 +207,7 @@ typedef struct { #define __NMPlatformIPAddress_COMMON \ __NMPlatformObject_COMMON; \ - NMIPConfigSource source; \ + NMIPConfigSource addr_source; \ \ /* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*(). * @@ -303,8 +310,21 @@ typedef union { #define __NMPlatformIPRoute_COMMON \ __NMPlatformObject_COMMON; \ - NMIPConfigSource source; \ + \ + /* The NMIPConfigSource. For routes that we receive from cache this corresponds + * to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values). + * When adding a route, the source will be coerced to the protocol using + * nmp_utils_ip_config_source_coerce_to_rtprot(). */ \ + NMIPConfigSource rt_source; \ + \ guint8 plen; \ + \ + /* the route has rtm_flags set to RTM_F_CLONED. Such a route + * is hidden by platform and does not exist from the point-of-view + * of platform users. This flag is internal to track those hidden + * routes. Such a route is not alive, according to nmp_object_is_alive(). */ \ + bool rt_cloned:1; \ + \ guint32 metric; \ guint32 mss; \ ; @@ -506,13 +526,14 @@ typedef struct { const char *(*link_get_udi) (NMPlatform *self, int ifindex); GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex); - gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + NMPlatformError (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid); gboolean (*link_get_permanent_address) (NMPlatform *, int ifindex, guint8 *buf, size_t *length); - gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); + NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); @@ -717,7 +738,6 @@ gboolean nm_platform_link_is_up (NMPlatform *self, int ifindex); gboolean nm_platform_link_is_connected (NMPlatform *self, int ifindex); gboolean nm_platform_link_uses_arp (NMPlatform *self, int ifindex); guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex); -gboolean nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid); gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex); gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length); int nm_platform_link_get_master (NMPlatform *self, int slave); @@ -740,10 +760,11 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex); GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex); -gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length); -gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); +NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index eb7e1ca4..30a52c25 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -47,6 +47,10 @@ } \ } G_STMT_END +/* logging to trace object lifetime and references. + * Disabled by default. */ +#define _LOGr(...) G_STMT_START { if (FALSE) { _LOGt (__VA_ARGS__); } } G_STMT_END + /*********************************************************************************************/ struct _NMPCache { @@ -211,7 +215,7 @@ nmp_object_ref (NMPObject *obj) g_return_val_if_fail (obj->_ref_count != NMP_REF_COUNT_STACKINIT, NULL); obj->_ref_count++; - _LOGt (obj, "ref: %d", obj->_ref_count); + _LOGr (obj, "ref: %d", obj->_ref_count); return obj; } @@ -222,7 +226,7 @@ nmp_object_unref (NMPObject *obj) if (obj) { g_return_if_fail (obj->_ref_count > 0); g_return_if_fail (obj->_ref_count != NMP_REF_COUNT_STACKINIT); - _LOGt (obj, "%s: %d", + _LOGr (obj, "%s: %d", obj->_ref_count <= 1 ? "destroy" : "unref", obj->_ref_count - 1); if (--obj->_ref_count <= 0) { @@ -262,7 +266,7 @@ _nmp_object_new_from_class (const NMPClass *klass) obj = g_slice_alloc0 (klass->sizeof_data + G_STRUCT_OFFSET (NMPObject, object)); obj->_class = klass; obj->_ref_count = 1; - _LOGt (obj, "new"); + _LOGr (obj, "new"); return obj; } @@ -915,12 +919,12 @@ _vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj) * * If nmp_object_from_nl() would just return NULL, we couldn't look * into the cache to see if it contains a route that now disappears - * (because it is cloned). + * (because it changed to be cloned). * * Instead we create a dead object, and nmp_cache_update_netlink() * will remove the old version of the update. **/ - return obj->object.ifindex > 0 && (obj->ip_route.source != _NM_IP_CONFIG_SOURCE_RTM_F_CLONED); + return obj->object.ifindex > 0 && !obj->ip_route.rt_cloned; } gboolean diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index c5241037..d295f7a0 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -94,9 +94,9 @@ typedef enum { /*< skip >*/ NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, } NMPCacheIdType; -typedef struct _NMPObject NMPObject; +typedef struct _NMPCacheId NMPCacheId; -typedef struct { +struct _NMPCacheId { union { NMMultiIndexId base; guint8 _id_type; /* NMPCacheIdType as guint8 */ @@ -136,7 +136,7 @@ typedef struct { struct in6_addr _misaligned_network; } routes_by_destination_ip6; }; -} NMPCacheId; +}; extern NMPCacheId _nmp_cache_id_static; #define NMP_CACHE_ID_STATIC (&_nmp_cache_id_static) diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index 5af4ce91..0633dd28 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -28,7 +28,7 @@ TEST_SOURCES = \ AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(CODE_COVERAGE_LDFLAGS) PLATFORM_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @GNOME_CODE_COVERAGE_RULES@ @@ -109,12 +109,12 @@ test_cleanup_linux_LDADD = $(PLATFORM_LDADD) test_nmp_object_SOURCES = \ test-nmp-object.c test_nmp_object_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_general_SOURCES = \ test-general.c test_general_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @VALGRIND_RULES@ diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in index 49f2fa09..4922a3dc 100644 --- a/src/platform/tests/Makefile.in +++ b/src/platform/tests/Makefile.in @@ -102,8 +102,9 @@ TESTS = test-address-fake$(EXEEXT) test-address-linux$(EXEEXT) \ test-route-fake$(EXEEXT) test-route-linux$(EXEEXT) subdir = src/platform/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -170,7 +171,8 @@ test_cleanup_linux_OBJECTS = $(am_test_cleanup_linux_OBJECTS) test_cleanup_linux_DEPENDENCIES = $(PLATFORM_LDADD) am_test_general_OBJECTS = test-general.$(OBJEXT) test_general_OBJECTS = $(am_test_general_OBJECTS) -test_general_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +test_general_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManagerTest.la am__objects_10 = test_link_fake-nm-platform.$(OBJEXT) \ test_link_fake-nm-fake-platform.$(OBJEXT) \ test_link_fake-nm-linux-platform.$(OBJEXT) @@ -192,7 +194,7 @@ test_link_linux_DEPENDENCIES = $(PLATFORM_LDADD) am_test_nmp_object_OBJECTS = test-nmp-object.$(OBJEXT) test_nmp_object_OBJECTS = $(am_test_nmp_object_OBJECTS) test_nmp_object_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la am__objects_14 = test_route_fake-nm-platform.$(OBJEXT) \ test_route_fake-nm-fake-platform.$(OBJEXT) \ test_route_fake-nm-linux-platform.$(OBJEXT) @@ -522,6 +524,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -578,13 +581,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -596,6 +600,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -656,6 +662,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -691,6 +699,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -772,7 +781,7 @@ TEST_SOURCES = \ AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(CODE_COVERAGE_LDFLAGS) PLATFORM_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la EXTRA_DIST = test-common.h monitor_SOURCES = monitor.c $(PLATFORM_SOURCES) @@ -837,13 +846,13 @@ test_nmp_object_SOURCES = \ test-nmp-object.c test_nmp_object_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_general_SOURCES = \ test-general.c test_general_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la all: all-am diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index 3af34be4..937eea11 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -25,7 +25,7 @@ #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" NMTST_DEFINE (); diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 0e3cf10b..87fccee2 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -8,7 +8,7 @@ #include "nm-fake-platform.h" #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define DEVICE_NAME "nm-test-device" @@ -84,7 +84,7 @@ void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, N /*****************************************************************************/ -int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__printf__, 1, 2))); +int nmtstp_run_command (const char *format, ...) _nm_printf (1, 2); #define nmtstp_run_command_check(...) do { g_assert_cmpint (nmtstp_run_command (__VA_ARGS__), ==, 0); } while (0) /*****************************************************************************/ diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index d8d92561..f67f0089 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -25,7 +25,7 @@ #include "nm-platform-utils.h" #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /******************************************************************/ diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 9d548aab..99873620 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -30,7 +30,7 @@ #include "nm-platform-utils.h" #include "test-common.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define LO_INDEX 1 #define LO_NAME "lo" @@ -60,16 +60,12 @@ test_bogus(void) g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX)); g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX)); g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX)); @@ -80,7 +76,6 @@ test_bogus(void) g_assert (!addrlen); g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU)); g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX)); @@ -226,7 +221,7 @@ test_slave (int master, int type, SignalData *master_changed) g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, master); accept_signals (link_changed, 1, 3); - accept_signals (master_changed, 0, 1); + accept_signals (master_changed, 0, 2); /* enslaveing brings put the slave */ if (NM_IN_SET (link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) @@ -515,13 +510,13 @@ test_bridge_addr (void) g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); - g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE)); + g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE) == NM_PLATFORM_ERROR_SUCCESS); g_assert (nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); g_assert (plink); g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE); - g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE)); + g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE) == NM_PLATFORM_ERROR_SUCCESS); g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); g_assert (plink); @@ -572,7 +567,7 @@ test_internal (void) g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); + accept_signals (link_changed, 1, 2); g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); @@ -592,7 +587,7 @@ test_internal (void) g_assert (nm_platform_link_supports_vlans (NM_PLATFORM_GET, ifindex)); /* Set MAC address */ - g_assert (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac))); + g_assert (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac)) == NM_PLATFORM_ERROR_SUCCESS); address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addrlen); g_assert (addrlen == sizeof(mac)); g_assert (!memcmp (address, mac, addrlen)); @@ -778,11 +773,32 @@ test_software_detect (gconstpointer user_data) } case NM_LINK_TYPE_MACVLAN: { NMPlatformLnkMacvlan lnk_macvlan = { }; + const NMPlatformLink *dummy; + char buf[256]; + int i; lnk_macvlan.mode = MACVLAN_MODE_BRIDGE; lnk_macvlan.no_promisc = FALSE; lnk_macvlan.tap = FALSE; + /* Since in old kernel versions sysfs files for macvtaps are not + * namespaced, the creation can fail if a macvtap in another namespace + * has the same index. Try to detect this situation and skip already + * used indexes. + * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=17af2bce88d31e65ed73d638bb752d2e13c66ced + */ + for (i = ifindex_parent + 1; i < ifindex_parent + 100; i++) { + snprintf (buf, sizeof (buf), "/sys/class/macvtap/tap%d", i); + if (!g_file_test (buf, G_FILE_TEST_IS_SYMLINK)) + break; + + _LOGD ("skipping ifindex %d as already used by a macvtap", i); + + dummy = nmtstp_link_dummy_add (NM_PLATFORM_GET, FALSE, "dummy-tmp"); + g_assert_cmpint (dummy->ifindex, ==, i); + nmtstp_link_del (NM_PLATFORM_GET, FALSE, dummy->ifindex, NULL); + } + if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) g_error ("Failed adding MACVLAN interface"); break; @@ -1861,7 +1877,7 @@ _test_netns_setup (gpointer fixture, gconstpointer test_data) { /* the singleton platform instance has netns support disabled. * Destroy the instance before the test and re-create it afterwards. */ - g_object_unref (nm_platform_get ()); + g_object_unref (NM_PLATFORM_GET); } static void @@ -1919,6 +1935,14 @@ _test_netns_check_skip (void) /******************************************************************/ +#define _sysctl_assert_eq(plat, path, value) \ + G_STMT_START { \ + gs_free char *_val = NULL; \ + \ + _val = nm_platform_sysctl_get (plat, path); \ + g_assert_cmpstr (_val, ==, value); \ + } G_STMT_END + static void test_netns_general (gpointer fixture, gconstpointer test_data) { @@ -1954,13 +1978,19 @@ test_netns_general (gpointer fixture, gconstpointer test_data) _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-c-%s-%02d", id, i)); } - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, NULL); + _sysctl_assert_eq (platform_1,"/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex", + NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex", + NULL); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); for (i = 0; i < 10; i++) { NMPlatform *pl; @@ -1982,10 +2012,11 @@ test_netns_general (gpointer fixture, gconstpointer test_data) path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; } g_assert (nm_platform_sysctl_set (pl, path, nm_sprintf_buf (sbuf, "%d", j))); - g_assert_cmpstr (nm_platform_sysctl_get (pl, path), ==, nm_sprintf_buf (sbuf, "%d", j)); + _sysctl_assert_eq (pl, path, nm_sprintf_buf (sbuf, "%d", j)); } - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"), ==, NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6"), ==, NULL); + + _sysctl_assert_eq (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6", NULL); + _sysctl_assert_eq (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6", NULL); /* older kernels (Ubuntu 12.04) don't support ethtool -i for dummy devices. Work around that and * skip asserts that are known to fail. */ diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c index d77170b3..9d4f69de 100644 --- a/src/platform/tests/test-nmp-object.c +++ b/src/platform/tests/test-nmp-object.c @@ -22,7 +22,7 @@ #include "nmp-object.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" struct { GList *udev_devices; diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index a50392a6..360404e9 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -23,9 +23,9 @@ #include <linux/rtnetlink.h> #include "nm-core-utils.h" -#include "test-common.h" +#include "nm-platform-utils.h" -#include "nm-test-utils.h" +#include "test-common.h" #define DEVICE_NAME "nm-test-device" @@ -178,7 +178,7 @@ test_ip4_route (void) /* Test route listing */ routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_IP_CONFIG_SOURCE_USER; + rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; rts[0].plen = 32; rts[0].ifindex = ifindex; @@ -186,7 +186,7 @@ test_ip4_route (void) rts[0].metric = metric; rts[0].mss = mss; rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK); - rts[1].source = NM_IP_CONFIG_SOURCE_USER; + rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; @@ -194,7 +194,7 @@ test_ip4_route (void) rts[1].metric = metric; rts[1].mss = mss; rts[1].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE); - rts[2].source = NM_IP_CONFIG_SOURCE_USER; + rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[2].network = 0; rts[2].plen = 0; rts[2].ifindex = ifindex; @@ -265,21 +265,21 @@ test_ip6_route (void) /* Test route listing */ routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_IP_CONFIG_SOURCE_USER; + rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; rts[0].plen = 128; rts[0].ifindex = ifindex; rts[0].gateway = in6addr_any; rts[0].metric = nm_utils_ip6_route_metric_normalize (metric); rts[0].mss = mss; - rts[1].source = NM_IP_CONFIG_SOURCE_USER; + rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; rts[1].metric = nm_utils_ip6_route_metric_normalize (metric); rts[1].mss = mss; - rts[2].source = NM_IP_CONFIG_SOURCE_USER; + rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[2].network = in6addr_any; rts[2].plen = 0; rts[2].ifindex = ifindex; diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index 21a4c57b..ebe76f1b 100644 --- a/src/platform/wifi/wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -21,8 +21,6 @@ #ifndef __WIFI_UTILS_PRIVATE_H__ #define __WIFI_UTILS_PRIVATE_H__ - -#include "nm-default.h" #include "nm-dbus-interface.h" #include "wifi-utils.h" diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index 4f04041a..b7fe86bb 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -21,16 +21,18 @@ #include "nm-default.h" +#include "wifi-utils.h" + #include <sys/stat.h> #include <stdio.h> #include <string.h> -#include "wifi-utils.h" #include "wifi-utils-private.h" #include "wifi-utils-nl80211.h" #if HAVE_WEXT #include "wifi-utils-wext.h" #endif +#include "nm-core-utils.h" gpointer wifi_data_new (const char *iface, int ifindex, gsize len) @@ -178,19 +180,20 @@ wifi_utils_deinit (WifiData *data) } gboolean -wifi_utils_is_wifi (const char *iface, const char *sysfs_path) +wifi_utils_is_wifi (const char *iface) { - char phy80211_path[255]; + char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/]; struct stat s; g_return_val_if_fail (iface != NULL, FALSE); - if (sysfs_path) { - /* Check for nl80211 sysfs paths */ - g_snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path); - if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) - return TRUE; - } + nm_sprintf_buf (phy80211_path, + "/sys/class/net/%s/phy80211", + NM_ASSERT_VALID_PATH_COMPONENT (iface)); + nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1); + + if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + return TRUE; #if HAVE_WEXT if (wifi_wext_is_wifi (iface)) diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index 9555bbee..8e2b93f1 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -24,12 +24,11 @@ #include <net/ethernet.h> -#include "nm-default.h" #include "nm-dbus-interface.h" typedef struct WifiData WifiData; -gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path); +gboolean wifi_utils_is_wifi (const char *iface); WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); diff --git a/src/ppp-manager/Makefile.am b/src/ppp-manager/Makefile.am index 7d3e503b..3026dab4 100644 --- a/src/ppp-manager/Makefile.am +++ b/src/ppp-manager/Makefile.am @@ -22,6 +22,7 @@ nm_pppd_plugin_la_LDFLAGS = -module -avoid-version nm_pppd_plugin_la_LIBADD = \ $(GLIB_LIBS) \ - -ldl + $(DL_LIBS) \ + $(NULL) endif diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in index c80ae6bc..b8215aab 100644 --- a/src/ppp-manager/Makefile.in +++ b/src/ppp-manager/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/ppp-manager ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -140,7 +141,8 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@WITH_PPP_TRUE@ $(am__DEPENDENCIES_1) am__nm_pppd_plugin_la_SOURCES_DIST = nm-pppd-plugin.c nm-pppd-plugin.h \ nm-ppp-status.h @WITH_PPP_TRUE@am_nm_pppd_plugin_la_OBJECTS = nm-pppd-plugin.lo @@ -251,6 +253,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -307,13 +310,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -325,6 +329,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -385,6 +391,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -420,6 +428,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -501,7 +510,8 @@ with_valgrind = @with_valgrind@ @WITH_PPP_TRUE@nm_pppd_plugin_la_LDFLAGS = -module -avoid-version @WITH_PPP_TRUE@nm_pppd_plugin_la_LIBADD = \ @WITH_PPP_TRUE@ $(GLIB_LIBS) \ -@WITH_PPP_TRUE@ -ldl +@WITH_PPP_TRUE@ $(DL_LIBS) \ +@WITH_PPP_TRUE@ $(NULL) all: all-am diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 89a7addf..a51f7cfa 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -482,7 +482,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, address.plen = u32; if (address.address && address.plen && address.plen <= 32) { - address.source = NM_IP_CONFIG_SOURCE_PPP; + address.addr_source = NM_IP_CONFIG_SOURCE_PPP; nm_ip4_config_add_address (config, &address); } else { _LOGE ("invalid IPv4 address received!"); @@ -540,7 +540,7 @@ iid_value_to_ll6_addr (GVariant *dict, out_addr->s6_addr16[0] = htons (0xfe80); memcpy (out_addr->s6_addr + 8, &iid, sizeof (iid)); if (out_iid) - nm_utils_ipv6_interface_identfier_get_from_addr (out_iid, out_addr); + nm_utils_ipv6_interface_identifier_get_from_addr (out_iid, out_addr); return TRUE; } @@ -1028,7 +1028,7 @@ nm_ppp_manager_start (NMPPPManager *manager, NMPPPManagerPrivate *priv; NMConnection *connection; NMSettingPpp *s_ppp; - gboolean s_ppp_created = FALSE; + gs_unref_object NMSettingPpp *s_ppp_free = NULL; NMSettingPppoe *pppoe_setting; NMSettingAdsl *adsl_setting; NMCmdLine *ppp_cmd; @@ -1056,24 +1056,21 @@ nm_ppp_manager_start (NMPPPManager *manager, nm_utils_modprobe (NULL, FALSE, "ppp_generic", NULL); connection = nm_act_request_get_applied_connection (req); - g_assert (connection); + g_return_val_if_fail (connection, FALSE); s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { /* If the PPP settings are all default we may not have a PPP setting yet, * so just make a default one here. */ - s_ppp = NM_SETTING_PPP (nm_setting_ppp_new ()); - s_ppp_created = TRUE; + s_ppp = s_ppp_free = NM_SETTING_PPP (nm_setting_ppp_new ()); } - + pppoe_setting = nm_connection_get_setting_pppoe (connection); if (pppoe_setting) { /* We can't modify the applied connection's setting, make a copy */ - if (!s_ppp_created) { - s_ppp = NM_SETTING_PPP (nm_setting_duplicate ((NMSetting *) s_ppp)); - s_ppp_created = TRUE; - } + if (!s_ppp_free) + s_ppp = s_ppp_free = NM_SETTING_PPP (nm_setting_duplicate ((NMSetting *) s_ppp)); pppoe_fill_defaults (s_ppp); } @@ -1106,9 +1103,6 @@ nm_ppp_manager_start (NMPPPManager *manager, priv->act_req = g_object_ref (req); out: - if (s_ppp_created) - g_object_unref (s_ppp); - if (ppp_cmd) nm_cmd_line_destroy (ppp_cmd); diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c index 4c16f1f0..9c47c339 100644 --- a/src/ppp-manager/nm-pppd-plugin.c +++ b/src/ppp-manager/nm-pppd-plugin.c @@ -19,7 +19,7 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#include "config.h" +#include <config.h> #define ___CONFIG_H__ #include <string.h> diff --git a/src/rdisc/Makefile.in b/src/rdisc/Makefile.in index ebf72fb7..68fed001 100644 --- a/src/rdisc/Makefile.in +++ b/src/rdisc/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/rdisc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -225,6 +226,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -281,13 +283,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -299,6 +302,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -359,6 +364,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -394,6 +401,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c index 6a1585b3..46f2b08c 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/rdisc/nm-fake-rdisc.c @@ -233,15 +233,20 @@ receive_ra (gpointer user_data) NMFakeRDisc *self = user_data; NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); NMRDisc *rdisc = NM_RDISC (self); + NMRDiscDataInternal *rdata = rdisc->rdata; FakeRa *ra = priv->ras->data; NMRDiscConfigMap changed = 0; guint32 now = nm_utils_get_monotonic_timestamp_s (); guint i; + NMRDiscDHCPLevel dhcp_level; priv->receive_ra_id = 0; - if (rdisc->dhcp_level != ra->dhcp_level) { - rdisc->dhcp_level = ra->dhcp_level; + /* preserve the "most managed" level on updates. */ + dhcp_level = MAX (rdata->public.dhcp_level, ra->dhcp_level); + + if (rdata->public.dhcp_level != dhcp_level) { + rdata->public.dhcp_level = dhcp_level; changed |= NM_RDISC_CONFIG_DHCP_LEVEL; } @@ -263,6 +268,8 @@ receive_ra (gpointer user_data) .preference = item->preference, }; + g_assert (route.plen > 0 && route.plen <= 128); + if (nm_rdisc_add_route (rdisc, &route)) changed |= NM_RDISC_CONFIG_ROUTES; @@ -294,13 +301,13 @@ receive_ra (gpointer user_data) changed |= NM_RDISC_CONFIG_DNS_DOMAINS; } - if (rdisc->mtu != ra->mtu) { - rdisc->mtu = ra->mtu; + if (rdata->public.mtu != ra->mtu) { + rdata->public.mtu = ra->mtu; changed |= NM_RDISC_CONFIG_MTU; } - if (rdisc->hop_limit != ra->hop_limit) { - rdisc->hop_limit = ra->hop_limit; + if (rdata->public.hop_limit != ra->hop_limit) { + rdata->public.hop_limit = ra->hop_limit; changed |= NM_RDISC_CONFIG_HOP_LIMIT; } @@ -344,15 +351,10 @@ nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self) NMRDisc * nm_fake_rdisc_new (int ifindex, const char *ifname) { - NMRDisc *rdisc = g_object_new (NM_TYPE_FAKE_RDISC, NULL); - - rdisc->ifindex = ifindex; - rdisc->ifname = g_strdup (ifname); - rdisc->max_addresses = NM_RDISC_MAX_ADDRESSES_DEFAULT; - rdisc->rtr_solicitations = NM_RDISC_RTR_SOLICITATIONS_DEFAULT; - rdisc->rtr_solicitation_interval = NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT; - - return rdisc; + return g_object_new (NM_TYPE_FAKE_RDISC, + NM_RDISC_IFINDEX, ifindex, + NM_RDISC_IFNAME, ifname, + NULL); } static void @@ -385,10 +387,10 @@ nm_fake_rdisc_class_init (NMFakeRDiscClass *klass) 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); + 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-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index 0c5971f4..12c2e30d 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -20,39 +20,65 @@ #include "nm-default.h" +#include "nm-lndp-rdisc.h" + #include <string.h> #include <arpa/inet.h> /* stdarg.h included because of a bug in ndp.h */ #include <stdarg.h> #include <ndp.h> -#include "nm-lndp-rdisc.h" #include "nm-rdisc-private.h" - #include "NetworkManagerUtils.h" #include "nm-platform.h" #include "nmp-netns.h" #define _NMLOG_PREFIX_NAME "rdisc-lndp" +/*****************************************************************************/ + typedef struct { struct ndp *ndp; GIOChannel *event_channel; guint event_id; guint ra_timeout_id; /* first RA timeout */ -} NMLNDPRDiscPrivate; +} NMLndpRDiscPrivate; + +/*****************************************************************************/ -#define NM_LNDP_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LNDP_RDISC, NMLNDPRDiscPrivate)) +struct _NMLndpRDisc { + NMRDisc parent; + NMLndpRDiscPrivate _priv; +}; -G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) +struct _NMLndpRDiscClass { + NMRDiscClass parent; +}; -/******************************************************************/ +/*****************************************************************************/ + +G_DEFINE_TYPE (NMLndpRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) + +#define NM_LNDP_RDISC_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMLndpRDisc *_self2 = (_self); \ + \ + nm_assert (NM_IS_LNDP_RDISC (_self)); \ + &_self->_priv; \ + }) + +/*****************************************************************************/ static gboolean send_rs (NMRDisc *rdisc, GError **error) { - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); struct ndp_msg *msg; int errsv; @@ -63,7 +89,7 @@ send_rs (NMRDisc *rdisc, GError **error) "cannot create router solicitation"); return FALSE; } - ndp_msg_ifindex_set (msg, rdisc->ifindex); + ndp_msg_ifindex_set (msg, nm_rdisc_get_ifindex (rdisc)); errsv = ndp_msg_send (priv->ndp, msg); ndp_msg_destroy (msg); @@ -89,6 +115,7 @@ static int receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) { NMRDisc *rdisc = (NMRDisc *) user_data; + NMRDiscDataInternal *rdata = rdisc->rdata; NMRDiscConfigMap changed = 0; struct ndp_msgra *msgra = ndp_msgra (msg); struct in6_addr gateway_addr; @@ -125,8 +152,14 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) else dhcp_level = NM_RDISC_DHCP_LEVEL_NONE; - if (dhcp_level != rdisc->dhcp_level) { - rdisc->dhcp_level = dhcp_level; + /* when receiving multiple RA (possibly from different routers), + * let's keep the "most managed" level. */ + G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_MANAGED > NM_RDISC_DHCP_LEVEL_OTHERCONF); + G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_OTHERCONF > NM_RDISC_DHCP_LEVEL_NONE); + dhcp_level = MAX (dhcp_level, rdata->public.dhcp_level); + + if (dhcp_level != rdata->public.dhcp_level) { + rdata->public.dhcp_level = dhcp_level; changed |= NM_RDISC_CONFIG_DHCP_LEVEL; } } @@ -255,8 +288,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) } hop_limit = ndp_msgra_curhoplimit (msgra); - if (rdisc->hop_limit != hop_limit) { - rdisc->hop_limit = hop_limit; + if (rdata->public.hop_limit != hop_limit) { + rdata->public.hop_limit = hop_limit; changed |= NM_RDISC_CONFIG_HOP_LIMIT; } @@ -264,8 +297,10 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_MTU) { guint32 mtu = ndp_msg_opt_mtu(msg, offset); if (mtu >= 1280) { - rdisc->mtu = mtu; - changed |= NM_RDISC_CONFIG_MTU; + if (rdata->public.mtu != mtu) { + rdata->public.mtu = mtu; + changed |= NM_RDISC_CONFIG_MTU; + } } else { /* All sorts of bad things would happen if we accepted this. * Kernel would set it, but would flush out all IPv6 addresses away @@ -283,7 +318,7 @@ static gboolean event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); _LOGD ("processing libndp events"); @@ -297,7 +332,7 @@ event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) static void start (NMRDisc *rdisc) { - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); int fd = ndp_get_eventfd (priv->ndp); priv->event_channel = g_io_channel_unix_new (fd); @@ -306,28 +341,39 @@ start (NMRDisc *rdisc) /* 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); + ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc); } -/******************************************************************/ +/*****************************************************************************/ -static inline gint32 -ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, gint32 defval) +static inline int +ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval) +{ + return (int) nm_platform_sysctl_get_int_checked (platform, + nm_utils_ip6_property_path (ifname, property), + 10, + min, + max, + defval); +} + +static void +nm_lndp_rdisc_init (NMLndpRDisc *lndp_rdisc) { - return nm_platform_sysctl_get_int32 (platform, nm_utils_ip6_property_path (ifname, property), defval); } NMRDisc * nm_lndp_rdisc_new (NMPlatform *platform, int ifindex, const char *ifname, - const char *uuid, + NMUtilsStableType stable_type, + const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, GError **error) { nm_auto_pop_netns NMPNetns *netns = NULL; NMRDisc *rdisc; - NMLNDPRDiscPrivate *priv; + NMLndpRDiscPrivate *priv; int errsv; g_return_val_if_fail (NM_IS_PLATFORM (platform), NULL); @@ -338,21 +384,23 @@ nm_lndp_rdisc_new (NMPlatform *platform, rdisc = g_object_new (NM_TYPE_LNDP_RDISC, NM_RDISC_PLATFORM, platform, + NM_RDISC_STABLE_TYPE, (int) stable_type, + NM_RDISC_IFINDEX, ifindex, + NM_RDISC_IFNAME, ifname, + NM_RDISC_NETWORK_ID, network_id, + NM_RDISC_ADDR_GEN_MODE, (int) addr_gen_mode, + NM_RDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, + "max_addresses", + 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT), + NM_RDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname, + "router_solicitations", + 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT), + NM_RDISC_ROUTER_SOLICITATION_INTERVAL, ipv6_sysctl_get (platform, ifname, + "router_solicitation_interval", + 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT), NULL); - rdisc->ifindex = ifindex; - rdisc->ifname = g_strdup (ifname); - rdisc->uuid = g_strdup (uuid); - rdisc->addr_gen_mode = addr_gen_mode; - - rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses", - NM_RDISC_MAX_ADDRESSES_DEFAULT); - rdisc->rtr_solicitations = ipv6_sysctl_get (platform, ifname, "router_solicitations", - NM_RDISC_RTR_SOLICITATIONS_DEFAULT); - rdisc->rtr_solicitation_interval = ipv6_sysctl_get (platform, ifname, "router_solicitation_interval", - NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT); - - priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); errsv = ndp_open (&priv->ndp); @@ -368,21 +416,16 @@ nm_lndp_rdisc_new (NMPlatform *platform, } static void -nm_lndp_rdisc_init (NMLNDPRDisc *lndp_rdisc) -{ -} - -static void dispose (GObject *object) { - NMLNDPRDisc *rdisc = NM_LNDP_RDISC (object); - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + NMRDisc *rdisc = (NMRDisc *) object; + NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); nm_clear_g_source (&priv->event_id); 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_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc); ndp_close (priv->ndp); priv->ndp = NULL; } @@ -391,13 +434,11 @@ dispose (GObject *object) } static void -nm_lndp_rdisc_class_init (NMLNDPRDiscClass *klass) +nm_lndp_rdisc_class_init (NMLndpRDiscClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMRDiscClass *rdisc_class = NM_RDISC_CLASS (klass); - g_type_class_add_private (klass, sizeof (NMLNDPRDiscPrivate)); - object_class->dispose = dispose; rdisc_class->start = start; rdisc_class->send_rs = send_rs; diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h index 4c7c4743..e2b47c04 100644 --- a/src/rdisc/nm-lndp-rdisc.h +++ b/src/rdisc/nm-lndp-rdisc.h @@ -22,32 +22,25 @@ #define __NETWORKMANAGER_LNDP_RDISC_H__ #include "nm-rdisc.h" +#include "nm-core-utils.h" #define NM_TYPE_LNDP_RDISC (nm_lndp_rdisc_get_type ()) -#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDisc)) -#define NM_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_RDISC, NMLNDPRDiscClass)) +#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDisc)) +#define NM_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass)) #define NM_IS_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LNDP_RDISC)) #define NM_IS_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_LNDP_RDISC)) -#define NM_LNDP_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDiscClass)) +#define NM_LNDP_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass)) -/******************************************************************/ - -typedef struct { - NMRDisc parent; -} NMLNDPRDisc; - -typedef struct { - NMRDiscClass parent; -} NMLNDPRDiscClass; - -/******************************************************************/ +typedef struct _NMLndpRDisc NMLndpRDisc; +typedef struct _NMLndpRDiscClass NMLndpRDiscClass; GType nm_lndp_rdisc_get_type (void); NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform, int ifindex, const char *ifname, - const char *uuid, + NMUtilsStableType stable_type, + const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, GError **error); diff --git a/src/rdisc/nm-rdisc-private.h b/src/rdisc/nm-rdisc-private.h index c0ec739a..abc5a399 100644 --- a/src/rdisc/nm-rdisc-private.h +++ b/src/rdisc/nm-rdisc-private.h @@ -25,6 +25,17 @@ /* Functions only used by rdisc implementations */ +struct _NMRDiscDataInternal { + NMRDiscData public; + GArray *gateways; + GArray *addresses; + GArray *routes; + GArray *dns_servers; + GArray *dns_domains; +}; + +typedef struct _NMRDiscDataInternal NMRDiscDataInternal; + void nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed); gboolean nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new); @@ -44,19 +55,20 @@ gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDoma const NMLogDomain __domain = (domain); \ \ if (nm_logging_enabled (__level, __domain)) { \ + NMRDisc *const __self = (self); \ char __prefix[64]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const NMRDisc *const __self = (self); \ \ - if (__self) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p,%s%s%s]", \ - _NMLOG_PREFIX_NAME, __self, \ - NM_PRINT_FMT_QUOTE_STRING (__self->ifname)); \ - __p_prefix = __prefix; \ - } \ _nm_log (__level, __domain, 0, \ "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + (__self \ + ? ({ \ + const char *__ifname = nm_rdisc_get_ifname (__self); \ + nm_sprintf_buf (__prefix, "%s[%p,%s%s%s]", \ + _NMLOG_PREFIX_NAME, __self, \ + NM_PRINT_FMT_QUOTE_STRING (__ifname)); \ + }) \ + : _NMLOG_PREFIX_NAME) \ + _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ } \ } G_STMT_END diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index 12e3962b..cf993bc3 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -20,36 +20,61 @@ #include "nm-default.h" +#include "nm-rdisc.h" + #include <stdlib.h> #include <arpa/inet.h> #include <string.h> -#include "nm-rdisc.h" -#include "nm-rdisc-private.h" +#include "nm-setting-ip6-config.h" +#include "nm-rdisc-private.h" #include "nm-utils.h" #include "nm-platform.h" #include "nmp-netns.h" -#include <nm-setting-ip6-config.h> - #define _NMLOG_PREFIX_NAME "rdisc" -typedef struct { - int solicitations_left; +/*****************************************************************************/ + +struct _NMRDiscPrivate { + /* this *must* be the first field. */ + NMRDiscDataInternal rdata; + + gint32 solicitations_left; guint send_rs_id; - gint64 last_rs; + gint32 last_rs; guint ra_timeout_id; /* first RA timeout */ guint timeout_id; /* prefix/dns/etc lifetime timeout */ char *last_send_rs_error; -} NMRDiscPrivate; - -#define NM_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_RDISC, NMRDiscPrivate)) + NMUtilsIPv6IfaceId iid; + + /* immutable values: */ + int ifindex; + char *ifname; + char *network_id; + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + NMUtilsStableType stable_type; + gint32 max_addresses; + gint32 router_solicitations; + gint32 router_solicitation_interval; + + NMPlatform *platform; + NMPNetns *netns; +}; -G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT) +typedef struct _NMRDiscPrivate NMRDiscPrivate; NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_PLATFORM, + PROP_IFINDEX, + PROP_IFNAME, + PROP_STABLE_TYPE, + PROP_NETWORK_ID, + PROP_ADDR_GEN_MODE, + PROP_MAX_ADDRESSES, + PROP_ROUTER_SOLICITATIONS, + PROP_ROUTER_SOLICITATION_INTERVAL, ); enum { @@ -60,49 +85,120 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -/******************************************************************/ +G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT) + +#define NM_RDISC_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMRDisc *_self2 = (_self); \ + \ + nm_assert (NM_IS_RDISC (_self)); \ + _self->_priv; \ + }) + +/*****************************************************************************/ + +static void _config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed); + +/*****************************************************************************/ NMPNetns * nm_rdisc_netns_get (NMRDisc *self) { g_return_val_if_fail (NM_IS_RDISC (self), NULL); - return self->_netns; + return NM_RDISC_GET_PRIVATE (self)->netns; } gboolean nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns) { + NMRDiscPrivate *priv; + g_return_val_if_fail (NM_IS_RDISC (self), FALSE); - if ( self->_netns - && !nmp_netns_push (self->_netns)) { + priv = NM_RDISC_GET_PRIVATE (self); + if ( priv->netns + && !nmp_netns_push (priv->netns)) { NM_SET_OUT (netns, NULL); return FALSE; } - NM_SET_OUT (netns, self->_netns); + NM_SET_OUT (netns, priv->netns); return TRUE; } -/******************************************************************/ +/*****************************************************************************/ + +int +nm_rdisc_get_ifindex (NMRDisc *self) +{ + g_return_val_if_fail (NM_IS_RDISC (self), 0); + + return NM_RDISC_GET_PRIVATE (self)->ifindex; +} + +const char * +nm_rdisc_get_ifname (NMRDisc *self) +{ + g_return_val_if_fail (NM_IS_RDISC (self), NULL); + + return NM_RDISC_GET_PRIVATE (self)->ifname; +} + +/*****************************************************************************/ + +static const NMRDiscData * +_data_complete (NMRDiscDataInternal *data) +{ +#define _SET(data, field) \ + G_STMT_START { \ + if ((data->public.field##_n = data->field->len) > 0) \ + data->public.field = (gpointer) data->field->data; \ + else \ + data->public.field = NULL; \ + } G_STMT_END + _SET (data, gateways); + _SET (data, addresses); + _SET (data, routes); + _SET (data, dns_servers); + _SET (data, dns_domains); +#undef _SET + return &data->public; +} + +static void +_emit_config_change (NMRDisc *self, NMRDiscConfigMap changed) +{ + _config_changed_log (self, changed); + g_signal_emit (self, signals[CONFIG_CHANGED], 0, + _data_complete (&NM_RDISC_GET_PRIVATE (self)->rdata), + (guint) changed); +} + +/*****************************************************************************/ gboolean nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) { + NMRDiscDataInternal *rdata = &NM_RDISC_GET_PRIVATE(rdisc)->rdata; int i, insert_idx = -1; - for (i = 0; i < rdisc->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); + for (i = 0; i < rdata->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (rdata->gateways, NMRDiscGateway, i); if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { if (new->lifetime == 0) { - g_array_remove_index (rdisc->gateways, i--); + g_array_remove_index (rdata->gateways, i--); return TRUE; } if (item->preference != new->preference) { - g_array_remove_index (rdisc->gateways, i--); + g_array_remove_index (rdata->gateways, i--); continue; } @@ -116,7 +212,7 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) } if (new->lifetime) - g_array_insert_val (rdisc->gateways, MAX (insert_idx, 0), *new); + g_array_insert_val (rdata->gateways, MAX (insert_idx, 0), *new); return !!new->lifetime; } @@ -137,12 +233,17 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) static gboolean complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) { + NMRDiscPrivate *priv; GError *error = NULL; - if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { - if (!nm_utils_ipv6_addr_set_stable_privacy (&addr->address, - rdisc->ifname, - rdisc->uuid, + g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE); + + priv = NM_RDISC_GET_PRIVATE (rdisc); + if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { + if (!nm_utils_ipv6_addr_set_stable_privacy (priv->stable_type, + &addr->address, + priv->ifname, + priv->network_id, addr->dad_counter++, &error)) { _LOGW ("complete-address: failed to generate an stable-privacy address: %s", @@ -154,14 +255,14 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) return TRUE; } - if (!rdisc->iid.id) { + if (!priv->iid.id) { _LOGW ("complete-address: can't generate an EUI-64 address: no interface identifier"); return FALSE; } if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) { _LOGD ("complete-address: adding an EUI-64 address"); - nm_utils_ipv6_addr_set_interface_identfier (&addr->address, rdisc->iid); + nm_utils_ipv6_addr_set_interface_identifier (&addr->address, priv->iid); return TRUE; } @@ -172,19 +273,24 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) gboolean nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; int i; if (!complete_address (rdisc, new)) return FALSE; - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; + + for (i = 0; i < rdata->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdata->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--); + g_array_remove_index (rdata->addresses, i--); return TRUE; } @@ -199,33 +305,46 @@ nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new) * 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) + if (priv->max_addresses && rdata->addresses->len >= priv->max_addresses) return FALSE; if (new->lifetime) - g_array_insert_val (rdisc->addresses, i, *new); + g_array_insert_val (rdata->addresses, i, *new); return !!new->lifetime; } gboolean nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; int i, insert_idx = -1; - if (new->plen == 0 || new->plen > 128) - return FALSE; + if (new->plen == 0 || new->plen > 128) { + /* Only expect non-default routes. The router has no idea what the + * local configuration or user preferences are, so sending routes + * with a prefix length of 0 must be ignored by NMRDisc. + * + * Also, upper layers also don't expect that NMRDisc exposes routes + * with a plen or zero or larger then 128. + */ + g_return_val_if_reached (FALSE); + } + + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); + for (i = 0; i < rdata->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (rdata->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--); + g_array_remove_index (rdata->routes, i--); return TRUE; } if (item->preference != new->preference) { - g_array_remove_index (rdisc->routes, i--); + g_array_remove_index (rdata->routes, i--); continue; } @@ -239,21 +358,26 @@ nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new) } if (new->lifetime) - g_array_insert_val (rdisc->routes, CLAMP (insert_idx, 0, G_MAXINT), *new); + g_array_insert_val (rdata->routes, CLAMP (insert_idx, 0, G_MAXINT), *new); return !!new->lifetime; } gboolean nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; int i; - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; + + for (i = 0; i < rdata->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdata->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); + g_array_remove_index (rdata->dns_servers, i); return TRUE; } if (item->timestamp != new->timestamp || item->lifetime != new->lifetime) { @@ -265,7 +389,7 @@ nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) } if (new->lifetime) - g_array_insert_val (rdisc->dns_servers, i, *new); + g_array_insert_val (rdata->dns_servers, i, *new); return !!new->lifetime; } @@ -273,17 +397,22 @@ nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; NMRDiscDNSDomain *item; int i; - for (i = 0; i < rdisc->dns_domains->len; i++) { - item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; + + for (i = 0; i < rdata->dns_domains->len; i++) { + item = &g_array_index (rdata->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); + g_array_remove_index (rdata->dns_domains, i); return TRUE; } @@ -298,8 +427,8 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) } if (new->lifetime) { - g_array_insert_val (rdisc->dns_domains, i, *new); - item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + g_array_insert_val (rdata->dns_domains, i, *new); + item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); item->domain = g_strdup (new->domain); } return !!new->lifetime; @@ -329,18 +458,24 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; + g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE); - if (rdisc->iid.id != iid.id) { - rdisc->iid = iid; + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; - if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) + if (priv->iid.id != iid.id) { + priv->iid = iid; + + if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) return FALSE; - if (rdisc->addresses->len) { + if (rdata->addresses->len) { _LOGD ("IPv6 interface identifier changed, flushing addresses"); - g_array_remove_range (rdisc->addresses, 0, rdisc->addresses->len); - g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, NM_RDISC_CONFIG_ADDRESSES); + g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); + _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES); } return TRUE; } @@ -349,13 +484,15 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) } static gboolean -send_rs (NMRDisc *rdisc) +send_rs_timeout (NMRDisc *rdisc) { nm_auto_pop_netns NMPNetns *netns = NULL; NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); GError *error = NULL; + priv->send_rs_id = 0; + if (!nm_rdisc_netns_push (rdisc, &netns)) return G_SOURCE_REMOVE; @@ -379,13 +516,12 @@ send_rs (NMRDisc *rdisc) priv->last_rs = nm_utils_get_monotonic_timestamp_s (); if (priv->solicitations_left > 0) { _LOGD ("scheduling router solicitation retry in %d seconds.", - rdisc->rtr_solicitation_interval); - priv->send_rs_id = g_timeout_add_seconds (rdisc->rtr_solicitation_interval, - (GSourceFunc) send_rs, rdisc); + (int) priv->router_solicitation_interval); + priv->send_rs_id = g_timeout_add_seconds (priv->router_solicitation_interval, + (GSourceFunc) send_rs_timeout, rdisc); } else { _LOGD ("did not receive a router advertisement after %d solicitations.", - rdisc->rtr_solicitations); - priv->send_rs_id = 0; + (int) priv->router_solicitations); } return G_SOURCE_REMOVE; @@ -395,17 +531,20 @@ static void solicit (NMRDisc *rdisc) { NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); - guint32 now = nm_utils_get_monotonic_timestamp_s (); - gint64 next; + gint64 next, now; + + if (priv->send_rs_id) + return; - if (!priv->send_rs_id) { - priv->solicitations_left = rdisc->rtr_solicitations; + now = nm_utils_get_monotonic_timestamp_s (); - next = CLAMP (priv->last_rs + rdisc->rtr_solicitation_interval - now, 0, G_MAXINT32); - _LOGD ("scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.", - next); - priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs, rdisc); - } + priv->solicitations_left = priv->router_solicitations; + + next = (((gint64) priv->last_rs) + priv->router_solicitation_interval) - now; + next = CLAMP (next, 0, G_MAXINT32); + _LOGD ("scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.", + next); + priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, rdisc); } static gboolean @@ -414,7 +553,7 @@ 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); + g_signal_emit (rdisc, signals[RA_TIMEOUT], 0); return G_SOURCE_REMOVE; } @@ -424,19 +563,20 @@ nm_rdisc_start (NMRDisc *rdisc) nm_auto_pop_netns NMPNetns *netns = NULL; NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); - guint ra_wait_secs; + gint64 ra_wait_secs; g_assert (klass->start); - _LOGD ("starting router discovery: %d", rdisc->ifindex); + _LOGD ("starting router discovery: %d", priv->ifindex); if (!nm_rdisc_netns_push (rdisc, &netns)) return; nm_clear_g_source (&priv->ra_timeout_id); - ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120); + ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; + ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc); - _LOGD ("scheduling RA timeout in %d seconds", ra_wait_secs); + _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); if (klass->start) klass->start (rdisc); @@ -447,23 +587,26 @@ nm_rdisc_start (NMRDisc *rdisc) void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address) { + NMRDiscDataInternal *rdata; int i; gboolean changed = FALSE; - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + + for (i = 0; i < rdata->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i); if (!IN6_ARE_ADDR_EQUAL (&item->address, address)) continue; _LOGD ("DAD failed for discovered address %s", nm_utils_inet6_ntop (address, NULL)); if (!complete_address (rdisc, item)) - g_array_remove_index (rdisc->addresses, i--); + g_array_remove_index (rdata->addresses, i--); changed = TRUE; } if (changed) - g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, NM_RDISC_CONFIG_ADDRESSES); + _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES); } #define CONFIG_MAP_MAX_STR 7 @@ -504,64 +647,73 @@ dhcp_level_to_string (NMRDiscDHCPLevel dhcp_level) #define expiry(item) (item->timestamp + item->lifetime) static void -config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed) +_config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed) { + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; int i; char changedstr[CONFIG_MAP_MAX_STR]; char addrstr[INET6_ADDRSTRLEN]; - if (_LOGD_ENABLED ()) { - config_map_to_string (changed, changedstr); - _LOGD ("router discovery configuration changed [%s]:", changedstr); - _LOGD (" dhcp-level %s", dhcp_level_to_string (rdisc->dhcp_level)); - for (i = 0; i < rdisc->gateways->len; i++) { - NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, i); + if (!_LOGD_ENABLED ()) + return; - inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr)); - _LOGD (" gateway %s pref %d exp %u", addrstr, gateway->preference, expiry (gateway)); - } - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *address = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + priv = NM_RDISC_GET_PRIVATE (rdisc); + rdata = &priv->rdata; - inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr)); - _LOGD (" address %s exp %u", addrstr, expiry (address)); - } - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *route = &g_array_index (rdisc->routes, NMRDiscRoute, i); + config_map_to_string (changed, changedstr); + _LOGD ("router discovery configuration changed [%s]:", changedstr); + _LOGD (" dhcp-level %s", dhcp_level_to_string (priv->rdata.public.dhcp_level)); + for (i = 0; i < rdata->gateways->len; i++) { + NMRDiscGateway *gateway = &g_array_index (rdata->gateways, NMRDiscGateway, i); - inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr)); - _LOGD (" route %s/%d via %s pref %d exp %u", addrstr, route->plen, - nm_utils_inet6_ntop (&route->gateway, NULL), route->preference, - expiry (route)); - } - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *dns_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr)); + _LOGD (" gateway %s pref %d exp %u", addrstr, gateway->preference, expiry (gateway)); + } + for (i = 0; i < rdata->addresses->len; i++) { + NMRDiscAddress *address = &g_array_index (rdata->addresses, NMRDiscAddress, i); - inet_ntop (AF_INET6, &dns_server->address, addrstr, sizeof (addrstr)); - _LOGD (" dns_server %s exp %u", addrstr, expiry (dns_server)); - } - for (i = 0; i < rdisc->dns_domains->len; i++) { - NMRDiscDNSDomain *dns_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr)); + _LOGD (" address %s exp %u", addrstr, expiry (address)); + } + for (i = 0; i < rdata->routes->len; i++) { + NMRDiscRoute *route = &g_array_index (rdata->routes, NMRDiscRoute, i); - _LOGD (" dns_domain %s exp %u", dns_domain->domain, expiry (dns_domain)); - } + inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr)); + _LOGD (" route %s/%d via %s pref %d exp %u", addrstr, (int) route->plen, + nm_utils_inet6_ntop (&route->gateway, NULL), route->preference, + expiry (route)); + } + for (i = 0; i < rdata->dns_servers->len; i++) { + NMRDiscDNSServer *dns_server = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i); + + inet_ntop (AF_INET6, &dns_server->address, addrstr, sizeof (addrstr)); + _LOGD (" dns_server %s exp %u", addrstr, expiry (dns_server)); + } + for (i = 0; i < rdata->dns_domains->len; i++) { + NMRDiscDNSDomain *dns_domain = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); + + _LOGD (" dns_domain %s exp %u", dns_domain->domain, expiry (dns_domain)); } } static void clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) { - int i; + NMRDiscDataInternal *rdata; + guint i; + + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; - for (i = 0; i < rdisc->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); + for (i = 0; i < rdata->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (rdata->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--); + g_array_remove_index (rdata->gateways, i--); *changed |= NM_RDISC_CONFIG_GATEWAYS; } else if (*nextevent > expiry) *nextevent = expiry; @@ -571,17 +723,20 @@ clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 static void clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) { - int i; + NMRDiscDataInternal *rdata; + guint i; + + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + for (i = 0; i < rdata->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdata->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--); + g_array_remove_index (rdata->addresses, i--); *changed |= NM_RDISC_CONFIG_ADDRESSES; } else if (*nextevent > expiry) *nextevent = expiry; @@ -591,17 +746,20 @@ clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 static void clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) { - int i; + NMRDiscDataInternal *rdata; + guint i; + + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); + for (i = 0; i < rdata->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (rdata->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--); + g_array_remove_index (rdata->routes, i--); *changed |= NM_RDISC_CONFIG_ROUTES; } else if (*nextevent > expiry) *nextevent = expiry; @@ -611,10 +769,13 @@ clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *n static void clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) { - int i; + NMRDiscDataInternal *rdata; + guint i; - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + + for (i = 0; i < rdata->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; @@ -622,7 +783,7 @@ clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint continue; if (now >= expiry) { - g_array_remove_index (rdisc->dns_servers, i--); + g_array_remove_index (rdata->dns_servers, i--); *changed |= NM_RDISC_CONFIG_DNS_SERVERS; } else if (now >= refresh) solicit (rdisc); @@ -634,10 +795,13 @@ clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint static void clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) { - int i; + NMRDiscDataInternal *rdata; + guint i; + + rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; - for (i = 0; i < rdisc->dns_domains->len; i++) { - NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + for (i = 0; i < rdata->dns_domains->len; i++) { + NMRDiscDNSDomain *item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; @@ -645,7 +809,7 @@ clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint continue; if (now >= expiry) { - g_array_remove_index (rdisc->dns_domains, i--); + g_array_remove_index (rdata->dns_domains, i--); *changed |= NM_RDISC_CONFIG_DNS_DOMAINS; } else if (now >= refresh) solicit (rdisc); @@ -673,7 +837,7 @@ check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) clean_dns_domains (rdisc, now, &changed, &nextevent); if (changed) - g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, changed); + _emit_config_change (rdisc, changed); if (nextevent != never) { g_return_if_fail (nextevent > now); @@ -686,8 +850,10 @@ check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) 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); + NMRDisc *self = user_data; + + NM_RDISC_GET_PRIVATE (self)->timeout_id = 0; + check_timestamps (self, nm_utils_get_monotonic_timestamp_s (), 0); return G_SOURCE_REMOVE; } @@ -715,21 +881,56 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMRDisc *self = NM_RDISC (object); + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (self); switch (prop_id) { case PROP_PLATFORM: /* construct-only */ - self->_platform = g_value_get_object (value) ? : NM_PLATFORM_GET; - if (!self->_platform) + priv->platform = g_value_get_object (value) ? : NM_PLATFORM_GET; + if (!priv->platform) g_return_if_reached (); - g_object_ref (self->_platform); + g_object_ref (priv->platform); - self->_netns = nm_platform_netns_get (self->_platform); - if (self->_netns) - g_object_ref (self->_netns); + priv->netns = nm_platform_netns_get (priv->platform); + if (priv->netns) + g_object_ref (priv->netns); - g_return_if_fail (!self->_netns || self->_netns == nmp_netns_get_current ()); + g_return_if_fail (!priv->netns || priv->netns == nmp_netns_get_current ()); + break; + case PROP_IFINDEX: + /* construct-only */ + priv->ifindex = g_value_get_int (value); + g_return_if_fail (priv->ifindex > 0); + break; + case PROP_IFNAME: + /* construct-only */ + priv->ifname = g_value_dup_string (value); + g_return_if_fail (priv->ifname && priv->ifname[0]); + break; + case PROP_STABLE_TYPE: + /* construct-only */ + priv->stable_type = g_value_get_int (value); + break; + case PROP_NETWORK_ID: + /* construct-only */ + priv->network_id = g_value_dup_string (value); + break; + case PROP_ADDR_GEN_MODE: + /* construct-only */ + priv->addr_gen_mode = g_value_get_int (value); + break; + case PROP_MAX_ADDRESSES: + /* construct-only */ + priv->max_addresses = g_value_get_int (value); + break; + case PROP_ROUTER_SOLICITATIONS: + /* construct-only */ + priv->router_solicitations = g_value_get_int (value); + break; + case PROP_ROUTER_SOLICITATION_INTERVAL: + /* construct-only */ + priv->router_solicitation_interval = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -740,17 +941,23 @@ set_property (GObject *object, guint prop_id, static void nm_rdisc_init (NMRDisc *rdisc) { - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMRDiscPrivate *priv; + NMRDiscDataInternal *rdata; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (rdisc, NM_TYPE_RDISC, NMRDiscPrivate); + rdisc->_priv = priv; - 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; + rdata = &priv->rdata; - /* Start at very low number so that last_rs - rtr_solicitation_interval + rdata->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway)); + rdata->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress)); + rdata->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute)); + rdata->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); + rdata->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); + g_array_set_clear_func (rdata->dns_domains, dns_domain_free); + priv->rdata.public.hop_limit = 64; + + /* Start at very low number so that last_rs - router_solicitation_interval * is much lower than nm_utils_get_monotonic_timestamp_s() at startup. */ priv->last_rs = G_MININT32; @@ -775,17 +982,20 @@ static void finalize (GObject *object) { NMRDisc *rdisc = NM_RDISC (object); + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMRDiscDataInternal *rdata = &priv->rdata; + + g_free (priv->ifname); + g_free (priv->network_id); - g_free (rdisc->ifname); - g_free (rdisc->uuid); - g_array_unref (rdisc->gateways); - g_array_unref (rdisc->addresses); - g_array_unref (rdisc->routes); - g_array_unref (rdisc->dns_servers); - g_array_unref (rdisc->dns_domains); + g_array_unref (rdata->gateways); + g_array_unref (rdata->addresses); + g_array_unref (rdata->routes); + g_array_unref (rdata->dns_servers); + g_array_unref (rdata->dns_domains); - g_clear_object (&rdisc->_netns); - g_clear_object (&rdisc->_platform); + g_clear_object (&priv->netns); + g_clear_object (&priv->platform); G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object); } @@ -800,7 +1010,6 @@ nm_rdisc_class_init (NMRDiscClass *klass) object_class->set_property = set_property; object_class->dispose = dispose; object_class->finalize = finalize; - klass->config_changed = config_changed; obj_properties[PROP_PLATFORM] = g_param_spec_object (NM_RDISC_PLATFORM, "", "", @@ -808,20 +1017,68 @@ nm_rdisc_class_init (NMRDiscClass *klass) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IFINDEX] = + g_param_spec_int (NM_RDISC_IFINDEX, "", "", + 0, G_MAXINT, 0, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IFNAME] = + g_param_spec_string (NM_RDISC_IFNAME, "", "", + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_STABLE_TYPE] = + g_param_spec_int (NM_RDISC_STABLE_TYPE, "", "", + NM_UTILS_STABLE_TYPE_UUID, NM_UTILS_STABLE_TYPE_STABLE_ID, NM_UTILS_STABLE_TYPE_UUID, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_NETWORK_ID] = + g_param_spec_string (NM_RDISC_NETWORK_ID, "", "", + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ADDR_GEN_MODE] = + g_param_spec_int (NM_RDISC_ADDR_GEN_MODE, "", "", + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_MAX_ADDRESSES] = + g_param_spec_int (NM_RDISC_MAX_ADDRESSES, "", "", + 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTER_SOLICITATIONS] = + g_param_spec_int (NM_RDISC_ROUTER_SOLICITATIONS, "", "", + 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTER_SOLICITATION_INTERVAL] = + g_param_spec_int (NM_RDISC_ROUTER_SOLICITATION_INTERVAL, "", "", + 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[CONFIG_CHANGED] = g_signal_new (NM_RDISC_CONFIG_CHANGED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMRDiscClass, config_changed), + 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_INT); + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); signals[RA_TIMEOUT] = g_signal_new (NM_RDISC_RA_TIMEOUT, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMRDiscClass, ra_timeout), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); } diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index 5b97bec5..9e5e9349 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -35,6 +35,15 @@ #define NM_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass)) #define NM_RDISC_PLATFORM "platform" +#define NM_RDISC_IFINDEX "ifindex" +#define NM_RDISC_IFNAME "ifname" +#define NM_RDISC_NETWORK_ID "network-id" +#define NM_RDISC_ADDR_GEN_MODE "addr-gen-mode" +#define NM_RDISC_STABLE_TYPE "stable-type" +#define NM_RDISC_MAX_ADDRESSES "max-addresses" +#define NM_RDISC_ROUTER_SOLICITATIONS "router-solicitations" +#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" + #define NM_RDISC_CONFIG_CHANGED "config-changed" #define NM_RDISC_RA_TIMEOUT "ra-timeout" @@ -69,7 +78,7 @@ typedef struct { typedef struct { struct in6_addr network; - int plen; + guint8 plen; struct in6_addr gateway; guint32 timestamp; guint32 lifetime; @@ -100,39 +109,42 @@ typedef enum { } NMRDiscConfigMap; #define NM_RDISC_MAX_ADDRESSES_DEFAULT 16 -#define NM_RDISC_RTR_SOLICITATIONS_DEFAULT 3 -#define NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT 4 +#define NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT 3 +#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 + +struct _NMRDiscPrivate; +struct _NMRDiscDataInternal; + +typedef struct { + NMRDiscDHCPLevel dhcp_level; + guint32 mtu; + int hop_limit; + + guint gateways_n; + guint addresses_n; + guint routes_n; + guint dns_servers_n; + guint dns_domains_n; + + const NMRDiscGateway *gateways; + const NMRDiscAddress *addresses; + const NMRDiscRoute *routes; + const NMRDiscDNSServer *dns_servers; + const NMRDiscDNSDomain *dns_domains; +} NMRDiscData; /** * NMRDisc: - * @ifindex: Interface index * * Interface-specific structure that handles incoming router advertisements, * caches advertised items and removes them when they are obsolete. */ typedef struct { GObject parent; - - NMPlatform *_platform; - NMPNetns *_netns; - - int ifindex; - char *ifname; - char *uuid; - NMSettingIP6ConfigAddrGenMode addr_gen_mode; - NMUtilsIPv6IfaceId iid; - gint32 max_addresses; - gint32 rtr_solicitations; - gint32 rtr_solicitation_interval; - - NMRDiscDHCPLevel dhcp_level; - GArray *gateways; - GArray *addresses; - GArray *routes; - GArray *dns_servers; - GArray *dns_domains; - int hop_limit; - guint32 mtu; + union { + struct _NMRDiscPrivate *_priv; + struct _NMRDiscDataInternal *rdata; + }; } NMRDisc; typedef struct { @@ -140,13 +152,13 @@ typedef struct { void (*start) (NMRDisc *rdisc); gboolean (*send_rs) (NMRDisc *rdisc, GError **error); - void (*config_changed) (NMRDisc *rdisc, NMRDiscConfigMap changed); - void (*ra_process) (NMRDisc *rdisc); - void (*ra_timeout) (NMRDisc *rdisc); } NMRDiscClass; GType nm_rdisc_get_type (void); +int nm_rdisc_get_ifindex (NMRDisc *self); +const char *nm_rdisc_get_ifname (NMRDisc *self); + gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid); void nm_rdisc_start (NMRDisc *rdisc); void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address); diff --git a/src/rdisc/tests/Makefile.am b/src/rdisc/tests/Makefile.am index 65191734..b054179e 100644 --- a/src/rdisc/tests/Makefile.am +++ b/src/rdisc/tests/Makefile.am @@ -29,7 +29,7 @@ test_rdisc_linux_LDADD = \ test_rdisc_fake_SOURCES = \ test-rdisc-fake.c test_rdisc_fake_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @VALGRIND_RULES@ TESTS = test-rdisc-fake diff --git a/src/rdisc/tests/Makefile.in b/src/rdisc/tests/Makefile.in index 895d7063..f160600e 100644 --- a/src/rdisc/tests/Makefile.in +++ b/src/rdisc/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-rdisc-linux$(EXEEXT) test-rdisc-fake$(EXEEXT) TESTS = test-rdisc-fake$(EXEEXT) subdir = src/rdisc/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -116,7 +117,7 @@ PROGRAMS = $(noinst_PROGRAMS) 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 + $(top_builddir)/src/libNetworkManagerTest.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -426,6 +427,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -482,13 +484,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -500,6 +503,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -560,6 +565,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -595,6 +602,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -685,7 +693,7 @@ test_rdisc_fake_SOURCES = \ test-rdisc-fake.c test_rdisc_fake_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la all: all-am diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/rdisc/tests/test-rdisc-fake.c index 1c514b90..02ffb510 100644 --- a/src/rdisc/tests/test-rdisc-fake.c +++ b/src/rdisc/tests/test-rdisc-fake.c @@ -28,7 +28,7 @@ #include "nm-fake-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static NMFakeRDisc * rdisc_new (void) @@ -46,11 +46,17 @@ rdisc_new (void) } static void -match_gateway (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref) +match_gateway (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref) { - NMRDiscGateway *gw = &g_array_index (array, NMRDiscGateway, idx); + const NMRDiscGateway *gw; char buf[INET6_ADDRSTRLEN]; + g_assert (rdata); + g_assert_cmpint (idx, <, rdata->gateways_n); + g_assert (rdata->gateways); + + gw = &rdata->gateways[idx]; + 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); @@ -58,11 +64,17 @@ match_gateway (GArray *array, guint idx, const char *addr, guint32 ts, guint32 l } static void -match_address (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred) +match_address (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred) { - NMRDiscAddress *a = &g_array_index (array, NMRDiscAddress, idx); + const NMRDiscAddress *a; char buf[INET6_ADDRSTRLEN]; + g_assert (rdata); + g_assert_cmpint (idx, <, rdata->addresses_n); + g_assert (rdata->addresses); + + a = &rdata->addresses[idx]; + 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); @@ -70,13 +82,20 @@ match_address (GArray *array, guint idx, const char *addr, guint32 ts, guint32 l } static void -match_route (GArray *array, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref) +match_route (const NMRDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref) { - NMRDiscRoute *route = &g_array_index (array, NMRDiscRoute, idx); + const NMRDiscRoute *route; char buf[INET6_ADDRSTRLEN]; + g_assert (rdata); + g_assert_cmpint (idx, <, rdata->routes_n); + g_assert (rdata->routes); + g_assert (plen > 0 && plen <= 128); + + route = &rdata->routes[idx]; + g_assert_cmpstr (inet_ntop (AF_INET6, &route->network, buf, sizeof (buf)), ==, nw); - g_assert_cmpint (route->plen, ==, plen); + g_assert_cmpint ((int) 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); @@ -84,20 +103,32 @@ match_route (GArray *array, guint idx, const char *nw, int plen, const char *gw, } static void -match_dns_server (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt) +match_dns_server (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt) { - NMRDiscDNSServer *dns = &g_array_index (array, NMRDiscDNSServer, idx); + const NMRDiscDNSServer *dns; char buf[INET6_ADDRSTRLEN]; + g_assert (rdata); + g_assert_cmpint (idx, <, rdata->dns_servers_n); + g_assert (rdata->dns_servers); + + dns = &rdata->dns_servers[idx]; + 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) +match_dns_domain (const NMRDiscData *rdata, guint idx, const char *domain, guint32 ts, guint32 lt) { - NMRDiscDNSDomain *dns = &g_array_index (array, NMRDiscDNSDomain, idx); + const NMRDiscDNSDomain *dns; + + g_assert (rdata); + g_assert_cmpint (idx, <, rdata->dns_domains_n); + g_assert (rdata->dns_domains); + + dns = &rdata->dns_domains[idx]; g_assert_cmpstr (dns->domain, ==, domain); g_assert_cmpint (dns->timestamp, ==, ts); @@ -114,8 +145,10 @@ typedef struct { } TestData; static void -test_simple_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +test_simple_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) { + NMRDiscConfigMap changed = changed_int; + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL | NM_RDISC_CONFIG_GATEWAYS | NM_RDISC_CONFIG_ADDRESSES | @@ -124,12 +157,12 @@ test_simple_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) 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_cmpint (rdata->dhcp_level, ==, NM_RDISC_DHCP_LEVEL_OTHERCONF); + match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); + match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10); + match_dns_domain (rdata, 0, "foobar.com", data->timestamp1, 10); g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); data->counter++; @@ -172,40 +205,42 @@ test_everything_rs_sent (NMRDisc *rdisc, TestData *data) } static void -test_everything_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +test_everything_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) { + NMRDiscConfigMap changed = changed_int; + 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); + 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 (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); + match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10); + match_dns_domain (rdata, 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:b::1", 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); + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES | + NM_RDISC_CONFIG_DNS_SERVERS | + NM_RDISC_CONFIG_DNS_DOMAINS); + + g_assert_cmpint (rdata->gateways_n, ==, 1); + match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (rdata->addresses_n, ==, 1); + match_address (rdata, 0, "2001:db8:a:b::1", data->timestamp1, 10, 10); + g_assert_cmpint (rdata->routes_n, ==, 1); + match_route (rdata, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1, 10, 10); + g_assert_cmpint (rdata->dns_servers_n, ==, 1); + match_dns_server (rdata, 0, "2001:db8:c:c::2", data->timestamp1, 10); + g_assert_cmpint (rdata->dns_domains_n, ==, 1); + match_dns_domain (rdata, 0, "foobar2.com", data->timestamp1, 10); g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); g_main_loop_quit (data->loop); @@ -263,35 +298,37 @@ test_everything (void) } static void -test_preference_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) { + NMRDiscConfigMap changed = changed_int; + 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:b::1", 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); + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES); + g_assert_cmpint (rdata->gateways_n, ==, 2); + match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_LOW); + g_assert_cmpint (rdata->addresses_n, ==, 2); + match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10); + g_assert_cmpint (rdata->routes_n, ==, 2); + match_route (rdata, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10); + match_route (rdata, 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:b::1", 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); + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES); + + g_assert_cmpint (rdata->gateways_n, ==, 2); + match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_RDISC_PREFERENCE_HIGH); + match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (rdata->addresses_n, ==, 2); + match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1 + 2, 10, 10); + match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10); + g_assert_cmpint (rdata->routes_n, ==, 2); + match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1 + 2, 10, 15); + match_route (rdata, 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); @@ -342,7 +379,7 @@ test_preference (void) } static void -test_dns_solicit_loop_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +test_dns_solicit_loop_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) { data->counter++; } diff --git a/src/rdisc/tests/test-rdisc-linux.c b/src/rdisc/tests/test-rdisc-linux.c index e22eb1ad..299abf3e 100644 --- a/src/rdisc/tests/test-rdisc-linux.c +++ b/src/rdisc/tests/test-rdisc-linux.c @@ -28,7 +28,7 @@ #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" NMTST_DEFINE (); @@ -64,6 +64,7 @@ main (int argc, char **argv) rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, ifname, + NM_UTILS_STABLE_TYPE_UUID, "8ce666e8-d34d-4fb1-b858-f15a7al28086", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, &error); diff --git a/src/settings/nm-inotify-helper.h b/src/settings/nm-inotify-helper.h index b4e2c612..2ac9376c 100644 --- a/src/settings/nm-inotify-helper.h +++ b/src/settings/nm-inotify-helper.h @@ -23,8 +23,6 @@ #include <sys/inotify.h> -#include "nm-default.h" - /* NOTE: this code should be killed once we depend on a new enough glib to * include the patches from https://bugzilla.gnome.org/show_bug.cgi?id=532815 */ diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h index 333aa461..916623a7 100644 --- a/src/settings/nm-secret-agent.h +++ b/src/settings/nm-secret-agent.h @@ -22,7 +22,6 @@ #define __NETWORKMANAGER_SECRET_AGENT_H__ #include <nm-connection.h> -#include "nm-default.h" #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 5b3a3999..f22807d3 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -93,7 +93,7 @@ typedef struct { NMAgentManager *agent_mgr; NMSessionMonitor *session_monitor; - guint session_changed_id; + gulong session_changed_id; NMSettingsConnectionFlags flags; gboolean ready; @@ -1529,6 +1529,7 @@ typedef struct { NMAuthSubject *subject; NMConnection *new_settings; gboolean save_to_disk; + char *audit_args; } UpdateInfo; typedef struct { @@ -1600,12 +1601,13 @@ update_complete (NMSettingsConnection *self, else g_dbus_method_invocation_return_value (info->context, NULL); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, info->audit_args, info->subject, error ? error->message : NULL); g_clear_object (&info->subject); g_clear_object (&info->agent_mgr); g_clear_object (&info->new_settings); + g_free (info->audit_args); memset (info, 0, sizeof (*info)); g_free (info); } @@ -1637,6 +1639,49 @@ con_update_cb (NMSettingsConnection *self, update_complete (self, info, error); } +static char * +con_list_changed_props (NMConnection *old, NMConnection *new) +{ + gs_unref_hashtable GHashTable *diff = NULL; + GHashTable *setting_diff; + char *setting_name, *prop_name; + GHashTableIter iter, iter2; + gboolean same; + GString *str; + + same = nm_connection_diff (old, new, + NM_SETTING_COMPARE_FLAG_EXACT | + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, + &diff); + + if (same || !diff) + return NULL; + + str = g_string_sized_new (32); + g_hash_table_iter_init (&iter, diff); + + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_diff)) { + if (!setting_diff) + continue; + + g_hash_table_iter_init (&iter2, setting_diff); + + while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL)) { + g_string_append (str, setting_name); + g_string_append_c (str, '.'); + g_string_append (str, prop_name); + g_string_append_c (str, ','); + } + } + + if (str->len) + str->str[str->len - 1] = '\0'; + + return g_string_free (str, FALSE); +} + static void update_auth_cb (NMSettingsConnection *self, GDBusMethodInvocation *context, @@ -1666,6 +1711,9 @@ update_auth_cb (NMSettingsConnection *self, update_agent_secrets_cache (self, info->new_settings); } + if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) + info->audit_args = con_list_changed_props (NM_CONNECTION (self), info->new_settings); + if (info->save_to_disk) { nm_settings_connection_replace_and_commit (self, info->new_settings, @@ -1769,7 +1817,7 @@ settings_connection_update_helper (NMSettingsConnection *self, return; error: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, subject, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, NULL, subject, error->message); g_clear_object (&tmp); @@ -1818,7 +1866,7 @@ con_delete_cb (NMSettingsConnection *self, g_dbus_method_invocation_return_value (info->context, NULL); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, - !error, info->subject, error ? error->message : NULL); + !error, NULL, info->subject, error ? error->message : NULL); g_free (info); } @@ -1832,7 +1880,7 @@ delete_auth_cb (NMSettingsConnection *self, CallbackInfo *info; if (error) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); g_dbus_method_invocation_return_gerror (context, error); return; @@ -1881,7 +1929,7 @@ impl_settings_connection_delete (NMSettingsConnection *self, return; out_err: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject, error->message); + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); g_dbus_method_invocation_take_error (context, error); } @@ -1974,7 +2022,7 @@ clear_secrets_cb (NMSettingsConnection *self, g_dbus_method_invocation_return_value (info->context, NULL); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - !error, info->subject, error ? error->message : NULL); + !error, NULL, info->subject, error ? error->message : NULL); g_free (info); } @@ -1991,7 +2039,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, if (error) { g_dbus_method_invocation_return_gerror (context, error); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - FALSE, subject, error->message); + FALSE, NULL, subject, error->message); } else { /* Clear secrets in connection and caches */ nm_connection_clear_secrets (NM_CONNECTION (self)); @@ -2031,7 +2079,7 @@ impl_settings_connection_clear_secrets (NMSettingsConnection *self, g_object_unref (subject); } else { nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - FALSE, NULL, error->message); + FALSE, NULL, NULL, error->message); g_dbus_method_invocation_take_error (context, error); } } @@ -2567,7 +2615,9 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->ready = TRUE; priv->session_monitor = g_object_ref (nm_session_monitor_get ()); - priv->session_changed_id = nm_session_monitor_connect (priv->session_monitor, session_changed_cb, self); + priv->session_changed_id = g_signal_connect (priv->session_monitor, + NM_SESSION_MONITOR_CHANGED, + G_CALLBACK (session_changed_cb), self); priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); @@ -2627,11 +2677,9 @@ dispose (GObject *object) set_visible (self, FALSE); - if (priv->session_monitor) { - nm_session_monitor_disconnect (priv->session_monitor, priv->session_changed_id); - priv->session_changed_id = 0; - g_clear_object (&priv->session_monitor); - } + nm_clear_g_signal_handler (priv->session_monitor, &priv->session_changed_id); + g_clear_object (&priv->session_monitor); + g_clear_object (&priv->agent_mgr); g_clear_pointer (&priv->filename, g_free); diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index c45505d9..761203ea 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -26,9 +26,6 @@ #include "nm-exported-object.h" #include <nm-connection.h> -#include "nm-default.h" - -G_BEGIN_DECLS #define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) #define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection)) @@ -230,6 +227,4 @@ const char *nm_settings_connection_get_filename (NMSettingsConnection *self); const char *nm_settings_connection_get_id (NMSettingsConnection *connection); const char *nm_settings_connection_get_uuid (NMSettingsConnection *connection); -G_END_DECLS - #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/nm-settings-plugin.h b/src/settings/nm-settings-plugin.h index ab88e7c2..8abd72ea 100644 --- a/src/settings/nm-settings-plugin.h +++ b/src/settings/nm-settings-plugin.h @@ -22,11 +22,7 @@ #ifndef __NETWORKMANAGER_SETTINGS_PLUGIN_H__ #define __NETWORKMANAGER_SETTINGS_PLUGIN_H__ - #include <nm-connection.h> -#include "nm-default.h" - -G_BEGIN_DECLS /* Plugin's factory function that returns a GObject that implements * NMSettingsPlugin. @@ -156,6 +152,4 @@ NMSettingsConnection *nm_settings_plugin_add_connection (NMSettingsPlugin *confi gboolean save_to_disk, GError **error); -G_END_DECLS - -#endif /* NM_SETTINGS_PLUGIN_H */ +#endif /* __NETWORKMANAGER_SETTINGS_PLUGIN_H__ */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 73c678a6..1f691c0b 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -25,6 +25,8 @@ #include "nm-default.h" +#include "nm-settings.h" + #include <unistd.h> #include <sys/stat.h> #include <errno.h> @@ -60,7 +62,6 @@ #include "nm-core-internal.h" #include "nm-device-ethernet.h" -#include "nm-settings.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" #include "nm-bus-manager.h" @@ -69,7 +70,6 @@ #include "nm-session-monitor.h" #include "plugins/keyfile/plugin.h" #include "nm-agent-manager.h" -#include "nm-connection-provider.h" #include "nm-config.h" #include "nm-audit-manager.h" #include "NetworkManagerUtils.h" @@ -133,11 +133,11 @@ static void claim_connection (NMSettings *self, static void unmanaged_specs_changed (NMSettingsPlugin *config, gpointer user_data); static void unrecognized_specs_changed (NMSettingsPlugin *config, gpointer user_data); -static void connection_provider_iface_init (NMConnectionProviderInterface *cp_iface); - -G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION_PROVIDER, connection_provider_iface_init)) +static void connection_ready_changed (NMSettingsConnection *conn, + GParamSpec *pspec, + gpointer user_data); +G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); typedef struct { NMAgentManager *agent_mgr; @@ -149,9 +149,9 @@ typedef struct { GSList *plugins; gboolean connections_loaded; GHashTable *connections; + NMSettingsConnection **connections_cached_list; GSList *unmanaged_specs; GSList *unrecognized_specs; - GSList *get_connections_cache; gboolean started; gboolean startup_complete; @@ -204,6 +204,11 @@ check_startup_complete (NMSettings *self) return; } + /* the connection_ready_changed signal handler is no longer needed. */ + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) + g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self); + priv->startup_complete = TRUE; _notify (self, PROP_STARTUP_COMPLETE); } @@ -258,7 +263,7 @@ load_connections (NMSettings *self) } priv->connections_loaded = TRUE; - g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTIONS); + _notify (self, PROP_CONNECTIONS); unmanaged_specs_changed (NULL, self); unrecognized_specs_changed (NULL, self); @@ -275,7 +280,7 @@ nm_settings_for_each_connection (NMSettings *self, g_return_if_fail (NM_IS_SETTINGS (self)); g_return_if_fail (for_each_func != NULL); - + priv = NM_SETTINGS_GET_PRIVATE (self); g_hash_table_iter_init (&iter, priv->connections); @@ -401,13 +406,60 @@ connection_sort (gconstpointer pa, gconstpointer pb) return 1; } +/** + * nm_settings_get_connections: + * @self: the #NMSettings + * @out_len: (out): (allow-none): returns the number of returned + * connections. + * + * Returns: (transfer-none): a list of NMSettingsConnections. The list is + * unsorted and NULL terminated. The result is never %NULL, in case of no + * connections, it returns an empty list. + * The returned list is cached internally, only valid until the next + * NMSettings operation. + */ +NMSettingsConnection *const* +nm_settings_get_connections (NMSettings *self, guint *out_len) +{ + GHashTableIter iter; + NMSettingsPrivate *priv; + guint l, i; + NMSettingsConnection **v; + NMSettingsConnection *con; + + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); + + if (priv->connections_cached_list) { + NM_SET_OUT (out_len, g_hash_table_size (priv->connections)); + return priv->connections_cached_list; + } + + l = g_hash_table_size (priv->connections); + + v = g_new (NMSettingsConnection *, l + 1); + + i = 0; + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con)) + v[i++] = con; + v[i] = NULL; + + nm_assert (i == l); + + NM_SET_OUT (out_len, l); + priv->connections_cached_list = v; + return v; +} + /* Returns a list of NMSettingsConnections. * The list is sorted in the order suitable for auto-connecting, i.e. * first go connections with autoconnect=yes and most recent timestamp. * Caller must free the list with g_slist_free(). */ GSList * -nm_settings_get_connections (NMSettings *self) +nm_settings_get_connections_sorted (NMSettings *self) { GHashTableIter iter; gpointer data = NULL; @@ -886,7 +938,6 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer 0, connection, by_user); - g_signal_emit_by_name (NM_SETTINGS (user_data), NM_CP_SIGNAL_CONNECTION_UPDATED, connection); } static void @@ -920,17 +971,18 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), 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); + if (!priv->startup_complete) + g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); g_object_unref (self); /* Forget about the connection internally */ g_hash_table_remove (priv->connections, (gpointer) cpath); + g_clear_pointer (&priv->connections_cached_list, g_free); /* Notify D-Bus */ g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); /* Re-emit for listeners like NMPolicy */ - g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_REMOVED, connection); _notify (self, PROP_CONNECTIONS); if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection))) nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection)); @@ -1069,6 +1121,7 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) g_hash_table_insert (priv->connections, (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), g_object_ref (connection)); + g_clear_pointer (&priv->connections_cached_list, g_free); nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ "); @@ -1078,7 +1131,6 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) if (priv->connections_loaded) { /* Internal added signal */ g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); - g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_ADDED, connection); _notify (self, PROP_CONNECTIONS); /* Exported D-Bus signal */ @@ -1154,16 +1206,6 @@ nm_settings_add_connection (NMSettings *self, return NULL; } -static NMConnection * -_nm_connection_provider_add_connection (NMConnectionProvider *provider, - NMConnection *connection, - gboolean save_to_disk, - GError **error) -{ - g_assert (NM_IS_CONNECTION_PROVIDER (provider) && NM_IS_SETTINGS (provider)); - return NM_CONNECTION (nm_settings_add_connection (NM_SETTINGS (provider), connection, save_to_disk, error)); -} - static gboolean secrets_filter_cb (NMSetting *setting, const char *secret, @@ -1411,12 +1453,12 @@ impl_settings_add_connection_add_cb (NMSettings *self, { if (error) { g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message); + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message); } else { g_dbus_method_invocation_return_value ( context, g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL, subject, NULL); } } @@ -1470,31 +1512,6 @@ impl_settings_add_connection_unsaved (NMSettings *self, impl_settings_add_connection_helper (self, context, settings, FALSE); } -static gboolean -ensure_root (NMBusManager *dbus_mgr, - GDBusMethodInvocation *context) -{ - gulong caller_uid; - GError *error = NULL; - - if (!nm_bus_manager_get_caller_info (dbus_mgr, context, NULL, &caller_uid, NULL)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to determine request UID."); - g_dbus_method_invocation_take_error (context, error); - return FALSE; - } - if (caller_uid != 0) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Permission denied"); - g_dbus_method_invocation_take_error (context, error); - return FALSE; - } - - return TRUE; -} - static void impl_settings_load_connections (NMSettings *self, GDBusMethodInvocation *context, @@ -1505,7 +1522,15 @@ impl_settings_load_connections (NMSettings *self, GSList *iter; int i; - if (!ensure_root (nm_bus_manager_get (), context)) + /* The permission is already enforced by the D-Bus daemon, but we ensure + * that the caller is still alive so that clients are forced to wait and + * we'll be able to switch to polkit without breaking behavior. + */ + if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), + context, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; failures = g_ptr_array_new (); @@ -1541,7 +1566,15 @@ impl_settings_reload_connections (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; - if (!ensure_root (nm_bus_manager_get (), context)) + /* The permission is already enforced by the D-Bus daemon, but we ensure + * that the caller is still alive so that clients are forced to wait and + * we'll be able to switch to polkit without breaking behavior. + */ + if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), + context, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { @@ -1837,11 +1870,11 @@ have_connection_for_device (NMSettings *self, NMDevice *device) NMSettingConnection *s_con; NMSettingWired *s_wired; const char *setting_hwaddr; - const char *device_hwaddr; + const char *perm_hw_addr; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - device_hwaddr = nm_device_get_hw_address (device); + perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); @@ -1875,8 +1908,8 @@ have_connection_for_device (NMSettings *self, NMDevice *device) setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); if (setting_hwaddr) { /* A connection mac-locked to this device */ - if ( device_hwaddr - && nm_utils_hwaddr_matches (setting_hwaddr, -1, device_hwaddr, -1)) + if ( perm_hw_addr + && nm_utils_hwaddr_matches (setting_hwaddr, -1, perm_hw_addr, -1)) return TRUE; } else { /* A connection that applies to any wired device */ @@ -2071,22 +2104,41 @@ nm_settings_sort_connections (gconstpointer a, gconstpointer b) return 0; } -static GSList * -get_best_connections (NMConnectionProvider *provider, - guint max_requested, - const char *ctype1, - const char *ctype2, - NMConnectionFilterFunc func, - gpointer func_data) +/** + * nm_settings_get_best_connections: + * @self: the #NMSetting + * @max_requested: if non-zero, the maximum number of connections to return + * @ctype1: an #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) to + * filter connections against + * @ctype2: a second #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) + * to filter connections against + * @func: caller-supplied function for filtering connections + * @func_data: caller-supplied data passed to @func + * + * Returns: a #GSList of #NMConnection objects in sorted order representing the + * "best" or highest-priority connections filtered by @ctype1 and/or @ctype2, + * and/or @func. Caller is responsible for freeing the returned #GSList, but + * the contained values do not need to be unreffed. + */ +GSList * +nm_settings_get_best_connections (NMSettings *self, + guint max_requested, + const char *ctype1, + const char *ctype2, + NMConnectionFilterFunc func, + gpointer func_data) { - NMSettings *self = NM_SETTINGS (provider); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv; GSList *sorted = NULL; GHashTableIter iter; NMSettingsConnection *connection; guint added = 0; guint64 oldest = 0; + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { guint64 cur_ts = 0; @@ -2095,7 +2147,7 @@ get_best_connections (NMConnectionProvider *provider, continue; if (ctype2 && !nm_connection_is_type (NM_CONNECTION (connection), ctype2)) continue; - if (func && !func (provider, NM_CONNECTION (connection), func_data)) + if (func && !func (self, NM_CONNECTION (connection), func_data)) continue; /* Don't bother with a connection that's older than the oldest one in the list */ @@ -2121,27 +2173,6 @@ get_best_connections (NMConnectionProvider *provider, return g_slist_reverse (sorted); } -static const GSList * -get_connections (NMConnectionProvider *provider) -{ - GSList *list = NULL; - NMSettings *self = NM_SETTINGS (provider); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - - list = _nm_utils_hash_values_to_slist (priv->connections); - - /* Cache the list every call so we can keep it 'const' for callers */ - g_slist_free (priv->get_connections_cache); - priv->get_connections_cache = list; - return list; -} - -static NMConnection * -cp_get_connection_by_uuid (NMConnectionProvider *provider, const char *uuid) -{ - return NM_CONNECTION (nm_settings_get_connection_by_uuid (NM_SETTINGS (provider), uuid)); -} - /***************************************************************/ gboolean @@ -2190,14 +2221,30 @@ setup_hostname_file_monitors (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GFileMonitor *monitor; + const char *path = HOSTNAME_FILE; + char *link_path = NULL; + struct stat file_stat; GFile *file; priv->hostname.value = nm_settings_get_hostname (self); + /* resolve the path to the hostname file if it is a symbolic link */ + if ( lstat(path, &file_stat) == 0 + && S_ISLNK (file_stat.st_mode) + && (link_path = nm_utils_read_link_absolute (path, NULL))) { + path = link_path; + if ( lstat(link_path, &file_stat) == 0 + && S_ISLNK (file_stat.st_mode)) { + _LOGW ("only one level of symbolic link indirection is allowed when monitoring " + HOSTNAME_FILE); + } + } + /* monitor changes to hostname file */ - file = g_file_new_for_path (HOSTNAME_FILE); + file = g_file_new_for_path (path); monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); g_object_unref (file); + g_free(link_path); if (monitor) { priv->hostname.monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (hostname_file_changed_cb), @@ -2287,15 +2334,6 @@ nm_settings_start (NMSettings *self, GError **error) } static void -connection_provider_iface_init (NMConnectionProviderInterface *cp_iface) -{ - cp_iface->get_best_connections = get_best_connections; - cp_iface->get_connections = get_connections; - cp_iface->add_connection = _nm_connection_provider_add_connection; - cp_iface->get_connection_by_uuid = cp_get_connection_by_uuid; -} - -static void nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); @@ -2359,7 +2397,7 @@ finalize (GObject *object) NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); g_hash_table_destroy (priv->connections); - g_slist_free (priv->get_connections_cache); + g_clear_pointer (&priv->connections_cached_list, g_free); g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 5d41e5bc..a0be42ee 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -49,6 +49,18 @@ #define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" #define NM_SETTINGS_SIGNAL_AGENT_REGISTERED "agent-registered" +/** + * NMConnectionFilterFunc: + * @settings: The #NMSettings requesting the filtering + * @connection: the connection to be filtered + * @func_data: the caller-provided data pointer + * + * Returns: %TRUE to allow the connection, %FALSE to ignore it + */ +typedef gboolean (*NMConnectionFilterFunc) (NMSettings *settings, + NMConnection *connection, + gpointer func_data); + struct _NMSettings { NMExportedObject parent_instance; }; @@ -61,6 +73,9 @@ typedef void (*NMSettingsSetHostnameCb) (const char *name, gboolean result, gpoi GType nm_settings_get_type (void); +NMSettings *nm_settings_get (void); +#define NM_SETTINGS_GET (nm_settings_get ()) + NMSettings *nm_settings_new (void); gboolean nm_settings_start (NMSettings *self, GError **error); @@ -86,10 +101,16 @@ void nm_settings_add_connection_dbus (NMSettings *self, NMSettingsAddCallback callback, gpointer user_data); -/* Returns a list of NMSettingsConnections. Caller must free the list with - * g_slist_free(). - */ -GSList *nm_settings_get_connections (NMSettings *settings); +NMSettingsConnection *const* nm_settings_get_connections (NMSettings *settings, guint *out_len); + +GSList *nm_settings_get_connections_sorted (NMSettings *settings); + +GSList *nm_settings_get_best_connections (NMSettings *self, + guint max_requested, + const char *ctype1, + const char *ctype2, + NMConnectionFilterFunc func, + gpointer func_data); NMSettingsConnection *nm_settings_add_connection (NMSettings *settings, NMConnection *connection, diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in index e770ccde..ba388a5f 100644 --- a/src/settings/plugins/Makefile.in +++ b/src/settings/plugins/Makefile.in @@ -93,8 +93,9 @@ host_triplet = @host@ @CONFIG_PLUGIN_IFNET_TRUE@am__append_4 = ifnet subdir = src/settings/plugins ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -229,6 +230,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -285,13 +287,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -303,6 +306,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -363,6 +368,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -398,6 +405,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/ibft/Makefile.in b/src/settings/plugins/ibft/Makefile.in index fe124670..9da764de 100644 --- a/src/settings/plugins/ibft/Makefile.in +++ b/src/settings/plugins/ibft/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ibft ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -296,6 +297,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -352,13 +354,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -370,6 +373,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -430,6 +435,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -465,6 +472,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/ibft/nm-ibft-connection.h b/src/settings/plugins/ibft/nm-ibft-connection.h index 4ccebc3c..a4ee17ac 100644 --- a/src/settings/plugins/ibft/nm-ibft-connection.h +++ b/src/settings/plugins/ibft/nm-ibft-connection.h @@ -21,8 +21,6 @@ #ifndef NM_IBFT_CONNECTION_H #define NM_IBFT_CONNECTION_H -G_BEGIN_DECLS - #include <nm-settings-connection.h> #define NM_TYPE_IBFT_CONNECTION (nm_ibft_connection_get_type ()) @@ -45,6 +43,4 @@ GType nm_ibft_connection_get_type (void); NMIbftConnection *nm_ibft_connection_new (const GPtrArray *block, GError **error); -G_END_DECLS - #endif /* NM_IBFT_CONNECTION_H */ diff --git a/src/settings/plugins/ibft/plugin.h b/src/settings/plugins/ibft/plugin.h index 3fc58c7f..4867e07d 100644 --- a/src/settings/plugins/ibft/plugin.h +++ b/src/settings/plugins/ibft/plugin.h @@ -21,8 +21,6 @@ #ifndef _PLUGIN_H_ #define _PLUGIN_H_ -#include "nm-default.h" - #define SETTINGS_TYPE_PLUGIN_IBFT (settings_plugin_ibft_get_type ()) #define SETTINGS_PLUGIN_IBFT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IBFT, SettingsPluginIbft)) #define SETTINGS_PLUGIN_IBFT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IBFT, SettingsPluginIbftClass)) diff --git a/src/settings/plugins/ibft/reader.h b/src/settings/plugins/ibft/reader.h index 42969ae0..97ef0c71 100644 --- a/src/settings/plugins/ibft/reader.h +++ b/src/settings/plugins/ibft/reader.h @@ -23,8 +23,6 @@ #include <nm-connection.h> -#include "nm-default.h" - gboolean read_ibft_blocks (const char *iscsiadm_path, GSList **out_blocks, GError **error); diff --git a/src/settings/plugins/ibft/tests/Makefile.am b/src/settings/plugins/ibft/tests/Makefile.am index 939947ca..e5cff73f 100644 --- a/src/settings/plugins/ibft/tests/Makefile.am +++ b/src/settings/plugins/ibft/tests/Makefile.am @@ -34,6 +34,9 @@ test_ibft_LDADD = \ @VALGRIND_RULES@ TESTS = test-ibft +check-local: + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ibft.so $(top_builddir)/src/NetworkManager --version >/dev/null + endif EXTRA_DIST = \ diff --git a/src/settings/plugins/ibft/tests/Makefile.in b/src/settings/plugins/ibft/tests/Makefile.in index c3fef788..f0c681ab 100644 --- a/src/settings/plugins/ibft/tests/Makefile.in +++ b/src/settings/plugins/ibft/tests/Makefile.in @@ -92,8 +92,9 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@TESTS = test-ibft$(EXEEXT) subdir = src/settings/plugins/ibft/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -424,6 +425,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -480,13 +482,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -498,6 +501,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -558,6 +563,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -593,6 +600,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -1034,8 +1042,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done +@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1145,19 +1154,20 @@ uninstall-am: .MAKE: check-am install-am install-strip -.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 \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am \ + check-local 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 install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am .PRECIOUS: Makefile @@ -1166,6 +1176,9 @@ uninstall-am: @ENABLE_TESTS_TRUE@@VALGRIND_RULES@ +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ibft.so $(top_builddir)/src/NetworkManager --version >/dev/null + # 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 9c98d891..cab468de 100644 --- a/src/settings/plugins/ibft/tests/test-ibft.c +++ b/src/settings/plugins/ibft/tests/test-ibft.c @@ -34,7 +34,7 @@ #include "reader.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static GPtrArray * read_block (const char *iscsiadm_path, const char *expected_mac) diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in index a87ee94c..3cd841c3 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -91,8 +91,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifcfg-rh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -306,6 +307,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -362,13 +364,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -380,6 +383,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -440,6 +445,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -475,6 +482,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index 5d6ebe6d..d850ac4e 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -21,8 +21,6 @@ #ifndef __COMMON_H__ #define __COMMON_H__ -#include "nm-default.h" - #define IFCFG_TAG "ifcfg-" #define KEYS_TAG "keys-" #define ROUTE_TAG "route-" @@ -38,7 +36,7 @@ #define AUGNEW_TAG ".augnew" #define AUGTMP_TAG ".augtmp" -#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts" +#define IFCFG_DIR SYSCONFDIR "/sysconfig/network-scripts" #define IFCFG_PLUGIN_NAME "ifcfg-rh" #define IFCFG_PLUGIN_INFO "(c) 2007 - 2015 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index b9bbf6d5..82f20598 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -20,6 +20,8 @@ #include "nm-default.h" +#include "nm-ifcfg-connection.h" + #include <string.h> #include <glib/gstdio.h> @@ -37,7 +39,6 @@ #include "common.h" #include "nm-config.h" -#include "nm-ifcfg-connection.h" #include "reader.h" #include "writer.h" #include "nm-inotify-helper.h" @@ -469,7 +470,7 @@ nm_ifcfg_connection_init (NMIfcfgConnection *connection) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); @@ -488,7 +489,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) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 44e02987..57db059b 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -21,10 +21,8 @@ #ifndef __NETWORKMANAGER_IFCFG_CONNECTION_H__ #define __NETWORKMANAGER_IFCFG_CONNECTION_H__ -G_BEGIN_DECLS - -#include <nm-dbus-interface.h> -#include <nm-settings-connection.h> +#include "nm-dbus-interface.h" +#include "nm-settings-connection.h" #define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) #define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection)) @@ -58,6 +56,4 @@ gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self, GHashTable *new_settings, GError **error); -G_END_DECLS - #endif /* __NETWORKMANAGER_IFCFG_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index 63184eb5..c2956d22 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -23,6 +23,8 @@ #include "nm-default.h" +#include "plugin.h" + #include <string.h> #include <unistd.h> #include <errno.h> @@ -31,20 +33,19 @@ #include <gmodule.h> +#include "nm-dbus-compat.h" #include "nm-setting-connection.h" -#include "common.h" -#include "plugin.h" #include "nm-settings-plugin.h" #include "nm-config.h" #include "NetworkManagerUtils.h" #include "nm-ifcfg-connection.h" #include "shvar.h" +#include "common.h" #include "reader.h" #include "writer.h" #include "utils.h" -#include "nm-dbus-compat.h" #include "nm-exported-object.h" #include "nmdbus-ifcfg-rh.h" @@ -61,8 +62,6 @@ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } G_STMT_END -#define ERR_GET_MSG(err) (((err) && (err)->message) ? (err)->message : "(unknown)") - static NMIfcfgConnection *update_connection (SettingsPluginIfcfg *plugin, NMConnection *source, @@ -364,17 +363,9 @@ update_connection (SettingsPluginIfcfg *self, 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); + _LOGI ("Ignoring connection "NM_IFCFG_CONNECTION_LOG_FMT" due to NM_CONTROLLED=no. Unmanaged: %s.", + NM_IFCFG_CONNECTION_LOG_ARG (connection_new), + nm_ifcfg_connection_get_unmanaged_spec (connection_new)); } 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)); diff --git a/src/settings/plugins/ifcfg-rh/plugin.h b/src/settings/plugins/ifcfg-rh/plugin.h index eba734cf..74c4b00a 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.h +++ b/src/settings/plugins/ifcfg-rh/plugin.h @@ -24,8 +24,6 @@ #ifndef _PLUGIN_H_ #define _PLUGIN_H_ -#include "nm-exported-object.h" - #define SETTINGS_TYPE_PLUGIN_IFCFG (settings_plugin_ifcfg_get_type ()) #define SETTINGS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfg)) #define SETTINGS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfgClass)) @@ -46,5 +44,5 @@ struct _SettingsPluginIfcfgClass { GType settings_plugin_ifcfg_get_type (void); -#endif /* _PLUGIN_H_ */ +#endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index fe762db1..af5d2910 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -20,6 +20,8 @@ #include "nm-default.h" +#include "reader.h" + #include <stdlib.h> #include <string.h> #include <sys/types.h> @@ -57,35 +59,31 @@ #include "shvar.h" #include "utils.h" -#include "reader.h" +/*****************************************************************************/ -#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG_PREFIX_NAME "ifcfg-rh" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + nm_log ((level), (_NMLOG_DOMAIN), \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME": " \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END -static gboolean -get_int (const char *str, int *value) -{ - char *e; - long int tmp; +#define PARSE_WARNING(...) _LOGW ("%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), " " _NM_UTILS_MACRO_REST(__VA_ARGS__)) - errno = 0; - tmp = strtol (str, &e, 0); - if (errno || *e != '\0' || tmp > G_MAXINT || tmp < G_MININT) - return FALSE; - *value = (int) tmp; - return TRUE; -} +/*****************************************************************************/ static gboolean get_uint (const char *str, guint32 *value) { - char *e; - long unsigned int tmp; + gint64 tmp; - errno = 0; - tmp = strtoul (str, &e, 0); - if (errno || *e != '\0') + tmp = _nm_utils_ascii_str_to_int64 (str, 0, 0, G_MAXUINT32, -1); + if (tmp == -1) return FALSE; - *value = (guint32) tmp; + *value = tmp; return TRUE; } @@ -130,6 +128,7 @@ make_connection_setting (const char *file, NMSettingConnectionLldp lldp; const char *ifcfg_name = NULL; char *new_id, *uuid = NULL, *zone = NULL, *value; + gs_free char *stable_id = NULL; ifcfg_name = utils_get_ifcfg_name (file, TRUE); if (!ifcfg_name) @@ -148,9 +147,12 @@ make_connection_setting (const char *file, uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); } + stable_id = svGetValue (ifcfg, "STABLE_ID", FALSE); + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_STABLE_ID, stable_id, NULL); g_free (uuid); @@ -242,15 +244,12 @@ make_connection_setting (const char *file, value = svGetValue (ifcfg, "GATEWAY_PING_TIMEOUT", FALSE); if (value) { - long int tmp; - guint32 timeout; + gint64 tmp; - errno = 0; - tmp = strtol (value, NULL, 10); - if (errno == 0 && tmp >= 0 && tmp < G_MAXINT32) { - timeout = (guint32) tmp; - g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, timeout, NULL); - } else + tmp = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32 - 1, -1); + if (tmp >= 0) + g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, (guint) tmp, NULL); + else PARSE_WARNING ("invalid GATEWAY_PING_TIMEOUT time"); g_free (value); } @@ -541,7 +540,8 @@ 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; - gint64 prefix_int, metric_int; + int prefix_int; + gint64 metric_int; gboolean success = FALSE; const char *pattern_empty = "^\\s*(\\#.*)?$"; @@ -609,9 +609,8 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * g_match_info_free (match_info); prefix_int = 32; if (prefix) { - errno = 0; - prefix_int = strtol (prefix, NULL, 10); - if (errno || prefix_int <= 0 || prefix_int > 32) { + prefix_int = _nm_utils_ascii_str_to_int64 (prefix, 10, 1, 32, -1); + if (prefix_int == -1) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route destination prefix '%s'", prefix); g_free (prefix); @@ -641,9 +640,8 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * metric_int = -1; if (g_match_info_matches (match_info)) { metric = g_match_info_fetch (match_info, 1); - errno = 0; - metric_int = strtol (metric, NULL, 10); - if (errno || metric_int < 0) { + metric_int = _nm_utils_ascii_str_to_int64 (metric, 10, 0, G_MAXUINT32, -1); + if (metric_int == -1) { g_match_info_free (match_info); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route metric '%s'", metric); @@ -766,7 +764,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; GMatchInfo *match_info; char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; - gint64 prefix_int, metric_int; + int prefix_int; + gint64 metric_int; gboolean success = FALSE; const char *pattern_empty = "^\\s*(\\#.*)?$"; @@ -828,9 +827,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error g_match_info_free (match_info); prefix_int = 128; if (prefix) { - errno = 0; - prefix_int = strtol (prefix, NULL, 10); - if (errno || prefix_int <= 0 || prefix_int > 128) { + prefix_int = _nm_utils_ascii_str_to_int64 (prefix, 10, 1, 128, -1); + if (prefix_int == -1) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 route destination prefix '%s'", prefix); g_free (dest); @@ -864,9 +862,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error metric_int = -1; if (g_match_info_matches (match_info)) { metric = g_match_info_fetch (match_info, 1); - errno = 0; - metric_int = strtol (metric, NULL, 10); - if (errno || metric_int < 0 || metric_int > G_MAXUINT32) { + metric_int = _nm_utils_ascii_str_to_int64 (metric, 10, 0, G_MAXUINT32, -1); + if (metric_int == -1) { g_match_info_free (match_info); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 route metric '%s'", metric); @@ -919,6 +916,7 @@ make_ip4_setting (shvarFile *ifcfg, shvarFile *route_ifcfg; gboolean never_default = FALSE; gint64 timeout; + gint priority; s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); @@ -1141,6 +1139,13 @@ make_ip4_setting (shvarFile *ifcfg, g_free (dns_options); dns_options = NULL; + /* DNS priority */ + priority = svGetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_DNS_PRIORITY, + priority, + NULL); + /* Static routes - route-<name> file */ route_path = utils_get_route_path (ifcfg->fileName); @@ -1323,6 +1328,7 @@ make_ip6_setting (shvarFile *ifcfg, char *ipv6addr, *ipv6addr_secondaries; char **list = NULL, **iter; guint32 i; + gint priority; shvarFile *network_ifcfg; gboolean never_default = FALSE; gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip; @@ -1525,6 +1531,13 @@ make_ip6_setting (shvarFile *ifcfg, NULL); } + /* IPv6 tokenized interface identifier */ + tmp = svGetValue (ifcfg, "IPV6_TOKEN", FALSE); + if (tmp) { + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, tmp, NULL); + g_free (tmp); + } + /* DNS servers * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) */ @@ -1572,6 +1585,13 @@ make_ip6_setting (shvarFile *ifcfg, g_free (value); g_free (dns_options); + /* DNS priority */ + priority = svGetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_DNS_PRIORITY, + priority, + NULL); + return NM_SETTING (s_ip6); error: @@ -1681,10 +1701,9 @@ read_dcb_app (shvarFile *ifcfg, tmp = g_strdup_printf ("DCB_APP_%s_PRIORITY", app); val = svGetValue (ifcfg, tmp, FALSE); if (val) { - success = get_int (val, &priority); - if (success) - success = (priority >= 0 && priority <= 7); - if (!success) { + priority = _nm_utils_ascii_str_to_int64 (val, 0, 0, 7, -1); + if (priority < 0) { + success = FALSE; g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid %s value '%s' (expected 0 - 7)", tmp, val); @@ -1824,7 +1843,6 @@ read_dcb_percent_array (shvarFile *ifcfg, char *val; gboolean success = FALSE; char **split = NULL, **iter; - int tmp; guint i, sum = 0; val = svGetValue (ifcfg, prop, FALSE); @@ -1847,7 +1865,10 @@ read_dcb_percent_array (shvarFile *ifcfg, } for (iter = split, i = 0; iter && *iter; iter++, i++) { - if (!get_int (*iter, &tmp) || tmp < 0 || tmp > 100) { + int tmp; + + tmp = _nm_utils_ascii_str_to_int64 (*iter, 0, 0, 100, -1); + if (tmp < 0) { PARSE_WARNING ("invalid %s percentage value '%s'", prop, *iter); g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "invalid percent element"); @@ -2169,7 +2190,7 @@ make_wep_setting (shvarFile *ifcfg, char *value; shvarFile *keys_ifcfg = NULL; int default_key_idx = 0; - gboolean has_default_key = FALSE, success; + gboolean has_default_key = FALSE; NMSettingSecretFlags key_flags; s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); @@ -2177,18 +2198,17 @@ make_wep_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "DEFAULTKEY", FALSE); if (value) { - success = get_int (value, &default_key_idx); - if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) { - has_default_key = TRUE; - default_key_idx--; /* convert to [0...3] */ - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL); - } else { + default_key_idx = _nm_utils_ascii_str_to_int64 (value, 0, 1, 4, 0); + if (default_key_idx == 0) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid default WEP key '%s'", value); - g_free (value); + g_free (value); goto error; } - g_free (value); + has_default_key = TRUE; + default_key_idx--; /* convert to [0...3] */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, (guint) default_key_idx, NULL); + g_free (value); } /* Read WEP key flags */ @@ -3348,6 +3368,10 @@ make_wireless_setting (shvarFile *ifcfg, g_free (value); } + value = svGetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", FALSE); + g_object_set (s_wireless, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, value, NULL); + g_free (value); + value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE); if (value) { char **strv; @@ -3489,17 +3513,16 @@ make_wireless_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "MTU", FALSE); if (value) { - long int mtu; + int mtu; - errno = 0; - mtu = strtol (value, NULL, 10); - if (errno || mtu < 0 || mtu > 50000) { + mtu = _nm_utils_ascii_str_to_int64 (value, 10, 0, 50000, -1); + if (mtu == -1) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid wireless MTU '%s'", value); g_free (value); goto error; } - g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL); + g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint) mtu, NULL); g_free (value); } @@ -3761,20 +3784,19 @@ make_wired_setting (shvarFile *ifcfg, { NMSettingWired *s_wired; char *value = NULL; - int mtu; char *nettype; s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); value = svGetValue (ifcfg, "MTU", FALSE); if (value) { - if (get_int (value, &mtu)) { - if (mtu >= 0 && mtu < 65536) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL); - } else { - /* Shouldn't be fatal... */ + int mtu; + + mtu = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (mtu >= 0) + g_object_set (s_wired, NM_SETTING_WIRED_MTU, (guint) mtu, NULL); + else PARSE_WARNING ("invalid MTU '%s'", value); - } g_free (value); } @@ -3864,6 +3886,10 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } + value = svGetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", FALSE); + g_object_set (s_wired, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, value, NULL); + g_free (value); + value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE); if (value) { char **strv; @@ -3945,9 +3971,9 @@ parse_infiniband_p_key (shvarFile *ifcfg, char **out_parent, GError **error) { - char *device = NULL, *physdev = NULL, *pkey_id = NULL, *end; + char *device = NULL, *physdev = NULL, *pkey_id = NULL; char *ifname = NULL; - guint32 id = G_MAXUINT32; + int id; gboolean ret = FALSE; device = svGetValue (ifcfg, "DEVICE", FALSE); @@ -3968,19 +3994,14 @@ parse_infiniband_p_key (shvarFile *ifcfg, goto done; } - if (g_str_has_prefix (pkey_id, "0x")) - id = strtoul (pkey_id, &end, 16); - else if (!g_str_has_prefix (pkey_id, "0")) - id = strtoul (pkey_id, &end, 10); - else - end = pkey_id; - if (end == pkey_id || *end || id > 0xFFFF) { + id = _nm_utils_ascii_str_to_int64 (pkey_id, 0, 0, 0xFFFF, -1); + if (id == -1) { PARSE_WARNING ("invalid InfiniBand PKEY_ID '%s'", pkey_id); goto done; } id = (id | 0x8000); - ifname = g_strdup_printf ("%s.%04x", physdev, id); + ifname = g_strdup_printf ("%s.%04x", physdev, (unsigned) id); if (strcmp (device, ifname) != 0) { PARSE_WARNING ("InfiniBand DEVICE (%s) does not match PHYSDEV+PKEY_ID (%s)", device, ifname); @@ -4012,19 +4033,18 @@ make_infiniband_setting (shvarFile *ifcfg, { NMSettingInfiniband *s_infiniband; char *value = NULL; - int mtu; s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ()); value = svGetValue (ifcfg, "MTU", FALSE); if (value) { - if (get_int (value, &mtu)) { - if (mtu >= 0 && mtu < 65536) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu, NULL); - } else { - /* Shouldn't be fatal... */ + int mtu; + + mtu = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (mtu >= 0) + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, (guint) mtu, NULL); + else PARSE_WARNING ("invalid MTU '%s'", value); - } g_free (value); } @@ -4648,16 +4668,14 @@ make_vlan_setting (shvarFile *ifcfg, char *iface_name = NULL; char *parent = NULL; const char *p = NULL; - char *end = NULL; - gint vlan_id = -1; + int vlan_id = -1; guint32 vlan_flags = 0; gint gvrp, reorder_hdr; value = svGetValue (ifcfg, "VLAN_ID", FALSE); if (value) { - errno = 0; - vlan_id = (gint) g_ascii_strtoll (value, NULL, 10); - if (vlan_id < 0 || vlan_id > 4096 || errno) { + vlan_id = _nm_utils_ascii_str_to_int64 (value, 10, 0, 4095, -1); + if (vlan_id == -1) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid VLAN_ID '%s'", value); g_free (value); @@ -4701,12 +4719,13 @@ make_vlan_setting (shvarFile *ifcfg, } if (p) { + int device_vlan_id; + /* Grab VLAN ID from interface name; this takes precedence over the * separate VLAN_ID property for backwards compat. */ - - gint device_vlan_id = (gint) g_ascii_strtoll (p, &end, 10); - if (device_vlan_id >= 0 && device_vlan_id <= 4095 && end != p && !*end) + device_vlan_id = _nm_utils_ascii_str_to_int64 (p, 10, 0, 4095, -1); + if (device_vlan_id != -1) vlan_id = device_vlan_id; } } diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h index 88f9a720..35464474 100644 --- a/src/settings/plugins/ifcfg-rh/reader.h +++ b/src/settings/plugins/ifcfg-rh/reader.h @@ -21,10 +21,7 @@ #ifndef __READER_H__ #define __READER_H__ -#include <nm-connection.h> - -#include "nm-default.h" -#include "shvar.h" +#include "nm-connection.h" NMConnection *connection_from_file (const char *filename, char **out_unhandled, diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 4e756349..75b19d53 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -25,6 +25,8 @@ #include "nm-default.h" +#include "shvar.h" + #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -34,12 +36,8 @@ #include <sys/stat.h> #include <unistd.h> -#include "shvar.h" - #include "nm-core-internal.h" -#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) - /* Open the file <name>, returning a shvarFile on success and NULL on failure. * Add a wrinkle to let the caller specify whether or not to create the file * (actually, return a structure anyway) if it doesn't exist. @@ -273,26 +271,23 @@ svGetValueFull (shvarFile *s, const char *key, gboolean verbatim) { char *value = NULL; char *line; - char *keyString; - int len; + guint len; g_return_val_if_fail (s != NULL, NULL); g_return_val_if_fail (key != NULL, NULL); - keyString = g_strdup_printf ("%s=", key); - len = strlen (keyString); + len = strlen (key); for (s->current = s->lineList; s->current; s->current = s->current->next) { line = s->current->data; - if (!strncmp (keyString, line, len)) { + if (!strncmp (key, line, len) && line[len] == '=') { /* Strip trailing spaces before unescaping to preserve spaces quoted whitespace */ - value = g_strchomp (g_strdup (line + len)); + value = g_strchomp (g_strdup (line + len + 1)); if (!verbatim) svUnescape (value); break; } } - g_free (keyString); return value; } @@ -373,11 +368,10 @@ svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 m result = _nm_utils_ascii_str_to_int64 (tmp, base, min, max, fallback); errsv = errno; - if (errsv != 0) - PARSE_WARNING ("Error reading '%s' value '%s' as integer (%d)", key, tmp, errsv); g_free (tmp); + errno = errsv; return result; } diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 227a44db..97df8128 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -31,10 +31,6 @@ #ifndef _SHVAR_H #define _SHVAR_H -#include "nm-default.h" - -G_BEGIN_DECLS - typedef struct _shvarFile shvarFile; struct _shvarFile { char *fileName; /* read-only */ @@ -95,6 +91,4 @@ const char *svEscape (const char *s, char **to_free); /* Unescape a string in-place */ void svUnescape (char *s); -G_END_DECLS - -#endif /* ! _SHVAR_H */ +#endif /* _SHVAR_H */ diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am index 73ddfeef..fedbd93f 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am @@ -49,5 +49,8 @@ test_ifcfg_rh_utils_LDADD = \ @VALGRIND_RULES@ TESTS = test-ifcfg-rh-utils test-ifcfg-rh +check-local: + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifcfg-rh.so $(top_builddir)/src/NetworkManager --version >/dev/null + endif diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in index 4bc35da2..ac21e19b 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -94,8 +94,9 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@ test-ifcfg-rh$(EXEEXT) subdir = src/settings/plugins/ifcfg-rh/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -478,6 +479,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -534,13 +536,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -552,6 +555,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -612,6 +617,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -647,6 +654,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -1220,8 +1228,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done +@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive @@ -1333,19 +1342,19 @@ uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) 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 install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ - uninstall uninstall-am + check-TESTS check-am check-local 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 \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @@ -1354,6 +1363,9 @@ uninstall-am: @ENABLE_TESTS_TRUE@@VALGRIND_RULES@ +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifcfg-rh.so $(top_builddir)/src/NetworkManager --version >/dev/null + # 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.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in index 74f3bf05..30cc7c05 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifcfg-rh/tests/network-scripts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -165,6 +166,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -221,13 +223,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -239,6 +242,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -299,6 +304,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -334,6 +341,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ 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 5a0f6451..d2a348bb 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 @@ -28,7 +28,7 @@ #include "common.h" #include "utils.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static void test_get_ifcfg_name (const char *desc, 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 5ed25fda..60938f6e 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -55,7 +55,7 @@ #include "writer.h" #include "utils.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /*****************************************************************************/ @@ -1734,6 +1734,69 @@ test_read_dns_options (void) } static void +test_clear_master (void) +{ + NMSettingConnection *s_con; + NMConnection *connection; + char *unmanaged = NULL; + char *testfile = NULL, *keyfile; + GError *error = NULL; + gboolean success; + shvarFile *f; + char *val; + + /* 1. load the bridge slave connection from disk */ + connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bridge-component", + NULL, TYPE_ETHERNET, &unmanaged); + g_assert_cmpstr (unmanaged, ==, NULL); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "br0"); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, "bridge"); + + /* 2. write the connection to a new file */ + _writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile); + + /* 3. clear master and slave-type */ + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, NULL, + NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, + NULL); + + g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, NULL); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NULL); + + /* 4. update the connection on disk */ + keyfile = utils_get_keys_path (testfile); + success = writer_update_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + testfile, + keyfile, + &error); + g_assert_no_error (error); + g_assert (success); + unlink (keyfile); + g_free (keyfile); + + /* 5. check that BRIDGE variable has been removed */ + f = svOpenFile (testfile, &error); + g_assert_no_error (error); + g_assert (f); + + val = svGetValue (f, "BRIDGE", FALSE); + g_assert (!val); + svCloseFile (f); + + unlink (testfile); + g_free (testfile); + g_object_unref (connection); +} + +static void test_write_dns_options (void) { NMConnection *connection; @@ -8781,6 +8844,7 @@ int main (int argc, char **argv) g_test_add_data_func (TPATH "static-ip6-only-gw/2001:db8:8:4::2", "2001:db8:8:4::2", test_write_wired_static_ip6_only_gw); g_test_add_data_func (TPATH "static-ip6-only-gw/::ffff:255.255.255.255", "::ffff:255.255.255.255", test_write_wired_static_ip6_only_gw); g_test_add_func (TPATH "read-dns-options", test_read_dns_options); + g_test_add_func (TPATH "clear-master", test_clear_master); nmtst_add_test_func (TPATH "read-static", test_read_wired_static, TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static", "System test-wired-static", GINT_TO_POINTER (TRUE)); nmtst_add_test_func (TPATH "read-static-bootproto", test_read_wired_static, TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-bootproto", "System test-wired-static-bootproto", GINT_TO_POINTER (FALSE)); diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c index fda900b2..b602a7d7 100644 --- a/src/settings/plugins/ifcfg-rh/utils.c +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -27,7 +27,8 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "shvar.h" + +#include "common.h" /* * utils_single_quote_string diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h index 752d08a6..b8b172e7 100644 --- a/src/settings/plugins/ifcfg-rh/utils.h +++ b/src/settings/plugins/ifcfg-rh/utils.h @@ -21,10 +21,9 @@ #ifndef _UTILS_H_ #define _UTILS_H_ -#include <nm-connection.h> -#include "nm-default.h" +#include "nm-connection.h" + #include "shvar.h" -#include "common.h" #define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") #define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")" diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index c17824d6..4817549e 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -42,7 +42,6 @@ #include "nm-setting-vlan.h" #include "nm-setting-team.h" #include "nm-setting-team-port.h" -#include "nm-core-internal.h" #include "nm-utils.h" #include "nm-core-internal.h" #include "NetworkManagerUtils.h" @@ -51,8 +50,20 @@ #include "shvar.h" #include "reader.h" #include "utils.h" -#include "crypto.h" +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG_PREFIX_NAME "ifcfg-rh" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + nm_log ((level), (_NMLOG_DOMAIN), \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME": " \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + +/*****************************************************************************/ static void save_secret_flags (shvarFile *ifcfg, @@ -100,7 +111,7 @@ set_secret (shvarFile *ifcfg, { shvarFile *keyfile; GError *error = NULL; - + /* Clear the secret from the ifcfg and the associated "keys" file */ svSetValue (ifcfg, key, NULL, FALSE); @@ -109,7 +120,7 @@ set_secret (shvarFile *ifcfg, keyfile = utils_get_keys_ifcfg (ifcfg->fileName, TRUE); if (!keyfile) { - nm_log_warn (LOGD_SETTINGS, " could not create ifcfg file for '%s'", ifcfg->fileName); + _LOGW ("could not create ifcfg file for '%s'", ifcfg->fileName); goto error; } @@ -121,8 +132,8 @@ set_secret (shvarFile *ifcfg, svSetValue (keyfile, key, value, verbatim); if (!svWriteFile (keyfile, 0600, &error)) { - nm_log_warn (LOGD_SETTINGS, " could not update ifcfg file '%s': %s", - keyfile->fileName, error->message); + _LOGW ("could not update ifcfg file '%s': %s", + keyfile->fileName, error->message); g_clear_error (&error); svCloseFile (keyfile); goto error; @@ -715,7 +726,7 @@ write_wireless_security_setting (NMConnection *connection, key = ascii_key; } } else { - nm_log_warn (LOGD_SETTINGS, " invalid WEP key '%s'", key); + _LOGW ("invalid WEP key '%s'", key); tmp = NULL; } @@ -842,6 +853,10 @@ write_wireless_setting (NMConnection *connection, cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); + svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wireless_get_generate_mac_address_mask (s_wireless), + FALSE); + svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE); macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); if (macaddr_blacklist[0]) { @@ -1100,6 +1115,10 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); + svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wired_get_generate_mac_address_mask (s_wired), + FALSE); + svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE); macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); if (macaddr_blacklist[0]) { @@ -1244,19 +1263,22 @@ write_wired_for_virtual (NMConnection *connection, shvarFile *ifcfg) has_wired = TRUE; device_mac = nm_setting_wired_get_mac_address (s_wired); - if (device_mac) - svSetValue (ifcfg, "HWADDR", device_mac, FALSE); + svSetValue (ifcfg, "HWADDR", device_mac, FALSE); cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac) - svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); + svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); + + svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wired_get_generate_mac_address_mask (s_wired), + FALSE); mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) { tmp = g_strdup_printf ("%u", mtu); svSetValue (ifcfg, "MTU", tmp, FALSE); g_free (tmp); - } + } else + svSetValue (ifcfg, "MTU", NULL, FALSE); } return has_wired; } @@ -1408,7 +1430,6 @@ write_team_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, svSetValue (ifcfg, "DEVICE", iface, FALSE); config = nm_setting_team_get_config (s_team); svSetValue (ifcfg, "TEAM_CONFIG", config, FALSE); - svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM, FALSE); *wired = write_wired_for_virtual (connection, ifcfg); @@ -1786,9 +1807,14 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) const char *master, *type; char *tmp; gint i_int; + const char *v_master = NULL; + const char *v_slave = NULL; + const char *v_bridge = NULL; + const char *v_team_master = NULL; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); + svSetValue (ifcfg, "STABLE_ID", nm_setting_connection_get_stable_id (s_con), FALSE); svSetValue (ifcfg, "DEVICE", nm_setting_connection_get_interface_name (s_con), FALSE); svSetValue (ifcfg, "ONBOOT", nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no", @@ -1853,17 +1879,28 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) master = nm_setting_connection_get_master (s_con); if (master) { if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME)) { - svSetValue (ifcfg, "MASTER", master, FALSE); - svSetValue (ifcfg, "SLAVE", "yes", FALSE); + v_master = master; + v_slave = "yes"; } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BRIDGE_SETTING_NAME)) - svSetValue (ifcfg, "BRIDGE", master, FALSE); + v_bridge = master; else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) { - svSetValue (ifcfg, "TEAM_MASTER", master, FALSE); - svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM_PORT, FALSE); + v_team_master = master; svSetValue (ifcfg, "TYPE", NULL, FALSE); } } + svSetValue (ifcfg, "MASTER", v_master, FALSE); + svSetValue (ifcfg, "SLAVE", v_slave, FALSE); + svSetValue (ifcfg, "BRIDGE", v_bridge, FALSE); + svSetValue (ifcfg, "TEAM_MASTER", v_team_master, FALSE); + + if (nm_streq0 (type, NM_SETTING_TEAM_SETTING_NAME)) + svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM, FALSE); + else if (master && nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) + svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM_PORT, FALSE); + else + svSetValue (ifcfg, "DEVICETYPE", NULL, FALSE); + /* secondary connection UUIDs */ svSetValue (ifcfg, "SECONDARY_UUIDS", NULL, FALSE); n = nm_setting_connection_get_num_secondaries (s_con); @@ -1970,6 +2007,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) gint32 j; guint32 i, n, num; gint64 route_metric; + gint priority; int timeout; GString *searches; gboolean success = FALSE; @@ -2281,6 +2319,12 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1); } + priority = nm_setting_ip_config_get_dns_priority (s_ip4); + if (priority) + svSetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", priority); + else + svSetValue (ifcfg, "IPV4_DNS_PRIORITY", NULL, FALSE); + success = TRUE; out: @@ -2440,6 +2484,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) char *addr_key; char *tmp; guint32 i, num, num4; + gint priority; GString *searches; NMIPAddress *addr; const char *dns; @@ -2604,8 +2649,20 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) addr_gen_mode); svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", tmp, FALSE); g_free (tmp); + } else { + svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", NULL, FALSE); } + /* IPv6 tokenized interface identifier */ + value = nm_setting_ip6_config_get_token (NM_SETTING_IP6_CONFIG (s_ip6)); + svSetValue (ifcfg, "IPV6_TOKEN", value, FALSE); + + priority = nm_setting_ip_config_get_dns_priority (s_ip6); + if (priority) + svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority); + else + svSetValue (ifcfg, "IPV6_DNS_PRIORITY", NULL, FALSE); + /* Static routes go to route6-<dev> file */ route6_path = utils_get_route6_path (ifcfg->fileName); if (!route6_path) { diff --git a/src/settings/plugins/ifcfg-rh/writer.h b/src/settings/plugins/ifcfg-rh/writer.h index 69389361..97a9f252 100644 --- a/src/settings/plugins/ifcfg-rh/writer.h +++ b/src/settings/plugins/ifcfg-rh/writer.h @@ -21,11 +21,7 @@ #ifndef _WRITER_H_ #define _WRITER_H_ -#include <sys/types.h> - -#include <nm-connection.h> - -#include "nm-default.h" +#include "nm-connection.h" gboolean writer_can_write_connection (NMConnection *connection, GError **error); diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in index 9f99e957..44295ada 100644 --- a/src/settings/plugins/ifnet/Makefile.in +++ b/src/settings/plugins/ifnet/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifnet ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -297,6 +298,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -353,13 +355,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -371,6 +374,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -431,6 +436,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -466,6 +473,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index 80b82535..9917463f 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -679,7 +679,7 @@ make_ip4_setting (NMConnection *connection, /* DNS searches */ value = ifnet_get_data (conn_name, "dns_search"); if (value) { - char *stripped = g_strdup (value); + gs_free char *stripped = g_strdup (value); char **searches = NULL; strip_string (stripped, '"'); diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index 6e1061c6..db5e7a13 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -501,13 +501,13 @@ GList * ifnet_get_connection_names (void) { GList *names = g_hash_table_get_keys (conn_table); - GList *result = NULL; + GList *iter, *result = NULL; - while (names) { - if (!ignore_connection_name (names->data)) - result = g_list_prepend (result, names->data); - names = names->next; + for (iter = names; iter; iter = iter->next) { + if (!ignore_connection_name (iter->data)) + result = g_list_prepend (result, iter->data); } + g_list_free (names); return g_list_reverse (result); } diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h index 968feaf5..31fc9ead 100644 --- a/src/settings/plugins/ifnet/net_parser.h +++ b/src/settings/plugins/ifnet/net_parser.h @@ -22,8 +22,6 @@ #ifndef _NET_PARSER_H #define _NET_PARSER_H -#include "nm-default.h" - #define CONF_NET_FILE SYSCONFDIR "/conf.d/net" gboolean ifnet_init (gchar * config_file); @@ -40,4 +38,5 @@ gboolean ifnet_flush_to_file (const char *config_file, gchar **out_backup); void ifnet_set_data (const char *conn_name, const char *key, const char *value); gboolean ifnet_add_network (const char *name, const char *type); gboolean ifnet_delete_network (const char *conn_name); + #endif diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h index 45969369..85a5cb1c 100644 --- a/src/settings/plugins/ifnet/net_utils.h +++ b/src/settings/plugins/ifnet/net_utils.h @@ -21,12 +21,15 @@ #ifndef _IFNET_UTILS_H #define _IFNET_UTILS_H + #define IFNET_PLUGIN_NAME "SettingsPlugin-Ifnet" + #include <arpa/inet.h> + #include <nm-setting-ip6-config.h> #include <nm-setting-ip4-config.h> -#include "nm-default.h" #include "net_parser.h" + #define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address) #define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.h b/src/settings/plugins/ifnet/nm-ifnet-connection.h index baa4c07e..856996e0 100644 --- a/src/settings/plugins/ifnet/nm-ifnet-connection.h +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.h @@ -25,8 +25,6 @@ #include <nm-settings-connection.h> #include "net_parser.h" -G_BEGIN_DECLS - #define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ()) #define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection)) #define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) @@ -49,5 +47,4 @@ NMIfnetConnection *nm_ifnet_connection_new (NMConnection *source, const char *nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection); -G_END_DECLS -#endif /* NM_IFNET_CONNECTION_H */ +#endif /* __NETWORKMANAGER_IFNET_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h index 33dcc201..09640968 100644 --- a/src/settings/plugins/ifnet/plugin.h +++ b/src/settings/plugins/ifnet/plugin.h @@ -23,8 +23,6 @@ #ifndef _PLUGIN_H_ #define _PLUGIN_H_ -#include "nm-default.h" - #define SETTINGS_TYPE_PLUGIN_IFNET (settings_plugin_ifnet_get_type ()) #define SETTINGS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnet)) #define SETTINGS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass)) diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am index 6590d4ae..8ece14c6 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.am +++ b/src/settings/plugins/ifnet/tests/Makefile.am @@ -34,9 +34,12 @@ test_ifnet_LDFLAGS = \ test_ifnet_LDADD = $(top_builddir)/src/libNetworkManager.la -#@VALGRIND_RULES@ +@VALGRIND_RULES@ TESTS = test-ifnet +check-local: + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifnet.so $(top_builddir)/src/NetworkManager --version >/dev/null + endif EXTRA_DIST = \ diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in index 4646a342..0aee0582 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.in +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -92,8 +92,9 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@TESTS = test-ifnet$(EXEEXT) subdir = src/settings/plugins/ifnet/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -430,6 +431,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -486,13 +488,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -504,6 +507,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -564,6 +569,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -599,6 +606,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -1084,8 +1092,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done +@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1195,25 +1204,31 @@ uninstall-am: .MAKE: check-am install-am install-strip -.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 \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am \ + check-local 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 install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am .PRECIOUS: Makefile @ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ +@ENABLE_TESTS_TRUE@@VALGRIND_RULES@ + +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifnet.so $(top_builddir)/src/NetworkManager --version >/dev/null + # 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/ifnet/tests/test-ifnet.c b/src/settings/plugins/ifnet/tests/test-ifnet.c index 3035fdb1..49f88f1c 100644 --- a/src/settings/plugins/ifnet/tests/test-ifnet.c +++ b/src/settings/plugins/ifnet/tests/test-ifnet.c @@ -38,7 +38,7 @@ #include "connection_parser.h" #include "nm-config.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /* Fake NMConfig handling; the values it returns don't matter, so this * is easier than forcing it to read our own config file, etc. @@ -346,7 +346,7 @@ test_delete_connection (void) static void test_missing_config (void) { - GError *error = NULL; + gs_free_error GError *error = NULL; NMConnection *connection; connection = ifnet_update_connection_from_config_block ("eth8", NULL, &error); diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c index 8e2559b3..505222ab 100644 --- a/src/settings/plugins/ifnet/wpa_parser.c +++ b/src/settings/plugins/ifnet/wpa_parser.c @@ -77,8 +77,10 @@ add_security (GHashTable *security) /* Hex format begins with " */ is_hex_ssid = (ssid[0] != '"'); if ((value = g_hash_table_lookup (security, "disabled")) != NULL) { - if (strcmp (value, "1") == 0) + if (strcmp (value, "1") == 0) { + destroy_security (security); return NULL; + } } /* Default priority is 1 */ @@ -111,6 +113,7 @@ add_security (GHashTable *security) static void add_key_value (GHashTable * network, gchar * line) { + gpointer orig_key, orig_value; gchar **key_value; if (g_str_has_prefix (line, "network={")) @@ -133,6 +136,14 @@ add_key_value (GHashTable * network, gchar * line) && !g_str_has_prefix (key_value[0], "wep_key") && strcmp (key_value[0], "ssid") != 0) strip_string (key_value[1], '"'); + + /* This sucks */ + if (g_hash_table_lookup_extended (network, key_value[0], &orig_key, &orig_value)) { + g_hash_table_remove (network, orig_key); + g_free (orig_key); + g_free (orig_value); + } + g_hash_table_insert (network, g_strdup (key_value[0]), g_strdup (key_value[1])); g_strfreev (key_value); diff --git a/src/settings/plugins/ifnet/wpa_parser.h b/src/settings/plugins/ifnet/wpa_parser.h index 8099d19c..d096f468 100644 --- a/src/settings/plugins/ifnet/wpa_parser.h +++ b/src/settings/plugins/ifnet/wpa_parser.h @@ -22,8 +22,6 @@ #ifndef _WPA_PARSER_H #define _WPA_PARSER_H -#include "nm-default.h" - #define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf" void wpa_parser_init (const char *wpa_supplicant_conf); diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in index 8b153c6d..4e1c657b 100644 --- a/src/settings/plugins/ifupdown/Makefile.in +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifupdown ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -296,6 +297,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -352,13 +354,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -370,6 +373,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -430,6 +435,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -465,6 +472,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/ifupdown/interface_parser.h b/src/settings/plugins/ifupdown/interface_parser.h index d4bb8515..bf9c4465 100644 --- a/src/settings/plugins/ifupdown/interface_parser.h +++ b/src/settings/plugins/ifupdown/interface_parser.h @@ -24,8 +24,6 @@ #ifndef _INTERFACE_PARSER_H #define _INTERFACE_PARSER_H -#include "nm-default.h" - typedef struct _if_data { char *key; diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h index 8085b831..e1999bef 100644 --- a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h +++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h @@ -25,10 +25,8 @@ #define __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ #include <nm-settings-connection.h> -#include "nm-default.h" -#include "interface_parser.h" -G_BEGIN_DECLS +#include "interface_parser.h" #define NM_TYPE_IFUPDOWN_CONNECTION (nm_ifupdown_connection_get_type ()) #define NM_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnection)) @@ -49,6 +47,4 @@ GType nm_ifupdown_connection_get_type (void); NMIfupdownConnection *nm_ifupdown_connection_new (if_block *block); -G_END_DECLS - #endif /* __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifupdown/parser.h b/src/settings/plugins/ifupdown/parser.h index ee88c500..549f1ad3 100644 --- a/src/settings/plugins/ifupdown/parser.h +++ b/src/settings/plugins/ifupdown/parser.h @@ -21,14 +21,15 @@ * (C) Copyright 2008 Canonical Ltd. */ +#ifndef __PARSER_H__ +#define __PARSER_H__ + #include <nm-connection.h> #include "interface_parser.h" -G_BEGIN_DECLS - gboolean ifupdown_update_connection_from_if_block (NMConnection *connection, if_block *block, GError **error); -G_END_DECLS +#endif /* __PARSER_H__ */ diff --git a/src/settings/plugins/ifupdown/plugin.h b/src/settings/plugins/ifupdown/plugin.h index 10ba2287..b568ea78 100644 --- a/src/settings/plugins/ifupdown/plugin.h +++ b/src/settings/plugins/ifupdown/plugin.h @@ -24,8 +24,6 @@ #ifndef _PLUGIN_H_ #define _PLUGIN_H_ -#include "nm-default.h" - #define PLUGIN_NAME "ifupdown" #define SETTINGS_TYPE_PLUGIN_IFUPDOWN (settings_plugin_ifupdown_get_type ()) diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am index e12c0181..1287a716 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.am +++ b/src/settings/plugins/ifupdown/tests/Makefile.am @@ -23,10 +23,12 @@ test_ifupdown_SOURCES = \ test_ifupdown_LDADD = \ $(top_builddir)/src/libNetworkManager.la -# TODO: enable valgrind for ifupdown. Currently it fails. -#@VALGRIND_RULES@ +@VALGRIND_RULES@ TESTS = test-ifupdown +check-local: + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifupdown.so $(top_builddir)/src/NetworkManager --version >/dev/null + endif EXTRA_DIST = \ diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in index f744e620..b63f9a89 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.in +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -92,8 +92,9 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@TESTS = test-ifupdown$(EXEEXT) subdir = src/settings/plugins/ifupdown/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -425,6 +426,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -481,13 +483,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -499,6 +502,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -559,6 +564,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -594,6 +601,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -1039,8 +1047,9 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done +@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1150,23 +1159,29 @@ uninstall-am: .MAKE: check-am install-am install-strip -.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 \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am \ + check-local 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 install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am .PRECIOUS: Makefile +@ENABLE_TESTS_TRUE@@VALGRIND_RULES@ + +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/../.libs/libnm-settings-plugin-ifupdown.so $(top_builddir)/src/NetworkManager --version >/dev/null + # 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/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index f383821c..7ce08aee 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -26,7 +26,7 @@ #include "interface_parser.h" #include "parser.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" typedef struct { char *key; @@ -506,6 +506,7 @@ test17_read_static_ipv4 (const char *path) g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "example.com"); g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 1), ==, "foo.example.com"); + ifparser_destroy (); g_object_unref (connection); } @@ -560,6 +561,7 @@ test18_read_static_ipv6 (const char *path) g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "example.com"); g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "foo.example.com"); + ifparser_destroy (); g_object_unref (connection); } @@ -594,6 +596,7 @@ test19_read_static_ipv4_plen (const char *path) g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); + ifparser_destroy (); g_object_unref (connection); } diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index bace6af4..e6f4b4cf 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -90,8 +90,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/keyfile ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -265,6 +266,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -321,13 +323,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -339,6 +342,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -399,6 +404,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -434,6 +441,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h index f6fa432b..31dbe754 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.h +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -24,8 +24,6 @@ #include <nm-settings-connection.h> -G_BEGIN_DECLS - #define NM_TYPE_KEYFILE_CONNECTION (nm_keyfile_connection_get_type ()) #define NM_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnection)) #define NM_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass)) @@ -47,6 +45,4 @@ NMKeyfileConnection *nm_keyfile_connection_new (NMConnection *source, const char *filename, GError **error); -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 6003c745..c5598fc5 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -26,7 +26,6 @@ #include <sys/types.h> #include <string.h> -#include <gmodule.h> #include <glib/gstdio.h> #include "nm-connection.h" diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h index 07403270..a22b9c49 100644 --- a/src/settings/plugins/keyfile/plugin.h +++ b/src/settings/plugins/keyfile/plugin.h @@ -22,8 +22,6 @@ #ifndef _PLUGIN_H_ #define _PLUGIN_H_ -#include "nm-default.h" - #define SETTINGS_TYPE_PLUGIN_KEYFILE (settings_plugin_keyfile_get_type ()) #define SETTINGS_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_KEYFILE, SettingsPluginKeyfile)) #define SETTINGS_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_KEYFILE, SettingsPluginKeyfileClass)) diff --git a/src/settings/plugins/keyfile/reader.h b/src/settings/plugins/keyfile/reader.h index a8021cb7..7bbc6005 100644 --- a/src/settings/plugins/keyfile/reader.h +++ b/src/settings/plugins/keyfile/reader.h @@ -24,8 +24,6 @@ #include <nm-connection.h> -#include "nm-default.h" - NMConnection *nm_keyfile_plugin_connection_from_file (const char *filename, GError **error); #endif /* _KEYFILE_PLUGIN_READER_H */ diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index 89708a18..e2e56d4e 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -92,8 +92,9 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@TESTS = test-keyfile$(EXEEXT) subdir = src/settings/plugins/keyfile/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -469,6 +470,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -525,13 +527,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -543,6 +546,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -603,6 +608,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -638,6 +645,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index 8be2893c..88e03515 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/keyfile/tests/keyfiles ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -165,6 +166,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -221,13 +223,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -239,6 +242,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -299,6 +304,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -334,6 +341,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index 7b66e198..e63fa495 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -34,7 +34,7 @@ #include "writer.h" #include "utils.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static void check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen) @@ -1546,7 +1546,7 @@ test_read_wired_8021x_tls_blob_connection (void) /* Make sure it's not a path, since it's a blob */ g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, - "*assertion*scheme == NM_SETTING_802_1X_CK_SCHEME_PATH*"); + NMTST_G_RETURN_MSG (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)); tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); g_test_assert_expected_messages (); g_assert (tmp == NULL); diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h index c18fb2bc..85aa5458 100644 --- a/src/settings/plugins/keyfile/utils.h +++ b/src/settings/plugins/keyfile/utils.h @@ -21,7 +21,6 @@ #ifndef _UTILS_H_ #define _UTILS_H_ -#include "nm-default.h" #include "NetworkManagerUtils.h" #define KEYFILE_PLUGIN_NAME "keyfile" diff --git a/src/settings/plugins/keyfile/writer.h b/src/settings/plugins/keyfile/writer.h index 25f44e94..89435651 100644 --- a/src/settings/plugins/keyfile/writer.h +++ b/src/settings/plugins/keyfile/writer.h @@ -24,8 +24,6 @@ #include <nm-connection.h> -#include "nm-default.h" - gboolean nm_keyfile_plugin_write_connection (NMConnection *connection, const char *existing_path, gboolean force_rename, diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c index 5ce8bb31..6283edd6 100644 --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -47,7 +47,6 @@ typedef struct GHashTable *config; GHashTable *blobs; guint32 ap_scan; - NMSettingMacRandomization mac_randomization; gboolean fast_required; gboolean dispose_has_run; } NMSupplicantConfigPrivate; @@ -85,7 +84,6 @@ nm_supplicant_config_init (NMSupplicantConfig * self) (GDestroyNotify) blob_free); priv->ap_scan = 1; - priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; priv->dispose_has_run = FALSE; } @@ -272,32 +270,6 @@ nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self) return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan; } -const char * -nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self) -{ - g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 0); - - /** - * mac_addr - MAC address policy default - * - * 0 = use permanent MAC address - * 1 = use random MAC address for each ESS connection - * 2 = like 1, but maintain OUI (with local admin bit set) - * - * By default, permanent MAC address is used unless policy is changed by - * the per-network mac_addr parameter. - */ - - switch (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->mac_randomization) { - case NM_SETTING_MAC_RANDOMIZATION_ALWAYS: - return "1"; - case NM_SETTING_MAC_RANDOMIZATION_NEVER: - case NM_SETTING_MAC_RANDOMIZATION_DEFAULT: - default: - return "0"; - } -} - gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self) { @@ -385,8 +357,6 @@ gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, NMSettingWireless * setting, guint32 fixed_freq, - NMSupplicantFeature mac_randomization_support, - NMSettingMacRandomization mac_randomization_fallback, GError **error) { NMSupplicantConfigPrivate *priv; @@ -477,23 +447,6 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, } } - priv->mac_randomization = nm_setting_wireless_get_mac_address_randomization (setting); - if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { - priv->mac_randomization = mac_randomization_fallback; - if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { - /* Don't use randomization, unless explicitly enabled. - * Randomization can work badly with captive portals. */ - priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; - } - } - - if ( priv->mac_randomization != NM_SETTING_MAC_RANDOMIZATION_NEVER - && mac_randomization_support != NM_SUPPLICANT_FEATURE_YES) { - g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, - "cannot enable mac-randomization due to missing supplicant support"); - return FALSE; - } - return TRUE; } diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h index 921bc16c..bf3e64c5 100644 --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -25,10 +25,8 @@ #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> #include <nm-setting-8021x.h> -#include "nm-default.h" -#include "nm-supplicant-types.h" -G_BEGIN_DECLS +#include "nm-supplicant-types.h" #define NM_TYPE_SUPPLICANT_CONFIG (nm_supplicant_config_get_type ()) #define NM_SUPPLICANT_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfig)) @@ -54,8 +52,6 @@ NMSupplicantConfig *nm_supplicant_config_new (void); guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self); -const char *nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self); - gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self); GVariant *nm_supplicant_config_to_variant (NMSupplicantConfig *self); @@ -65,8 +61,6 @@ GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self); gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self, NMSettingWireless *setting, guint32 fixed_freq, - NMSupplicantFeature mac_randomization_support, - NMSettingMacRandomization mac_randomization_fallback, GError **error); gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, @@ -86,6 +80,4 @@ gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, gboolean wired, GError **error); -G_END_DECLS - -#endif /* NM_SUPPLICANT_CONFIG_H */ +#endif /* __NETWORKMANAGER_SUPPLICANT_CONFIG_H__ */ diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index ce7a2a2c..626472d0 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -385,10 +385,11 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities) g_return_if_fail (capabilities && g_variant_is_of_type (capabilities, G_VARIANT_TYPE_VARDICT)); - if (g_variant_lookup (capabilities, "Scan", "^a&s", &array)) { - if (_nm_utils_string_in_list ("active", array)) + if ( g_variant_lookup (capabilities, "Scan", "^a&s", &array) + && array) { + if (g_strv_contains (array, "active")) have_active = TRUE; - if (_nm_utils_string_in_list ("ssid", array)) + if (g_strv_contains (array, "ssid")) have_ssid = TRUE; g_free (array); } @@ -502,12 +503,6 @@ nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, priv->ap_support = ap_support; } -NMSupplicantFeature -nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self) -{ - return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->mac_randomization_support; -} - static void set_preassoc_scan_mac_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) { @@ -562,7 +557,7 @@ iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data g_variant_new ("(ssv)", WPAS_DBUS_IFACE_INTERFACE, "PreassocMacAddr", - g_variant_new_string ("1")), + g_variant_new_string ("0")), G_DBUS_CALL_FLAGS_NONE, -1, priv->init_cancellable, @@ -1222,9 +1217,7 @@ set_mac_randomization_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user return; } - _LOGI ("config: set MAC randomization to %s", - nm_supplicant_config_get_mac_randomization (priv->cfg)); - + _LOGT ("config: set MAC randomization to 0"); add_network (self); } @@ -1255,23 +1248,20 @@ set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) nm_supplicant_config_get_ap_scan (priv->cfg)); if (priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_YES) { - const char *mac_randomization = nm_supplicant_config_get_mac_randomization (priv->cfg); - /* Enable/disable association MAC address randomization */ g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", g_variant_new ("(ssv)", WPAS_DBUS_IFACE_INTERFACE, "MacAddr", - g_variant_new_string (mac_randomization)), + g_variant_new_string ("0")), G_DBUS_CALL_FLAGS_NONE, -1, priv->assoc_cancellable, (GAsyncReadyCallback) set_mac_randomization_cb, self); - } else { + } else add_network (self); - } } gboolean diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index dbe77b1c..a586e7ea 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -22,7 +22,6 @@ #ifndef __NETWORKMANAGER_SUPPLICANT_INTERFACE_H__ #define __NETWORKMANAGER_SUPPLICANT_INTERFACE_H__ -#include "nm-default.h" #include "nm-supplicant-types.h" /* @@ -165,6 +164,4 @@ NMSupplicantFeature nm_supplicant_interface_get_ap_support (NMSupplicantInterfac void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, NMSupplicantFeature apmode); -NMSupplicantFeature nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self); - #endif /* NM_SUPPLICANT_INTERFACE_H */ diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index f2c63364..57cd5713 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -194,9 +194,11 @@ update_capabilities (NMSupplicantManager *self) if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { array = g_variant_get_strv (value, NULL); priv->ap_support = NM_SUPPLICANT_FEATURE_NO; - if (_nm_utils_string_in_list ("ap", array)) - priv->ap_support = NM_SUPPLICANT_FEATURE_YES; - g_free (array); + if (array) { + if (g_strv_contains (array, "ap")) + priv->ap_support = NM_SUPPLICANT_FEATURE_YES; + g_free (array); + } } g_variant_unref (value); } @@ -215,9 +217,11 @@ update_capabilities (NMSupplicantManager *self) if (value) { if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { array = g_variant_get_strv (value, NULL); - if (_nm_utils_string_in_list ("fast", array)) - priv->fast_supported = TRUE; - g_free (array); + if (array) { + if (g_strv_contains (array, "fast")) + priv->fast_supported = TRUE; + g_free (array); + } } g_variant_unref (value); } diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h index b0ce6a52..4cd7a0bd 100644 --- a/src/supplicant-manager/nm-supplicant-manager.h +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -22,12 +22,9 @@ #ifndef __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ #define __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ -#include "nm-default.h" #include "nm-supplicant-types.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_SUPPLICANT_MANAGER (nm_supplicant_manager_get_type ()) #define NM_SUPPLICANT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManager)) #define NM_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass)) diff --git a/src/supplicant-manager/tests/Makefile.am b/src/supplicant-manager/tests/Makefile.am index 6672c673..3ab9122e 100644 --- a/src/supplicant-manager/tests/Makefile.am +++ b/src/supplicant-manager/tests/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/supplicant-manager \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - -DTEST_CERT_DIR=\"$(srcdir)/certs/\" \ + -DTEST_CERT_DIR=\"$(abs_srcdir)/certs\" \ $(GLIB_CFLAGS) noinst_PROGRAMS = test-supplicant-config diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in index 7c822d91..bb5efff7 100644 --- a/src/supplicant-manager/tests/Makefile.in +++ b/src/supplicant-manager/tests/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-supplicant-config$(EXEEXT) TESTS = test-supplicant-config$(EXEEXT) subdir = src/supplicant-manager/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -463,6 +464,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -519,13 +521,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -537,6 +540,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -597,6 +602,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -632,6 +639,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -703,7 +711,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/supplicant-manager \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - -DTEST_CERT_DIR=\"$(srcdir)/certs/\" \ + -DTEST_CERT_DIR=\"$(abs_srcdir)/certs\" \ $(GLIB_CFLAGS) test_supplicant_config_SOURCES = \ diff --git a/src/supplicant-manager/tests/certs/Makefile.in b/src/supplicant-manager/tests/certs/Makefile.in index 819f36cc..a1be6bcb 100644 --- a/src/supplicant-manager/tests/certs/Makefile.in +++ b/src/supplicant-manager/tests/certs/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/supplicant-manager/tests/certs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -165,6 +166,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -221,13 +223,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -239,6 +242,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -299,6 +304,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -334,6 +341,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c index 881f44f6..e8f84448 100644 --- a/src/supplicant-manager/tests/test-supplicant-config.c +++ b/src/supplicant-manager/tests/test-supplicant-config.c @@ -35,7 +35,7 @@ #include "nm-supplicant-config.h" #include "nm-supplicant-settings-verify.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static gboolean validate_opt (const char *detail, @@ -160,8 +160,6 @@ test_wifi_open (void) g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0, - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -265,8 +263,6 @@ test_wifi_wep_key (const char *detail, g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0, - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -410,8 +406,6 @@ test_wifi_wpa_psk (const char *detail, g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0, - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -530,9 +524,9 @@ test_wifi_eap (void) s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); nm_connection_add_setting (connection, NM_SETTING (s_8021x)); nm_setting_802_1x_add_eap_method (s_8021x, "tls"); - nm_setting_802_1x_set_client_cert (s_8021x, TEST_CERT_DIR "test-cert.p12", NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); - nm_setting_802_1x_set_ca_cert (s_8021x, TEST_CERT_DIR "test-ca-cert.pem", NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); - nm_setting_802_1x_set_private_key (s_8021x, TEST_CERT_DIR "test-cert.p12", NULL, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); + nm_setting_802_1x_set_client_cert (s_8021x, TEST_CERT_DIR "/test-cert.p12", NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); + nm_setting_802_1x_set_ca_cert (s_8021x, TEST_CERT_DIR "/test-ca-cert.pem", NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); + nm_setting_802_1x_set_private_key (s_8021x, TEST_CERT_DIR "/test-cert.p12", NULL, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, NULL); /* IP4 setting */ s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); @@ -557,8 +551,6 @@ test_wifi_eap (void) g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0, - NM_SUPPLICANT_FEATURE_UNKNOWN, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); diff --git a/src/systemd/nm-sd.c b/src/systemd/nm-sd.c index 4d596020..43ae0a8b 100644 --- a/src/systemd/nm-sd.c +++ b/src/systemd/nm-sd.c @@ -134,3 +134,10 @@ nm_sd_event_attach_default (void) /*****************************************************************************/ +/* ensure that defines in nm-sd.h correspond to the internal defines. */ + +#include "nm-sd-adapt.h" +#include "dhcp-lease-internal.h" + +/*****************************************************************************/ + diff --git a/src/systemd/nm-sd.h b/src/systemd/nm-sd.h index 888d44ab..f07a7082 100644 --- a/src/systemd/nm-sd.h +++ b/src/systemd/nm-sd.h @@ -21,5 +21,16 @@ guint nm_sd_event_attach_default (void); +/***************************************************************************** + * expose internal systemd API + * + * FIXME: don't use any internal systemd API. + *****************************************************************************/ + +struct sd_dhcp_lease; + +int dhcp_lease_save(struct sd_dhcp_lease *lease, const char *lease_file); +int dhcp_lease_load(struct sd_dhcp_lease **ret, const char *lease_file); + #endif /* __NM_SD_H__ */ diff --git a/src/systemd/sd-adapt/build.h b/src/systemd/sd-adapt/build.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/build.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/cgroup-util.h b/src/systemd/sd-adapt/cgroup-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/cgroup-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/condition.h b/src/systemd/sd-adapt/condition.h new file mode 100644 index 00000000..d3a6812a --- /dev/null +++ b/src/systemd/sd-adapt/condition.h @@ -0,0 +1,5 @@ +#pragma once + +/* dummy header */ + +typedef struct _sd_adapt_Condition Condition; diff --git a/src/systemd/sd-adapt/conf-parser.h b/src/systemd/sd-adapt/conf-parser.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/conf-parser.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/def.h b/src/systemd/sd-adapt/def.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/def.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/dirent-util.h b/src/systemd/sd-adapt/dirent-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/dirent-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/formats-util.h b/src/systemd/sd-adapt/formats-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/formats-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/gunicode.h b/src/systemd/sd-adapt/gunicode.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/gunicode.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/libudev.h b/src/systemd/sd-adapt/libudev.h new file mode 100644 index 00000000..8c49f075 --- /dev/null +++ b/src/systemd/sd-adapt/libudev.h @@ -0,0 +1,5 @@ +#pragma once + +/* dummy header */ + +struct udev_device; diff --git a/src/systemd/sd-adapt/missing.h b/src/systemd/sd-adapt/missing.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/missing.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/mkdir.h b/src/systemd/sd-adapt/mkdir.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/mkdir.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/nm-sd-adapt.c b/src/systemd/sd-adapt/nm-sd-adapt.c index 4e308276..4e308276 100644 --- a/src/systemd/nm-sd-adapt.c +++ b/src/systemd/sd-adapt/nm-sd-adapt.c diff --git a/src/systemd/nm-sd-adapt.h b/src/systemd/sd-adapt/nm-sd-adapt.h index 010c8a80..cf27c1af 100644 --- a/src/systemd/nm-sd-adapt.h +++ b/src/systemd/sd-adapt/nm-sd-adapt.h @@ -140,8 +140,12 @@ sd_notify (int unset_environment, const char *state) } /* Can't include both net/if.h and linux/if.h; so have to define this here */ +#ifndef IF_NAMESIZE +#define IF_NAMESIZE 16 +#endif + #ifndef IFNAMSIZ -#define IFNAMSIZ 16 +#define IFNAMSIZ IF_NAMESIZE #endif #ifndef MAX_HANDLE_SZ diff --git a/src/systemd/sd-adapt/process-util.h b/src/systemd/sd-adapt/process-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/process-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/sd-daemon.h b/src/systemd/sd-adapt/sd-daemon.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/sd-daemon.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/stat-util.h b/src/systemd/sd-adapt/stat-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/stat-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/udev-util.h b/src/systemd/sd-adapt/udev-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/udev-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/udev.h b/src/systemd/sd-adapt/udev.h new file mode 100644 index 00000000..00f60f92 --- /dev/null +++ b/src/systemd/sd-adapt/udev.h @@ -0,0 +1,5 @@ +#pragma once + +/* dummy header */ + +#include "libudev.h" diff --git a/src/systemd/sd-adapt/user-util.h b/src/systemd/sd-adapt/user-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/user-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/virt.h b/src/systemd/sd-adapt/virt.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/virt.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/src/basic/escape.h b/src/systemd/src/basic/escape.h index b8ec96ad..24729dc1 100644 --- a/src/systemd/src/basic/escape.h +++ b/src/systemd/src/basic/escape.h @@ -28,9 +28,7 @@ #endif /* NM_IGNORED */ #include "string-util.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ /* What characters are special in the shell? */ /* must be escaped outside and inside double-quotes */ diff --git a/src/systemd/src/basic/ether-addr-util.c b/src/systemd/src/basic/ether-addr-util.c index 0219300d..a793219c 100644 --- a/src/systemd/src/basic/ether-addr-util.c +++ b/src/systemd/src/basic/ether-addr-util.c @@ -25,6 +25,7 @@ #include "ether-addr-util.h" #include "macro.h" +#include "string-util.h" char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) { assert(addr); @@ -56,3 +57,71 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) { a->ether_addr_octet[4] == b->ether_addr_octet[4] && a->ether_addr_octet[5] == b->ether_addr_octet[5]; } + +int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) { + size_t pos = 0, n, field; + char sep = '\0'; + const char *hex = HEXDIGITS, *hexoff; + size_t x; + bool touched; + +#define parse_fields(v) \ + for (field = 0; field < ELEMENTSOF(v); field++) { \ + touched = false; \ + for (n = 0; n < (2 * sizeof(v[0])); n++) { \ + if (s[pos] == '\0') \ + break; \ + hexoff = strchr(hex, s[pos]); \ + if (hexoff == NULL) \ + break; \ + assert(hexoff >= hex); \ + x = hexoff - hex; \ + if (x >= 16) \ + x -= 6; /* A-F */ \ + assert(x < 16); \ + touched = true; \ + v[field] <<= 4; \ + v[field] += x; \ + pos++; \ + } \ + if (!touched) \ + return -EINVAL; \ + if (field < (ELEMENTSOF(v)-1)) { \ + if (s[pos] != sep) \ + return -EINVAL; \ + else \ + pos++; \ + } \ + } + + assert(s); + assert(ret); + + sep = s[strspn(s, hex)]; + if (sep == '\n') + return -EINVAL; + if (strchr(":.-", sep) == NULL) + return -EINVAL; + + if (sep == '.') { + uint16_t shorts[3] = { 0 }; + + parse_fields(shorts); + + for (n = 0; n < ELEMENTSOF(shorts); n++) { + ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8); + ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff); + } + } else { + struct ether_addr out = { .ether_addr_octet = { 0 } }; + + parse_fields(out.ether_addr_octet); + + for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++) + ret->ether_addr_octet[n] = out.ether_addr_octet[n]; + } + + if (offset) + *offset = pos; + return 0; +} diff --git a/src/systemd/src/basic/ether-addr-util.h b/src/systemd/src/basic/ether-addr-util.h index 07436379..74e125a9 100644 --- a/src/systemd/src/basic/ether-addr-util.h +++ b/src/systemd/src/basic/ether-addr-util.h @@ -35,3 +35,5 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b); static inline bool ether_addr_is_null(const struct ether_addr *addr) { return ether_addr_equal(addr, ÐER_ADDR_NULL); } + +int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset); diff --git a/src/systemd/src/basic/extract-word.c b/src/systemd/src/basic/extract-word.c new file mode 100644 index 00000000..eb54daa3 --- /dev/null +++ b/src/systemd/src/basic/extract-word.c @@ -0,0 +1,302 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "nm-sd-adapt.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> + +#include "alloc-util.h" +#include "escape.h" +#include "extract-word.h" +#include "log.h" +#include "macro.h" +#include "string-util.h" +#include "utf8.h" + +int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) { + _cleanup_free_ char *s = NULL; + size_t allocated = 0, sz = 0; + char c; + int r; + + char quote = 0; /* 0 or ' or " */ + bool backslash = false; /* whether we've just seen a backslash */ + + assert(p); + assert(ret); + + /* Bail early if called after last value or with no input */ + if (!*p) + goto finish_force_terminate; + c = **p; + + if (!separators) + separators = WHITESPACE; + + /* Parses the first word of a string, and returns it in + * *ret. Removes all quotes in the process. When parsing fails + * (because of an uneven number of quotes or similar), leaves + * the pointer *p at the first invalid character. */ + + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) + if (!GREEDY_REALLOC(s, allocated, sz+1)) + return -ENOMEM; + + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + else if (strchr(separators, c)) { + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { + (*p)++; + goto finish_force_next; + } + } else { + /* We found a non-blank character, so we will always + * want to return a string (even if it is empty), + * allocate it here. */ + if (!GREEDY_REALLOC(s, allocated, sz+1)) + return -ENOMEM; + break; + } + } + + for (;; (*p)++, c = **p) { + if (backslash) { + if (!GREEDY_REALLOC(s, allocated, sz+7)) + return -ENOMEM; + + if (c == 0) { + if ((flags & EXTRACT_CUNESCAPE_RELAX) && + (!quote || flags & EXTRACT_RELAX)) { + /* If we find an unquoted trailing backslash and we're in + * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the + * output. + * + * Unbalanced quotes will only be allowed in EXTRACT_RELAX + * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them. + */ + s[sz++] = '\\'; + goto finish_force_terminate; + } + if (flags & EXTRACT_RELAX) + goto finish_force_terminate; + return -EINVAL; + } + + if (flags & EXTRACT_CUNESCAPE) { + bool eight_bit = false; + char32_t u; + + r = cunescape_one(*p, (size_t) -1, &u, &eight_bit); + if (r < 0) { + if (flags & EXTRACT_CUNESCAPE_RELAX) { + s[sz++] = '\\'; + s[sz++] = c; + } else + return -EINVAL; + } else { + (*p) += r - 1; + + if (eight_bit) + s[sz++] = u; + else + sz += utf8_encode_unichar(s + sz, u); + } + } else + s[sz++] = c; + + backslash = false; + + } else if (quote) { /* inside either single or double quotes */ + for (;; (*p)++, c = **p) { + if (c == 0) { + if (flags & EXTRACT_RELAX) + goto finish_force_terminate; + return -EINVAL; + } else if (c == quote) { /* found the end quote */ + quote = 0; + break; + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { + backslash = true; + break; + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + } + + } else { + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) { + quote = c; + break; + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { + backslash = true; + break; + } else if (strchr(separators, c)) { + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { + (*p)++; + goto finish_force_next; + } + /* Skip additional coalesced separators. */ + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + if (!strchr(separators, c)) + break; + } + goto finish; + + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + } + } + } + +finish_force_terminate: + *p = NULL; +finish: + if (!s) { + *p = NULL; + *ret = NULL; + return 0; + } + +finish_force_next: + s[sz] = 0; + *ret = s; + s = NULL; + + return 1; +} + +#if 0 /* NM_IGNORED */ +int extract_first_word_and_warn( + const char **p, + char **ret, + const char *separators, + ExtractFlags flags, + const char *unit, + const char *filename, + unsigned line, + const char *rvalue) { + + /* Try to unquote it, if it fails, warn about it and try again + * but this time using EXTRACT_CUNESCAPE_RELAX to keep the + * backslashes verbatim in invalid escape sequences. */ + + const char *save; + int r; + + save = *p; + r = extract_first_word(p, ret, separators, flags); + if (r >= 0) + return r; + + if (r == -EINVAL && !(flags & EXTRACT_CUNESCAPE_RELAX)) { + + /* Retry it with EXTRACT_CUNESCAPE_RELAX. */ + *p = save; + r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX); + if (r >= 0) { + /* It worked this time, hence it must have been an invalid escape sequence we could correct. */ + log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Invalid escape sequences in line, correcting: \"%s\"", rvalue); + return r; + } + + /* If it's still EINVAL; then it must be unbalanced quoting, report this. */ + if (r == -EINVAL) + return log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting, ignoring: \"%s\"", rvalue); + } + + /* Can be any error, report it */ + return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue); +} + +int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) { + va_list ap; + char **l; + int n = 0, i, c, r; + + /* Parses a number of words from a string, stripping any + * quotes if necessary. */ + + assert(p); + + /* Count how many words are expected */ + va_start(ap, flags); + for (;;) { + if (!va_arg(ap, char **)) + break; + n++; + } + va_end(ap); + + if (n <= 0) + return 0; + + /* Read all words into a temporary array */ + l = newa0(char*, n); + for (c = 0; c < n; c++) { + + r = extract_first_word(p, &l[c], separators, flags); + if (r < 0) { + int j; + + for (j = 0; j < c; j++) + free(l[j]); + + return r; + } + + if (r == 0) + break; + } + + /* If we managed to parse all words, return them in the passed + * in parameters */ + va_start(ap, flags); + for (i = 0; i < n; i++) { + char **v; + + v = va_arg(ap, char **); + assert(v); + + *v = l[i]; + } + va_end(ap); + + return c; +} +#endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/extract-word.h b/src/systemd/src/basic/extract-word.h new file mode 100644 index 00000000..21db5ef3 --- /dev/null +++ b/src/systemd/src/basic/extract-word.h @@ -0,0 +1,35 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "macro.h" + +typedef enum ExtractFlags { + EXTRACT_RELAX = 1, + EXTRACT_CUNESCAPE = 2, + EXTRACT_CUNESCAPE_RELAX = 4, + EXTRACT_QUOTES = 8, + EXTRACT_DONT_COALESCE_SEPARATORS = 16, + EXTRACT_RETAIN_ESCAPE = 32, +} ExtractFlags; + +int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); +int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue); +int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_; diff --git a/src/systemd/src/basic/fd-util.c b/src/systemd/src/basic/fd-util.c index e92b3740..c518f757 100644 --- a/src/systemd/src/basic/fd-util.c +++ b/src/systemd/src/basic/fd-util.c @@ -27,13 +27,13 @@ #include <unistd.h> #include "fd-util.h" +#include "fs-util.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #include "parse-util.h" #include "path-util.h" #include "socket-util.h" +#include "stdio-util.h" #include "util.h" int close_nointr(int fd) { @@ -189,6 +189,12 @@ int fd_cloexec(int fd, bool cloexec) { } #if 0 /* NM_IGNORED */ +void stdio_unset_cloexec(void) { + fd_cloexec(STDIN_FILENO, false); + fd_cloexec(STDOUT_FILENO, false); + fd_cloexec(STDERR_FILENO, false); +} + _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { unsigned i; @@ -234,7 +240,7 @@ int close_all_fds(const int except[], unsigned n_except) { while ((de = readdir(d))) { int fd = -1; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; if (safe_atoi(de->d_name, &fd) < 0) @@ -362,3 +368,17 @@ bool fdname_is_valid(const char *s) { return p - s < 256; } + +int fd_get_path(int fd, char **ret) { + char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + int r; + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + + r = readlink_malloc(procfs_path, ret); + + if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */ + return -EBADF; + + return r; +} diff --git a/src/systemd/src/basic/fd-util.h b/src/systemd/src/basic/fd-util.h index 44528c6e..34b98d4a 100644 --- a/src/systemd/src/basic/fd-util.h +++ b/src/systemd/src/basic/fd-util.h @@ -63,6 +63,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir); int fd_nonblock(int fd, bool nonblock); int fd_cloexec(int fd, bool cloexec); +void stdio_unset_cloexec(void); int close_all_fds(const int except[], unsigned n_except); @@ -72,6 +73,8 @@ void cmsg_close_all(struct msghdr *mh); bool fdname_is_valid(const char *s); +int fd_get_path(int fd, char **ret); + /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */ #define ERRNO_IS_DISCONNECT(r) \ IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH) diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index e940e10e..b2fe15ca 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -49,6 +49,8 @@ #include "umask-util.h" #include "utf8.h" +#define READ_FULL_BYTES_MAX (4U*1024U*1024U) + int write_string_stream(FILE *f, const char *line, bool enforce_newline) { assert(f); @@ -232,7 +234,7 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { if (S_ISREG(st.st_mode)) { /* Safety check */ - if (st.st_size > 4*1024*1024) + if (st.st_size > READ_FULL_BYTES_MAX) return -E2BIG; /* Start with the right file size, but be prepared for @@ -247,26 +249,31 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { char *t; size_t k; - t = realloc(buf, n+1); + t = realloc(buf, n + 1); if (!t) return -ENOMEM; buf = t; k = fread(buf + l, 1, n - l, f); + if (k > 0) + l += k; - if (k <= 0) { - if (ferror(f)) - return -errno; + if (ferror(f)) + return -errno; + if (feof(f)) break; - } - l += k; - n *= 2; + /* We aren't expecting fread() to return a short read outside + * of (error && eof), assert buffer is full and enlarge buffer. + */ + assert(l == n); /* Safety check */ - if (n > 4*1024*1024) + if (n >= READ_FULL_BYTES_MAX) return -E2BIG; + + n = MIN(n * 2, READ_FULL_BYTES_MAX); } buf[l] = 0; @@ -1071,7 +1078,7 @@ int fflush_and_check(FILE *f) { return 0; } -/* This is much like like mkostemp() but is subject to umask(). */ +/* This is much like mkostemp() but is subject to umask(). */ int mkostemp_safe(char *pattern, int flags) { _cleanup_umask_ mode_t u = 0; int fd; @@ -1087,30 +1094,6 @@ int mkostemp_safe(char *pattern, int flags) { return fd; } -int open_tmpfile(const char *path, int flags) { - char *p; - int fd; - - assert(path); - -#ifdef O_TMPFILE - /* Try O_TMPFILE first, if it is supported */ - fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR); - if (fd >= 0) - return fd; -#endif - - /* Fall back to unguessable name + unlinking */ - p = strjoina(path, "/systemd-tmp-XXXXXX"); - - fd = mkostemp_safe(p, flags); - if (fd < 0) - return fd; - - unlink(p); - return fd; -} - int tempfn_xxxxxx(const char *p, const char *extra, char **ret) { const char *fn; char *t; @@ -1185,12 +1168,13 @@ int tempfn_random(const char *p, const char *extra, char **ret) { return 0; } +#if 0 /* NM_IGNORED */ int tempfn_random_child(const char *p, const char *extra, char **ret) { char *t, *x; uint64_t u; unsigned i; + int r; - assert(p); assert(ret); /* Turns this: @@ -1199,6 +1183,12 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0 */ + if (!p) { + r = tmp_dir(&p); + if (r < 0) + return r; + } + if (!extra) extra = ""; @@ -1220,7 +1210,6 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { return 0; } -#if 0 /* NM_IGNORED */ int write_timestamp_file_atomic(const char *fn, usec_t n) { char ln[DECIMAL_STR_MAX(n)+2]; @@ -1234,7 +1223,6 @@ int write_timestamp_file_atomic(const char *fn, usec_t n) { return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); } -#endif /* NM_IGNORED */ int read_timestamp_file(const char *fn, usec_t *ret) { _cleanup_free_ char *ln = NULL; @@ -1255,6 +1243,7 @@ int read_timestamp_file(const char *fn, usec_t *ret) { *ret = (usec_t) t; return 0; } +#endif /* NM_IGNORED */ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) { int r; @@ -1284,3 +1273,150 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) return fputs(s, f); } + +#if 0 /* NM_IGNORED */ +int open_tmpfile_unlinkable(const char *directory, int flags) { + char *p; + int fd, r; + + if (!directory) { + r = tmp_dir(&directory); + if (r < 0) + return r; + } + + /* Returns an unlinked temporary file that cannot be linked into the file system anymore */ + +#ifdef O_TMPFILE + /* Try O_TMPFILE first, if it is supported */ + fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR); + if (fd >= 0) + return fd; +#endif + + /* Fall back to unguessable name + unlinking */ + p = strjoina(directory, "/systemd-tmp-XXXXXX"); + + fd = mkostemp_safe(p, flags); + if (fd < 0) + return fd; + + (void) unlink(p); + + return fd; +} + +int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { + _cleanup_free_ char *tmp = NULL; + int r, fd; + + assert(target); + assert(ret_path); + + /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */ + assert((flags & O_EXCL) == 0); + + /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in + * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in + * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */ + +#ifdef O_TMPFILE + { + _cleanup_free_ char *dn = NULL; + + dn = dirname_malloc(target); + if (!dn) + return -ENOMEM; + + fd = open(dn, O_TMPFILE|flags, 0640); + if (fd >= 0) { + *ret_path = NULL; + return fd; + } + + log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn); + } +#endif + + r = tempfn_random(target, NULL, &tmp); + if (r < 0) + return r; + + fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640); + if (fd < 0) + return -errno; + + *ret_path = tmp; + tmp = NULL; + + return fd; +} + +int link_tmpfile(int fd, const char *path, const char *target) { + + assert(fd >= 0); + assert(target); + + /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd + * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported + * on the directory, and renameat2() is used instead. + * + * Note that in both cases we will not replace existing files. This is because linkat() does not support this + * operation currently (renameat2() does), and there is no nice way to emulate this. */ + + if (path) { + if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0) + return -errno; + } else { + char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1]; + + xsprintf(proc_fd_path, "/proc/self/fd/%i", fd); + + if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0) + return -errno; + } + + return 0; +} + +int read_nul_string(FILE *f, char **ret) { + _cleanup_free_ char *x = NULL; + size_t allocated = 0, n = 0; + + assert(f); + assert(ret); + + /* Reads a NUL-terminated string from the specified file. */ + + for (;;) { + int c; + + if (!GREEDY_REALLOC(x, allocated, n+2)) + return -ENOMEM; + + c = fgetc(f); + if (c == 0) /* Terminate at NUL byte */ + break; + if (c == EOF) { + if (ferror(f)) + return -errno; + break; /* Terminate at EOF */ + } + + x[n++] = (char) c; + } + + if (x) + x[n] = 0; + else { + x = new0(char, 1); + if (!x) + return -ENOMEM; + } + + *ret = x; + x = NULL; + + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h index 8084895f..9ac497d9 100644 --- a/src/systemd/src/basic/fileio.h +++ b/src/systemd/src/basic/fileio.h @@ -72,7 +72,6 @@ int fflush_and_check(FILE *f); int fopen_temporary(const char *path, FILE **_f, char **_temp_path); int mkostemp_safe(char *pattern, int flags); -int open_tmpfile(const char *path, int flags); int tempfn_xxxxxx(const char *p, const char *extra, char **ret); int tempfn_random(const char *p, const char *extra, char **ret); @@ -82,3 +81,10 @@ int write_timestamp_file_atomic(const char *fn, usec_t n); int read_timestamp_file(const char *fn, usec_t *ret); int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space); + +int open_tmpfile_unlinkable(const char *directory, int flags); +int open_tmpfile_linkable(const char *target, int flags, char **ret_path); + +int link_tmpfile(int fd, const char *path, const char *target); + +int read_nul_string(FILE *f, char **ret); diff --git a/src/systemd/src/basic/fs-util.c b/src/systemd/src/basic/fs-util.c index 9a843644..de0cd8fb 100644 --- a/src/systemd/src/basic/fs-util.c +++ b/src/systemd/src/basic/fs-util.c @@ -30,26 +30,22 @@ #include <unistd.h> #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "dirent-util.h" -#endif /* NM_IGNORED */ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" #include "log.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" #include "mkdir.h" -#endif /* NM_IGNORED */ #include "parse-util.h" #include "path-util.h" +#include "stat-util.h" +#include "stdio-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" -#if 0 /* NM_IGNORED */ #include "user-util.h" -#endif /* NM_IGNORED */ #include "util.h" int unlink_noerrno(const char *path) { @@ -151,6 +147,7 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char return 0; } +#endif /* NM_IGNORED */ int readlinkat_malloc(int fd, const char *p, char **ret) { size_t l = 100; @@ -189,6 +186,7 @@ int readlink_malloc(const char *p, char **ret) { return readlinkat_malloc(AT_FDCWD, p, ret); } +#if 0 /* NM_IGNORED */ int readlink_value(const char *p, char **ret) { _cleanup_free_ char *link = NULL; char *value; @@ -504,4 +502,106 @@ int get_files_in_directory(const char *path, char ***list) { return n; } + +static int getenv_tmp_dir(const char **ret_path) { + const char *n; + int r, ret = 0; + + assert(ret_path); + + /* We use the same order of environment variables python uses in tempfile.gettempdir(): + * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */ + FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") { + const char *e; + + e = secure_getenv(n); + if (!e) + continue; + if (!path_is_absolute(e)) { + r = -ENOTDIR; + goto next; + } + if (!path_is_safe(e)) { + r = -EPERM; + goto next; + } + + r = is_dir(e, true); + if (r < 0) + goto next; + if (r == 0) { + r = -ENOTDIR; + goto next; + } + + *ret_path = e; + return 1; + + next: + /* Remember first error, to make this more debuggable */ + if (ret >= 0) + ret = r; + } + + if (ret < 0) + return ret; + + *ret_path = NULL; + return ret; +} + +static int tmp_dir_internal(const char *def, const char **ret) { + const char *e; + int r, k; + + assert(def); + assert(ret); + + r = getenv_tmp_dir(&e); + if (r > 0) { + *ret = e; + return 0; + } + + k = is_dir(def, true); + if (k == 0) + k = -ENOTDIR; + if (k < 0) + return r < 0 ? r : k; + + *ret = def; + return 0; +} + +int var_tmp_dir(const char **ret) { + + /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus + * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is + * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR, + * making it a variable that overrides all temporary file storage locations. */ + + return tmp_dir_internal("/var/tmp", ret); +} + +int tmp_dir(const char **ret) { + + /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually + * backed by an in-memory file system: /tmp. */ + + return tmp_dir_internal("/tmp", ret); +} + +int inotify_add_watch_fd(int fd, int what, uint32_t mask) { + char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + int r; + + /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */ + xsprintf(path, "/proc/self/fd/%i", what); + + r = inotify_add_watch(fd, path, mask); + if (r < 0) + return -errno; + + return r; +} #endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/fs-util.h b/src/systemd/src/basic/fs-util.h index 0d23f863..2c3b9a1c 100644 --- a/src/systemd/src/basic/fs-util.h +++ b/src/systemd/src/basic/fs-util.h @@ -61,6 +61,9 @@ int mkfifo_atomic(const char *path, mode_t mode); int get_files_in_directory(const char *path, char ***list); +int tmp_dir(const char **ret); +int var_tmp_dir(const char **ret); + #define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1) #define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ @@ -72,3 +75,5 @@ union inotify_event_buffer { struct inotify_event ev; uint8_t raw[INOTIFY_EVENT_MAX]; }; + +int inotify_add_watch_fd(int fd, int what, uint32_t mask); diff --git a/src/systemd/src/basic/hashmap.c b/src/systemd/src/basic/hashmap.c index 4df3ae73..dc6bcab0 100644 --- a/src/systemd/src/basic/hashmap.c +++ b/src/systemd/src/basic/hashmap.c @@ -29,9 +29,7 @@ #include "hashmap.h" #include "macro.h" #include "mempool.h" -#if 0 /* NM_IGNORED */ #include "process-util.h" -#endif /* NM_IGNORED */ #include "random-util.h" #include "set.h" #include "siphash24.h" @@ -1768,6 +1766,9 @@ void *ordered_hashmap_next(OrderedHashmap *h, const void *key) { int set_consume(Set *s, void *value) { int r; + assert(s); + assert(value); + r = set_put(s, value); if (r <= 0) free(value); @@ -1777,26 +1778,26 @@ int set_consume(Set *s, void *value) { int set_put_strdup(Set *s, const char *p) { char *c; - int r; assert(s); assert(p); + if (set_contains(s, (char*) p)) + return 0; + c = strdup(p); if (!c) return -ENOMEM; - r = set_consume(s, c); - if (r == -EEXIST) - return 0; - - return r; + return set_consume(s, c); } int set_put_strdupv(Set *s, char **l) { int n = 0, r; char **i; + assert(s); + STRV_FOREACH(i, l) { r = set_put_strdup(s, *i); if (r < 0) @@ -1807,3 +1808,23 @@ int set_put_strdupv(Set *s, char **l) { return n; } + +int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags) { + const char *p = v; + int r; + + assert(s); + assert(v); + + for (;;) { + char *word; + + r = extract_first_word(&p, &word, separators, flags); + if (r <= 0) + return r; + + r = set_consume(s, word); + if (r < 0) + return r; + } +} diff --git a/src/systemd/src/basic/hostname-util.c b/src/systemd/src/basic/hostname-util.c index ee48b86d..480f9d9d 100644 --- a/src/systemd/src/basic/hostname-util.c +++ b/src/systemd/src/basic/hostname-util.c @@ -180,16 +180,16 @@ bool is_localhost(const char *hostname) { assert(hostname); /* This tries to identify local host and domain names - * described in RFC6761 plus the redhatism of .localdomain */ + * described in RFC6761 plus the redhatism of localdomain */ return strcaseeq(hostname, "localhost") || strcaseeq(hostname, "localhost.") || - strcaseeq(hostname, "localdomain.") || - strcaseeq(hostname, "localdomain") || + strcaseeq(hostname, "localhost.localdomain") || + strcaseeq(hostname, "localhost.localdomain.") || endswith_no_case(hostname, ".localhost") || endswith_no_case(hostname, ".localhost.") || - endswith_no_case(hostname, ".localdomain") || - endswith_no_case(hostname, ".localdomain."); + endswith_no_case(hostname, ".localhost.localdomain") || + endswith_no_case(hostname, ".localhost.localdomain."); } #if 0 /* NM_IGNORED */ diff --git a/src/systemd/src/basic/in-addr-util.c b/src/systemd/src/basic/in-addr-util.c index 10898dae..95230e7d 100644 --- a/src/systemd/src/basic/in-addr-util.c +++ b/src/systemd/src/basic/in-addr-util.c @@ -22,26 +22,36 @@ #include <arpa/inet.h> #include <endian.h> #include <errno.h> +#include <net/if.h> #include <stdint.h> #include <stdlib.h> #include "alloc-util.h" #include "in-addr-util.h" #include "macro.h" +#include "parse-util.h" #include "util.h" +bool in4_addr_is_null(const struct in_addr *a) { + return a->s_addr == 0; +} + +bool in6_addr_is_null(const struct in6_addr *a) { + return + a->s6_addr32[0] == 0 && + a->s6_addr32[1] == 0 && + a->s6_addr32[2] == 0 && + a->s6_addr32[3] == 0; +} + int in_addr_is_null(int family, const union in_addr_union *u) { assert(u); if (family == AF_INET) - return u->in.s_addr == 0; + return in4_addr_is_null(&u->in); if (family == AF_INET6) - return - u->in6.s6_addr32[0] == 0 && - u->in6.s6_addr32[1] == 0 && - u->in6.s6_addr32[2] == 0 && - u->in6.s6_addr32[3] == 0; + return in6_addr_is_null(&u->in6); return -EAFNOSUPPORT; } @@ -226,6 +236,48 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { return 0; } +int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) { + size_t l; + char *x; + int r; + + assert(u); + assert(ret); + + /* Much like in_addr_to_string(), but optionally appends the zone interface index to the address, to properly + * handle IPv6 link-local addresses. */ + + if (family != AF_INET6) + goto fallback; + if (ifindex <= 0) + goto fallback; + + r = in_addr_is_link_local(family, u); + if (r < 0) + return r; + if (r == 0) + goto fallback; + + l = INET6_ADDRSTRLEN + 1 + DECIMAL_STR_MAX(ifindex) + 1; + x = new(char, l); + if (!x) + return -ENOMEM; + + errno = 0; + if (!inet_ntop(family, u, x, l)) { + free(x); + return errno > 0 ? -errno : -EINVAL; + } + + sprintf(strchr(x, 0), "%%%i", ifindex); + *ret = x; + + return 0; + +fallback: + return in_addr_to_string(family, u, ret); +} + int in_addr_from_string(int family, const char *s, union in_addr_union *ret) { assert(s); @@ -263,6 +315,47 @@ int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *re return -EINVAL; } +int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex) { + const char *suffix; + int r, ifi = 0; + + assert(s); + assert(family); + assert(ret); + + /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id") + * if one is found. */ + + suffix = strchr(s, '%'); + if (suffix) { + + if (ifindex) { + /* If we shall return the interface index, try to parse it */ + r = parse_ifindex(suffix + 1, &ifi); + if (r < 0) { + unsigned u; + + u = if_nametoindex(suffix + 1); + if (u <= 0) + return -errno; + + ifi = (int) u; + } + } + + s = strndupa(s, suffix - s); + } + + r = in_addr_from_string_auto(s, family, ret); + if (r < 0) + return r; + + if (ifindex) + *ifindex = ifi; + + return r; +} + unsigned char in_addr_netmask_to_prefixlen(const struct in_addr *addr) { assert(addr); diff --git a/src/systemd/src/basic/in-addr-util.h b/src/systemd/src/basic/in-addr-util.h index 17798ce8..d60064ae 100644 --- a/src/systemd/src/basic/in-addr-util.h +++ b/src/systemd/src/basic/in-addr-util.h @@ -36,6 +36,9 @@ struct in_addr_data { union in_addr_union address; }; +bool in4_addr_is_null(const struct in_addr *a); +bool in6_addr_is_null(const struct in6_addr *a); + int in_addr_is_null(int family, const union in_addr_union *u); int in_addr_is_link_local(int family, const union in_addr_union *u); int in_addr_is_localhost(int family, const union in_addr_union *u); @@ -43,8 +46,10 @@ int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_ int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); int in_addr_to_string(int family, const union in_addr_union *u, char **ret); +int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret); int in_addr_from_string(int family, const char *s, union in_addr_union *ret); int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret); +int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex); unsigned char in_addr_netmask_to_prefixlen(const struct in_addr *addr); struct in_addr* in_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen); int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); diff --git a/src/systemd/src/basic/io-util.c b/src/systemd/src/basic/io-util.c index aaf414f4..61b667f0 100644 --- a/src/systemd/src/basic/io-util.c +++ b/src/systemd/src/basic/io-util.c @@ -35,6 +35,11 @@ int flush_fd(int fd) { .events = POLLIN, }; + /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything + * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read + * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used + * was set to non-blocking too. */ + for (;;) { char buf[LINE_MAX]; ssize_t l; diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h index d6a877ea..7db87b49 100644 --- a/src/systemd/src/basic/macro.h +++ b/src/systemd/src/basic/macro.h @@ -98,6 +98,15 @@ #define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq)) #define UNIQ __COUNTER__ +/* builtins */ +#if __SIZEOF_INT__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffs(x); +#elif __SIZEOF_LONG__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffsl(x); +#else +#error "neither int nor long are four bytes long?!?" +#endif + /* Rounds up */ #define ALIGN4(l) (((l) + 3) & ~3) diff --git a/src/systemd/src/basic/parse-util.c b/src/systemd/src/basic/parse-util.c index eb53c42d..27386631 100644 --- a/src/systemd/src/basic/parse-util.c +++ b/src/systemd/src/basic/parse-util.c @@ -28,11 +28,10 @@ #include <xlocale.h> #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "extract-word.h" -#endif /* NM_IGNORED */ #include "macro.h" #include "parse-util.h" +#include "process-util.h" #include "string-util.h" int parse_boolean(const char *v) { @@ -538,3 +537,46 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { return 0; } + +int parse_percent_unbounded(const char *p) { + const char *pc, *n; + unsigned v; + int r; + + pc = endswith(p, "%"); + if (!pc) + return -EINVAL; + + n = strndupa(p, pc - p); + r = safe_atou(n, &v); + if (r < 0) + return r; + + return (int) v; +} + +int parse_percent(const char *p) { + int v; + + v = parse_percent_unbounded(p); + if (v > 100) + return -ERANGE; + + return v; +} + +#if 0 /* NM_IGNORED */ +int parse_nice(const char *p, int *ret) { + int n, r; + + r = safe_atoi(p, &n); + if (r < 0) + return r; + + if (!nice_is_valid(n)) + return -ERANGE; + + *ret = n; + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/parse-util.h b/src/systemd/src/basic/parse-util.h index d8dc26a3..461e1cd4 100644 --- a/src/systemd/src/basic/parse-util.h +++ b/src/systemd/src/basic/parse-util.h @@ -90,6 +90,23 @@ static inline int safe_atoli(const char *s, long int *ret_u) { } #endif +#if SIZE_MAX == UINT_MAX +static inline int safe_atozu(const char *s, size_t *ret_u) { + assert_cc(sizeof(size_t) == sizeof(unsigned)); + return safe_atou(s, (unsigned *) ret_u); +} +#else +static inline int safe_atozu(const char *s, size_t *ret_u) { + assert_cc(sizeof(size_t) == sizeof(long unsigned)); + return safe_atolu(s, ret_u); +} +#endif + int safe_atod(const char *s, double *ret_d); int parse_fractional_part_u(const char **s, size_t digits, unsigned *res); + +int parse_percent_unbounded(const char *p); +int parse_percent(const char *p); + +int parse_nice(const char *p, int *ret); diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c index c3b7d187..86d35bbe 100644 --- a/src/systemd/src/basic/path-util.c +++ b/src/systemd/src/basic/path-util.c @@ -34,19 +34,13 @@ #undef basename #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "extract-word.h" -#endif /* NM_IGNORED */ #include "fs-util.h" #include "log.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #include "path-util.h" -#if 0 /* NM_IGNORED */ #include "stat-util.h" -#endif /* NM_IGNORED */ #include "string-util.h" #include "strv.h" #include "time-util.h" @@ -580,10 +574,10 @@ static int binary_is_good(const char *binary) { if (r < 0) return r; - return !path_equal(d, "true") && - !path_equal(d, "/bin/true") && - !path_equal(d, "/usr/bin/true") && - !path_equal(d, "/dev/null"); + return !PATH_IN_SET(d, "true" + "/bin/true", + "/usr/bin/true", + "/dev/null"); } int fsck_exists(const char *fstype) { @@ -769,34 +763,53 @@ char *file_in_same_dir(const char *path, const char *filename) { return ret; } -bool hidden_file_allow_backup(const char *filename) { - assert(filename); - - return - filename[0] == '.' || - streq(filename, "lost+found") || - streq(filename, "aquota.user") || - streq(filename, "aquota.group") || - endswith(filename, ".rpmnew") || - endswith(filename, ".rpmsave") || - endswith(filename, ".rpmorig") || - endswith(filename, ".dpkg-old") || - endswith(filename, ".dpkg-new") || - endswith(filename, ".dpkg-tmp") || - endswith(filename, ".dpkg-dist") || - endswith(filename, ".dpkg-bak") || - endswith(filename, ".dpkg-backup") || - endswith(filename, ".dpkg-remove") || - endswith(filename, ".swp"); -} +bool hidden_or_backup_file(const char *filename) { + const char *p; -bool hidden_file(const char *filename) { assert(filename); - if (endswith(filename, "~")) + if (filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, "~")) return true; - return hidden_file_allow_backup(filename); + p = strrchr(filename, '.'); + if (!p) + return false; + + /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up + * with always new suffixes and that everybody else should just adjust to that, then it really should be on + * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt + * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional + * string. Specifically: there's now: + * + * The generic suffixes "~" and ".bak" for backup files + * The generic prefix "." for hidden files + * + * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist" + * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead. + */ + + return STR_IN_SET(p + 1, + "rpmnew", + "rpmsave", + "rpmorig", + "dpkg-old", + "dpkg-new", + "dpkg-tmp", + "dpkg-dist", + "dpkg-bak", + "dpkg-backup", + "dpkg-remove", + "ucf-new", + "ucf-old", + "ucf-dist", + "swp", + "bak", + "old", + "new"); } bool is_device_path(const char *path) { diff --git a/src/systemd/src/basic/path-util.h b/src/systemd/src/basic/path-util.h index 2c2f87a9..a27c13fc 100644 --- a/src/systemd/src/basic/path-util.h +++ b/src/systemd/src/basic/path-util.h @@ -48,6 +48,23 @@ bool path_equal(const char *a, const char *b) _pure_; bool path_equal_or_files_same(const char *a, const char *b); char* path_join(const char *root, const char *path, const char *rest); +static inline bool path_equal_ptr(const char *a, const char *b) { + return !!a == !!b && (!a || path_equal(a, b)); +} + +/* Note: the search terminates on the first NULL item. */ +#define PATH_IN_SET(p, ...) \ + ({ \ + char **s; \ + bool _found = false; \ + STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \ + if (path_equal(p, *s)) { \ + _found = true; \ + break; \ + } \ + _found; \ + }) + int path_strv_make_absolute_cwd(char **l); char** path_strv_resolve(char **l, const char *prefix); char** path_strv_resolve_uniq(char **l, const char *prefix); @@ -105,7 +122,6 @@ bool path_is_safe(const char *p) _pure_; char *file_in_same_dir(const char *path, const char *filename); -bool hidden_file_allow_backup(const char *filename); -bool hidden_file(const char *filename) _pure_; +bool hidden_or_backup_file(const char *filename) _pure_; bool is_device_path(const char *path); diff --git a/src/systemd/src/basic/random-util.c b/src/systemd/src/basic/random-util.c index 5500fd28..1d8ca882 100644 --- a/src/systemd/src/basic/random-util.c +++ b/src/systemd/src/basic/random-util.c @@ -34,9 +34,7 @@ #include "fd-util.h" #include "io-util.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif #include "random-util.h" #include "time-util.h" @@ -51,7 +49,7 @@ int dev_urandom(void *p, size_t n) { * never block, and will always return some data from the * kernel, regardless if the random pool is fully initialized * or not. It thus makes no guarantee for the quality of the - * returned entropy, but is good enough for or usual usecases + * returned entropy, but is good enough for our usual usecases * of seeding the hash functions for hashtable */ /* Use the getrandom() syscall unless we know we don't have diff --git a/src/systemd/src/basic/set.h b/src/systemd/src/basic/set.h index e0d9dd00..a5f8beb0 100644 --- a/src/systemd/src/basic/set.h +++ b/src/systemd/src/basic/set.h @@ -19,11 +19,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "extract-word.h" #include "hashmap.h" #include "macro.h" -Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); -#define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) +Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) static inline Set *set_free(Set *s) { internal_hashmap_free(HASHMAP_BASE(s)); @@ -41,8 +42,8 @@ static inline Set *set_copy(Set *s) { return (Set*) internal_hashmap_copy(HASHMAP_BASE(s)); } -int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); -#define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) +int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) int set_put(Set *s, const void *key); /* no set_update */ @@ -122,6 +123,7 @@ static inline char **set_get_strv(Set *s) { int set_consume(Set *s, void *value); int set_put_strdup(Set *s, const char *p); int set_put_strdupv(Set *s, char **l); +int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags); #define SET_FOREACH(e, s, i) \ for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); ) diff --git a/src/systemd/src/basic/signal-util.h b/src/systemd/src/basic/signal-util.h new file mode 100644 index 00000000..dfd6eb56 --- /dev/null +++ b/src/systemd/src/basic/signal-util.h @@ -0,0 +1,56 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010-2015 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <signal.h> + +#include "macro.h" + +int reset_all_signal_handlers(void); +int reset_signal_mask(void); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int sigset_add_many(sigset_t *ss, ...); +int sigprocmask_many(int how, sigset_t *old, ...); + +const char *signal_to_string(int i) _const_; +int signal_from_string(const char *s) _pure_; + +int signal_from_string_try_harder(const char *s); + +void nop_signal_handler(int sig); + +static inline void block_signals_reset(sigset_t *ss) { + assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0); +} + +#define BLOCK_SIGNALS(...) \ + _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \ + sigset_t t; \ + assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \ + t; \ + }) + +static inline bool SIGNAL_VALID(int signo) { + return signo > 0 && signo < _NSIG; +} diff --git a/src/systemd/src/basic/siphash24.c b/src/systemd/src/basic/siphash24.c index 145f64b2..4db444f5 100644 --- a/src/systemd/src/basic/siphash24.c +++ b/src/systemd/src/basic/siphash24.c @@ -19,6 +19,8 @@ #include "nm-sd-adapt.h" +#include <stdio.h> + #include "macro.h" #include "siphash24.h" #include "unaligned.h" diff --git a/src/systemd/src/basic/socket-util.c b/src/systemd/src/basic/socket-util.c index c68db7c3..be57d829 100644 --- a/src/systemd/src/basic/socket-util.c +++ b/src/systemd/src/basic/socket-util.c @@ -25,6 +25,7 @@ #include <net/if.h> #include <netdb.h> #include <netinet/ip.h> +#include <poll.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -35,22 +36,18 @@ #include "alloc-util.h" #include "fd-util.h" #include "fileio.h" -#if 0 /* NM_IGNORED */ #include "formats-util.h" -#endif /* NM_IGNORED */ #include "log.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #include "parse-util.h" #include "path-util.h" #include "socket-util.h" #include "string-table.h" #include "string-util.h" -#if 0 /* NM_IGNORED */ +#include "strv.h" #include "user-util.h" -#endif /* NM_IGNORED */ +#include "utf8.h" #include "util.h" #if 0 /* NM_IGNORED */ @@ -91,7 +88,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { return -EINVAL; a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); a->size = sizeof(struct sockaddr_in6); } else if (*s == '/') { @@ -139,7 +136,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (r > 0) { /* Gotcha, it's a traditional IPv4 address */ a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htons((uint16_t) u); + a->sockaddr.in.sin_port = htobe16((uint16_t)u); a->size = sizeof(struct sockaddr_in); } else { unsigned idx; @@ -153,7 +150,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { return -EINVAL; a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); a->sockaddr.in6.sin6_scope_id = idx; a->sockaddr.in6.sin6_addr = in6addr_any; a->size = sizeof(struct sockaddr_in6); @@ -170,12 +167,12 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (socket_ipv6_is_supported()) { a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_port = htobe16((uint16_t)u); a->sockaddr.in6.sin6_addr = in6addr_any; a->size = sizeof(struct sockaddr_in6); } else { a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htons((uint16_t) u); + a->sockaddr.in.sin_port = htobe16((uint16_t)u); a->sockaddr.in.sin_addr.s_addr = INADDR_ANY; a->size = sizeof(struct sockaddr_in); } @@ -494,9 +491,7 @@ int sockaddr_port(const struct sockaddr *_sa) { if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6)) return -EAFNOSUPPORT; - return ntohs(sa->sa.sa_family == AF_INET6 ? - sa->in6.sin6_port : - sa->in.sin_port); + return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port); } int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) { @@ -512,13 +507,13 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ case AF_INET: { uint32_t a; - a = ntohl(sa->in.sin_addr.s_addr); + a = be32toh(sa->in.sin_addr.s_addr); if (include_port) r = asprintf(&p, "%u.%u.%u.%u:%u", a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF, - ntohs(sa->in.sin_port)); + be16toh(sa->in.sin_port)); else r = asprintf(&p, "%u.%u.%u.%u", @@ -540,7 +535,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ r = asprintf(&p, "%u.%u.%u.%u:%u", a[0], a[1], a[2], a[3], - ntohs(sa->in6.sin6_port)); + be16toh(sa->in6.sin6_port)); else r = asprintf(&p, "%u.%u.%u.%u", @@ -556,7 +551,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ r = asprintf(&p, "[%s]:%u", a, - ntohs(sa->in6.sin6_port)); + be16toh(sa->in6.sin6_port)); if (r < 0) return -ENOMEM; } else { @@ -803,6 +798,42 @@ static const char* const ip_tos_table[] = { DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); +bool ifname_valid(const char *p) { + bool numeric = true; + + /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources + * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We + * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */ + + if (isempty(p)) + return false; + + if (strlen(p) >= IFNAMSIZ) + return false; + + if (STR_IN_SET(p, ".", "..")) + return false; + + while (*p) { + if ((unsigned char) *p >= 127U) + return false; + + if ((unsigned char) *p <= 32U) + return false; + + if (*p == ':' || *p == '/') + return false; + + numeric = numeric && (*p >= '0' && *p <= '9'); + p++; + } + + if (numeric) + return false; + + return true; +} + int getpeercred(int fd, struct ucred *ucred) { socklen_t n = sizeof(struct ucred); struct ucred u; @@ -959,7 +990,7 @@ ssize_t next_datagram_size_fd(int fd) { l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC); if (l < 0) { - if (errno == EOPNOTSUPP) + if (errno == EOPNOTSUPP || errno == EFAULT) goto fallback; return -errno; @@ -980,3 +1011,56 @@ fallback: return (ssize_t) k; } + +int flush_accept(int fd) { + + struct pollfd pollfd = { + .fd = fd, + .events = POLLIN, + }; + int r; + + + /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */ + + for (;;) { + int cfd; + + r = poll(&pollfd, 1, 0); + if (r < 0) { + if (errno == EINTR) + continue; + + return -errno; + + } else if (r == 0) + return 0; + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (cfd < 0) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN) + return 0; + + return -errno; + } + + close(cfd); + } +} + +struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) { + struct cmsghdr *cmsg; + + assert(mh); + + CMSG_FOREACH(cmsg, mh) + if (cmsg->cmsg_level == level && + cmsg->cmsg_type == type && + (length == (socklen_t) -1 || length == cmsg->cmsg_len)) + return cmsg; + + return NULL; +} diff --git a/src/systemd/src/basic/socket-util.h b/src/systemd/src/basic/socket-util.h index d17a2f35..2536b085 100644 --- a/src/systemd/src/basic/socket-util.h +++ b/src/systemd/src/basic/socket-util.h @@ -123,6 +123,8 @@ int fd_inc_rcvbuf(int fd, size_t n); int ip_tos_to_string_alloc(int i, char **s); int ip_tos_from_string(const char *s); +bool ifname_valid(const char *p); + int getpeercred(int fd, struct ucred *ucred); int getpeersec(int fd, char **ret); @@ -135,5 +137,20 @@ int receive_one_fd(int transport_fd, int flags); ssize_t next_datagram_size_fd(int fd); +int flush_accept(int fd); + #define CMSG_FOREACH(cmsg, mh) \ for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg))) + +struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length); + +/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */ +#define SOCKADDR_UN_LEN(sa) \ + ({ \ + const struct sockaddr_un *_sa = &(sa); \ + assert(_sa->sun_family == AF_UNIX); \ + offsetof(struct sockaddr_un, sun_path) + \ + (_sa->sun_path[0] == 0 ? \ + 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \ + strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \ + }) diff --git a/src/systemd/src/basic/string-table.h b/src/systemd/src/basic/string-table.h index b180488f..369610ef 100644 --- a/src/systemd/src/basic/string-table.h +++ b/src/systemd/src/basic/string-table.h @@ -48,6 +48,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k #define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ scope type name##_from_string(const char *s) { \ int b; \ + if (!s) \ + return -1; \ b = parse_boolean(s); \ if (b == 0) \ return (type) 0; \ @@ -56,26 +58,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ } -#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ - _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ - _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \ - struct __useless_struct_to_allow_trailing_semicolon__ - -#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \ - _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ - _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ - struct __useless_struct_to_allow_trailing_semicolon__ - -#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,) -#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static) -#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static) -#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static) - -#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,) - -/* For string conversions where numbers are also acceptable */ -#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \ - int name##_to_string_alloc(type i, char **str) { \ +#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \ + scope int name##_to_string_alloc(type i, char **str) { \ char *s; \ if (i < 0 || i > max) \ return -ERANGE; \ @@ -89,7 +73,9 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k } \ *str = s; \ return 0; \ - } \ + } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \ type name##_from_string(const char *s) { \ type i; \ unsigned u = 0; \ @@ -102,4 +88,32 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k return (type) u; \ return (type) -1; \ } \ + + +#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static) + +#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,) + +/* For string conversions where numbers are also acceptable */ +#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,) \ struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static) diff --git a/src/systemd/src/basic/string-util.c b/src/systemd/src/basic/string-util.c index 68de772e..b4e774cc 100644 --- a/src/systemd/src/basic/string-util.c +++ b/src/systemd/src/basic/string-util.c @@ -24,11 +24,10 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "gunicode.h" -#endif /* NM_IGNORED */ #include "macro.h" #include "string-util.h" #include "utf8.h" @@ -327,6 +326,14 @@ char ascii_tolower(char x) { return x; } +char ascii_toupper(char x) { + + if (x >= 'a' && x <= 'z') + return x - 'a' + 'A'; + + return x; +} + char *ascii_strlower(char *t) { char *p; @@ -338,6 +345,17 @@ char *ascii_strlower(char *t) { return t; } +char *ascii_strupper(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + *p = ascii_toupper(*p); + + return t; +} + char *ascii_strlower_n(char *t, size_t n) { size_t i; @@ -809,25 +827,20 @@ int free_and_strdup(char **p, const char *s) { return 1; } -#pragma GCC push_options -#pragma GCC optimize("O0") +/* + * Pointer to memset is volatile so that compiler must de-reference + * the pointer and can't assume that it points to any function in + * particular (such as memset, which it then might further "optimize") + * This approach is inspired by openssl's crypto/mem_clr.c. + */ +typedef void *(*memset_t)(void *,int,size_t); -void* memory_erase(void *p, size_t l) { - volatile uint8_t* x = (volatile uint8_t*) p; - - /* This basically does what memset() does, but hopefully isn't - * optimized away by the compiler. One of those days, when - * glibc learns memset_s() we should replace this call by - * memset_s(), but until then this has to do. */ - - for (; l > 0; l--) - *(x++) = 'x'; +static volatile memset_t memset_func = memset; - return p; +void* memory_erase(void *p, size_t l) { + return memset_func(p, 'x', l); } -#pragma GCC pop_options - char* string_erase(char *x) { if (!x) diff --git a/src/systemd/src/basic/string-util.h b/src/systemd/src/basic/string-util.h index ad0c8137..b75aba63 100644 --- a/src/systemd/src/basic/string-util.h +++ b/src/systemd/src/basic/string-util.h @@ -37,6 +37,7 @@ #define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS #define ALPHANUMERICAL LETTERS DIGITS +#define HEXDIGITS DIGITS "abcdefABCDEF" #define streq(a,b) (strcmp((a),(b)) == 0) #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) @@ -65,6 +66,10 @@ static inline bool isempty(const char *p) { return !p || !p[0]; } +static inline const char *empty_to_null(const char *p) { + return isempty(p) ? NULL : p; +} + static inline char *startswith(const char *s, const char *prefix) { size_t l; @@ -132,6 +137,9 @@ char ascii_tolower(char x); char *ascii_strlower(char *s); char *ascii_strlower_n(char *s, size_t n); +char ascii_toupper(char x); +char *ascii_strupper(char *s); + int ascii_strcasecmp_n(const char *a, const char *b, size_t n); int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m); diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c index e885c598..eeb8c1e0 100644 --- a/src/systemd/src/basic/strv.c +++ b/src/systemd/src/basic/strv.c @@ -28,9 +28,7 @@ #include "alloc-util.h" #include "escape.h" -#if 0 /* NM_IGNORED */ #include "extract-word.h" -#endif /* NM_IGNORED */ #include "fileio.h" #include "string-util.h" #include "strv.h" @@ -143,16 +141,16 @@ char **strv_new_ap(const char *x, va_list ap) { va_list aq; /* As a special trick we ignore all listed strings that equal - * (const char*) -1. This is supposed to be used with the + * STRV_IGNORE. This is supposed to be used with the * STRV_IFNOTNULL() macro to include possibly NULL strings in * the string list. */ if (x) { - n = x == (const char*) -1 ? 0 : 1; + n = x == STRV_IGNORE ? 0 : 1; va_copy(aq, ap); while ((s = va_arg(aq, const char*))) { - if (s == (const char*) -1) + if (s == STRV_IGNORE) continue; n++; @@ -166,7 +164,7 @@ char **strv_new_ap(const char *x, va_list ap) { return NULL; if (x) { - if (x != (const char*) -1) { + if (x != STRV_IGNORE) { a[i] = strdup(x); if (!a[i]) goto fail; @@ -175,7 +173,7 @@ char **strv_new_ap(const char *x, va_list ap) { while ((s = va_arg(ap, const char*))) { - if (s == (const char*) -1) + if (s == STRV_IGNORE) continue; a[i] = strdup(s); @@ -564,6 +562,42 @@ int strv_extend(char ***l, const char *value) { return strv_consume(l, v); } +int strv_extend_front(char ***l, const char *value) { + size_t n, m; + char *v, **c; + + assert(l); + + /* Like strv_extend(), but prepends rather than appends the new entry */ + + if (!value) + return 0; + + n = strv_length(*l); + + /* Increase and overflow check. */ + m = n + 2; + if (m < n) + return -ENOMEM; + + v = strdup(value); + if (!v) + return -ENOMEM; + + c = realloc_multiply(*l, sizeof(char*), m); + if (!c) { + free(v); + return -ENOMEM; + } + + memmove(c+1, c, n * sizeof(char*)); + c[0] = v; + c[n+1] = NULL; + + *l = c; + return 0; +} + char **strv_uniq(char **l) { char **i; @@ -608,6 +642,17 @@ char **strv_remove(char **l, const char *s) { } char **strv_parse_nulstr(const char *s, size_t l) { + /* l is the length of the input data, which will be split at NULs into + * elements of the resulting strv. Hence, the number of items in the resulting strv + * will be equal to one plus the number of NUL bytes in the l bytes starting at s, + * unless s[l-1] is NUL, in which case the final empty string is not stored in + * the resulting strv, and length is equal to the number of NUL bytes. + * + * Note that contrary to a normal nulstr which cannot contain empty strings, because + * the input data is terminated by any two consequent NUL bytes, this parser accepts + * empty strings in s. + */ + const char *p; unsigned c = 0, i = 0; char **v; @@ -670,6 +715,13 @@ char **strv_split_nulstr(const char *s) { } int strv_make_nulstr(char **l, char **p, size_t *q) { + /* A valid nulstr with two NULs at the end will be created, but + * q will be the length without the two trailing NULs. Thus the output + * string is a valid nulstr and can be iterated over using NULSTR_FOREACH, + * and can also be parsed by strv_parse_nulstr as long as the length + * is provided separately. + */ + size_t n_allocated = 0, n = 0; _cleanup_free_ char *m = NULL; char **i; @@ -682,7 +734,7 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { z = strlen(*i); - if (!GREEDY_REALLOC(m, n_allocated, n + z + 1)) + if (!GREEDY_REALLOC(m, n_allocated, n + z + 2)) return -ENOMEM; memcpy(m + n, *i, z + 1); @@ -693,11 +745,14 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { m = new0(char, 1); if (!m) return -ENOMEM; - n = 0; - } + n = 1; + } else + /* make sure there is a second extra NUL at the end of resulting nulstr */ + m[n] = '\0'; + assert(n > 0); *p = m; - *q = n; + *q = n - 1; m = NULL; @@ -773,13 +828,8 @@ char **strv_reverse(char **l) { if (n <= 1) return l; - for (i = 0; i < n / 2; i++) { - char *t; - - t = l[i]; - l[i] = l[n-1-i]; - l[n-1-i] = t; - } + for (i = 0; i < n / 2; i++) + SWAP_TWO(l[i], l[n-1-i]); return l; } @@ -808,7 +858,7 @@ bool strv_fnmatch(char* const* patterns, const char *s, int flags) { char* const* p; STRV_FOREACH(p, patterns) - if (fnmatch(*p, s, 0) == 0) + if (fnmatch(*p, s, flags) == 0) return true; return false; @@ -850,7 +900,7 @@ int strv_extend_n(char ***l, const char *value, size_t n) { if (n == 0) return 0; - /* Adds the value value n times to l */ + /* Adds the value n times to l */ k = strv_length(*l); diff --git a/src/systemd/src/basic/strv.h b/src/systemd/src/basic/strv.h index 4a93818a..683ce83a 100644 --- a/src/systemd/src/basic/strv.h +++ b/src/systemd/src/basic/strv.h @@ -25,9 +25,7 @@ #include <stddef.h> #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "extract-word.h" -#endif /* NM_IGNORED */ #include "macro.h" #include "util.h" @@ -52,6 +50,7 @@ int strv_extend_strv(char ***a, char **b, bool filter_duplicates); int strv_extend_strv_concat(char ***a, char **b, const char *suffix); int strv_extend(char ***l, const char *value); int strv_extendf(char ***l, const char *format, ...) _printf_(2,0); +int strv_extend_front(char ***l, const char *value); int strv_push(char ***l, char *value); int strv_push_pair(char ***l, char *a, char *b); int strv_push_prepend(char ***l, char *value); @@ -70,8 +69,10 @@ bool strv_equal(char **a, char **b); char **strv_new(const char *x, ...) _sentinel_; char **strv_new_ap(const char *x, va_list ap); +#define STRV_IGNORE ((const char *) -1) + static inline const char* STRV_IFNOTNULL(const char *x) { - return x ? x : (const char *) -1; + return x ? x : STRV_IGNORE; } static inline bool strv_isempty(char * const *l) { @@ -81,9 +82,7 @@ static inline bool strv_isempty(char * const *l) { char **strv_split(const char *s, const char *separator); char **strv_split_newlines(const char *s); -#if 0 /* NM_IGNORED */ int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags); -#endif /* NM_IGNORED */ char *strv_join(char **l, const char *separator); char *strv_join_quoted(char **l); diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c index 5b2b2180..212c8f4e 100644 --- a/src/systemd/src/basic/time-util.c +++ b/src/systemd/src/basic/time-util.c @@ -49,15 +49,12 @@ static clockid_t map_clock_id(clockid_t c) { /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on - * those archs. - * - * Also, older kernels don't support CLOCK_BOOTTIME: fall back to CLOCK_MONOTONIC. */ + * those archs. */ switch (c) { - case CLOCK_BOOTTIME: case CLOCK_BOOTTIME_ALARM: - return clock_boottime_or_monotonic (); + return CLOCK_BOOTTIME; case CLOCK_REALTIME_ALARM: return CLOCK_REALTIME; @@ -92,6 +89,16 @@ dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { return ts; } +triple_timestamp* triple_timestamp_get(triple_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + ts->boottime = clock_boottime_supported() ? now(CLOCK_BOOTTIME) : USEC_INFINITY; + + return ts; +} + dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { int64_t delta; assert(ts); @@ -109,6 +116,24 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { return ts; } +triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) { + int64_t delta; + + assert(ts); + + if (u == USEC_INFINITY || u <= 0) { + ts->realtime = ts->monotonic = ts->boottime = u; + return ts; + } + + ts->realtime = u; + delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; + ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta); + ts->boottime = clock_boottime_supported() ? usec_sub(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY; + + return ts; +} + dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) { int64_t delta; assert(ts); @@ -141,6 +166,26 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us return ts; } +usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) { + + switch (clock) { + + case CLOCK_REALTIME: + case CLOCK_REALTIME_ALARM: + return ts->realtime; + + case CLOCK_MONOTONIC: + return ts->monotonic; + + case CLOCK_BOOTTIME: + case CLOCK_BOOTTIME_ALARM: + return ts->boottime; + + default: + return USEC_INFINITY; + } +} + usec_t timespec_load(const struct timespec *ts) { assert(ts); @@ -212,32 +257,95 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) { return tv; } -static char *format_timestamp_internal(char *buf, size_t l, usec_t t, - bool utc, bool us) { +static char *format_timestamp_internal( + char *buf, + size_t l, + usec_t t, + bool utc, + bool us) { + + /* The weekdays in non-localized (English) form. We use this instead of the localized form, so that our + * generated timestamps may be parsed with parse_timestamp(), and always read the same. */ + static const char * const weekdays[] = { + [0] = "Sun", + [1] = "Mon", + [2] = "Tue", + [3] = "Wed", + [4] = "Thu", + [5] = "Fri", + [6] = "Sat", + }; + struct tm tm; time_t sec; - int k; + size_t n; assert(buf); - assert(l > 0); + if (l < + 3 + /* week day */ + 1 + 10 + /* space and date */ + 1 + 8 + /* space and time */ + (us ? 1 + 6 : 0) + /* "." and microsecond part */ + 1 + 1 + /* space and shortest possible zone */ + 1) + return NULL; /* Not enough space even for the shortest form. */ if (t <= 0 || t == USEC_INFINITY) + return NULL; /* Timestamp is unset */ + + sec = (time_t) (t / USEC_PER_SEC); /* Round down */ + if ((usec_t) sec != (t / USEC_PER_SEC)) + return NULL; /* overflow? */ + + if (!localtime_or_gmtime_r(&sec, &tm, utc)) return NULL; - sec = (time_t) (t / USEC_PER_SEC); - localtime_or_gmtime_r(&sec, &tm, utc); + /* Start with the week day */ + assert((size_t) tm.tm_wday < ELEMENTSOF(weekdays)); + memcpy(buf, weekdays[tm.tm_wday], 4); - if (us) - k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm); - else - k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm); + /* Add the main components */ + if (strftime(buf + 3, l - 3, " %Y-%m-%d %H:%M:%S", &tm) <= 0) + return NULL; /* Doesn't fit */ - if (k <= 0) - return NULL; + /* Append the microseconds part, if that's requested */ if (us) { - snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC)); - if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0) - return NULL; + n = strlen(buf); + if (n + 8 > l) + return NULL; /* Microseconds part doesn't fit. */ + + sprintf(buf + n, ".%06llu", (unsigned long long) (t % USEC_PER_SEC)); + } + + /* Append the timezone */ + n = strlen(buf); + if (utc) { + /* If this is UTC then let's explicitly use the "UTC" string here, because gmtime_r() normally uses the + * obsolete "GMT" instead. */ + if (n + 5 > l) + return NULL; /* "UTC" doesn't fit. */ + + strcpy(buf + n, " UTC"); + + } else if (!isempty(tm.tm_zone)) { + size_t tn; + + /* An explicit timezone is specified, let's use it, if it fits */ + tn = strlen(tm.tm_zone); + if (n + 1 + tn + 1 > l) { + /* The full time zone does not fit in. Yuck. */ + + if (n + 1 + _POSIX_TZNAME_MAX + 1 > l) + return NULL; /* Not even enough space for the POSIX minimum (of 6)? In that case, complain that it doesn't fit */ + + /* So the time zone doesn't fit in fully, but the caller passed enough space for the POSIX + * minimum time zone length. In this case suppress the timezone entirely, in order not to dump + * an overly long, hard to read string on the user. This should be safe, because the user will + * assume the local timezone anyway if none is shown. And so does parse_timestamp(). */ + } else { + buf[n++] = ' '; + strcpy(buf + n, tm.tm_zone); + } } return buf; @@ -499,12 +607,11 @@ int parse_timestamp(const char *t, usec_t *usec) { { "Sat", 6 }, }; - const char *k; - const char *utc; + const char *k, *utc, *tzn = NULL; struct tm tm, copy; time_t x; usec_t x_usec, plus = 0, minus = 0, ret; - int r, weekday = -1; + int r, weekday = -1, dst = -1; unsigned i; /* @@ -569,15 +676,55 @@ int parse_timestamp(const char *t, usec_t *usec) { goto finish; } + /* See if the timestamp is suffixed with UTC */ utc = endswith_no_case(t, " UTC"); if (utc) t = strndupa(t, utc - t); + else { + const char *e = NULL; + int j; + + tzset(); + + /* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only + * support the local timezones here, nothing else. Not because we wouldn't want to, but simply because + * there are no nice APIs available to cover this. By accepting the local time zone strings, we make + * sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't + * support arbitrary timezone specifications. */ - x = ret / USEC_PER_SEC; + for (j = 0; j <= 1; j++) { + + if (isempty(tzname[j])) + continue; + + e = endswith_no_case(t, tzname[j]); + if (!e) + continue; + if (e == t) + continue; + if (e[-1] != ' ') + continue; + + break; + } + + if (IN_SET(j, 0, 1)) { + /* Found one of the two timezones specified. */ + t = strndupa(t, e - t - 1); + dst = j; + tzn = tzname[j]; + } + } + + x = (time_t) (ret / USEC_PER_SEC); x_usec = 0; - assert_se(localtime_or_gmtime_r(&x, &tm, utc)); - tm.tm_isdst = -1; + if (!localtime_or_gmtime_r(&x, &tm, utc)) + return -EINVAL; + + tm.tm_isdst = dst; + if (tzn) + tm.tm_zone = tzn; if (streq(t, "today")) { tm.tm_sec = tm.tm_min = tm.tm_hour = 0; @@ -594,7 +741,6 @@ int parse_timestamp(const char *t, usec_t *usec) { goto from_tm; } - for (i = 0; i < ELEMENTSOF(day_nr); i++) { size_t skip; @@ -687,7 +833,6 @@ parse_usec: return -EINVAL; x_usec = add; - } from_tm: @@ -1089,22 +1234,55 @@ bool timezone_is_valid(const char *name) { return true; } -clockid_t clock_boottime_or_monotonic(void) { - static clockid_t clock = -1; - int fd; +bool clock_boottime_supported(void) { + static int supported = -1; - if (clock != -1) - return clock; + /* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */ - fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC); - if (fd < 0) - clock = CLOCK_MONOTONIC; - else { - safe_close(fd); - clock = CLOCK_BOOTTIME; + if (supported < 0) { + int fd; + + fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC); + if (fd < 0) + supported = false; + else { + safe_close(fd); + supported = true; + } } - return clock; + return supported; +} + +clockid_t clock_boottime_or_monotonic(void) { + if (clock_boottime_supported()) + return CLOCK_BOOTTIME; + else + return CLOCK_MONOTONIC; +} + +bool clock_supported(clockid_t clock) { + struct timespec ts; + + switch (clock) { + + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + return true; + + case CLOCK_BOOTTIME: + return clock_boottime_supported(); + + case CLOCK_BOOTTIME_ALARM: + if (!clock_boottime_supported()) + return false; + + /* fall through, after checking the cached value for CLOCK_BOOTTIME. */ + + default: + /* For everything else, check properly */ + return clock_gettime(clock, &ts) >= 0; + } } #if 0 /* NM_IGNORED */ diff --git a/src/systemd/src/basic/time-util.h b/src/systemd/src/basic/time-util.h index 77e3cd08..99be5ce6 100644 --- a/src/systemd/src/basic/time-util.h +++ b/src/systemd/src/basic/time-util.h @@ -39,6 +39,12 @@ typedef struct dual_timestamp { usec_t monotonic; } dual_timestamp; +typedef struct triple_timestamp { + usec_t realtime; + usec_t monotonic; + usec_t boottime; +} triple_timestamp; + #define USEC_INFINITY ((usec_t) -1) #define NSEC_INFINITY ((nsec_t) -1) @@ -62,14 +68,17 @@ typedef struct dual_timestamp { #define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC)) #define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC)) -#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */ +/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this + * to 6. Let's rely on that. */ +#define FORMAT_TIMESTAMP_MAX (3+1+10+1+8+1+6+1+6+1) #define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */ #define FORMAT_TIMESTAMP_RELATIVE_MAX 256 #define FORMAT_TIMESPAN_MAX 64 #define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1) -#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0ULL, 0ULL }) +#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) {}) +#define TRIPLE_TIMESTAMP_NULL ((struct triple_timestamp) {}) usec_t now(clockid_t clock); nsec_t now_nsec(clockid_t clock); @@ -79,11 +88,28 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u); dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u); +triple_timestamp* triple_timestamp_get(triple_timestamp *ts); +triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u); + +#define DUAL_TIMESTAMP_HAS_CLOCK(clock) \ + IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC) + +#define TRIPLE_TIMESTAMP_HAS_CLOCK(clock) \ + IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) + static inline bool dual_timestamp_is_set(dual_timestamp *ts) { return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY)); } +static inline bool triple_timestamp_is_set(triple_timestamp *ts) { + return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || + (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY) || + (ts->boottime > 0 && ts->boottime != USEC_INFINITY)); +} + +usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); + usec_t timespec_load(const struct timespec *ts) _pure_; struct timespec *timespec_store(struct timespec *ts, usec_t u); @@ -112,6 +138,8 @@ bool ntp_synced(void); int get_timezones(char ***l); bool timezone_is_valid(const char *name); +bool clock_boottime_supported(void); +bool clock_supported(clockid_t clock); clockid_t clock_boottime_or_monotonic(void); #define xstrftime(buf, fmt, tm) \ diff --git a/src/systemd/src/basic/unaligned.h b/src/systemd/src/basic/unaligned.h index 79be645b..7c847a3c 100644 --- a/src/systemd/src/basic/unaligned.h +++ b/src/systemd/src/basic/unaligned.h @@ -109,3 +109,21 @@ static inline void unaligned_write_le64(void *_u, uint64_t a) { unaligned_write_le32(u, (uint32_t) a); unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); } + +#if __BYTE_ORDER == __BIG_ENDIAN +#define unaligned_read_ne16 unaligned_read_be16 +#define unaligned_read_ne32 unaligned_read_be32 +#define unaligned_read_ne64 unaligned_read_be64 + +#define unaligned_write_ne16 unaligned_write_be16 +#define unaligned_write_ne32 unaligned_write_be32 +#define unaligned_write_ne64 unaligned_write_be64 +#else +#define unaligned_read_ne16 unaligned_read_le16 +#define unaligned_read_ne32 unaligned_read_le32 +#define unaligned_read_ne64 unaligned_read_le64 + +#define unaligned_write_ne16 unaligned_write_le16 +#define unaligned_write_ne32 unaligned_write_le32 +#define unaligned_write_ne64 unaligned_write_le64 +#endif diff --git a/src/systemd/src/basic/utf8.h b/src/systemd/src/basic/utf8.h index 1bc23dc1..322dac20 100644 --- a/src/systemd/src/basic/utf8.h +++ b/src/systemd/src/basic/utf8.h @@ -27,9 +27,7 @@ #endif /* NM_IGNORED */ #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd" #define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf" diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c index 6d641a4a..79c7aa46 100644 --- a/src/systemd/src/basic/util.c +++ b/src/systemd/src/basic/util.c @@ -37,39 +37,29 @@ #include <unistd.h> #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "build.h" +#include "cgroup-util.h" #include "def.h" #include "dirent-util.h" -#endif /* NM_IGNORED */ #include "fd-util.h" #include "fileio.h" -#if 0 /* NM_IGNORED */ #include "formats-util.h" -#endif /* NM_IGNORED */ #include "hashmap.h" #include "hostname-util.h" #include "log.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #include "parse-util.h" #include "path-util.h" -#if 0 /* NM_IGNORED */ #include "process-util.h" -#endif /* NM_IGNORED */ #include "set.h" -#if 0 /* NM_IGNORED */ #include "signal-util.h" #include "stat-util.h" -#endif /* NM_IGNORED */ #include "string-util.h" #include "strv.h" #include "time-util.h" -#if 0 /* NM_IGNORED */ +#include "umask-util.h" #include "user-util.h" -#endif /* NM_IGNORED */ #include "util.h" /* Put this test here for a lack of better place */ @@ -78,6 +68,7 @@ assert_cc(EAGAIN == EWOULDBLOCK); #if 0 /* NM_IGNORED */ int saved_argc = 0; char **saved_argv = NULL; +static int saved_in_initrd = -1; #endif /* NM_IGNORED */ size_t page_size(void) { @@ -436,13 +427,17 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa _exit(EXIT_FAILURE); } - if (!stdout_is_tty) - dup2(fd, STDOUT_FILENO); + if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } - if (!stderr_is_tty) - dup2(fd, STDERR_FILENO); + if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } - if (fd > 2) + if (fd > STDERR_FILENO) close(fd); } @@ -466,11 +461,10 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa } bool in_initrd(void) { - static int saved = -1; struct statfs s; - if (saved >= 0) - return saved; + if (saved_in_initrd >= 0) + return saved_in_initrd; /* We make two checks here: * @@ -482,11 +476,15 @@ bool in_initrd(void) { * emptying when transititioning to the main systemd. */ - saved = access("/etc/initrd-release", F_OK) >= 0 && - statfs("/", &s) >= 0 && - is_temporary_fs(&s); + saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 && + statfs("/", &s) >= 0 && + is_temporary_fs(&s); + + return saved_in_initrd; +} - return saved; +void in_initrd_force(bool value) { + saved_in_initrd = value; } /* hey glibc, APIs with callbacks without a user pointer are so useless */ @@ -534,7 +532,7 @@ int on_ac_power(void) { if (!de) break; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY); @@ -588,47 +586,6 @@ int on_ac_power(void) { return found_online || !found_offline; } -bool id128_is_valid(const char *s) { - size_t i, l; - - l = strlen(s); - if (l == 32) { - - /* Simple formatted 128bit hex string */ - - for (i = 0; i < l; i++) { - char c = s[i]; - - if (!(c >= '0' && c <= '9') && - !(c >= 'a' && c <= 'z') && - !(c >= 'A' && c <= 'Z')) - return false; - } - - } else if (l == 36) { - - /* Formatted UUID */ - - for (i = 0; i < l; i++) { - char c = s[i]; - - if ((i == 8 || i == 13 || i == 18 || i == 23)) { - if (c != '-') - return false; - } else { - if (!(c >= '0' && c <= '9') && - !(c >= 'a' && c <= 'z') && - !(c >= 'A' && c <= 'Z')) - return false; - } - } - - } else - return false; - - return true; -} - int container_get_leader(const char *machine, pid_t *pid) { _cleanup_free_ char *s = NULL, *class = NULL; const char *p; @@ -779,26 +736,140 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int } uint64_t physical_memory(void) { - long mem; + _cleanup_free_ char *root = NULL, *value = NULL; + uint64_t mem, lim; + size_t ps; + long sc; + + /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of + * memory. + * + * In order to support containers nicely that have a configured memory limit we'll take the minimum of the + * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */ + + sc = sysconf(_SC_PHYS_PAGES); + assert(sc > 0); + + ps = page_size(); + mem = (uint64_t) sc * (uint64_t) ps; + + if (cg_get_root_path(&root) < 0) + return mem; + + if (cg_get_attribute("memory", root, "memory.limit_in_bytes", &value)) + return mem; - /* We return this as uint64_t in case we are running as 32bit - * process on a 64bit kernel with huge amounts of memory */ + if (safe_atou64(value, &lim) < 0) + return mem; - mem = sysconf(_SC_PHYS_PAGES); - assert(mem > 0); + /* Make sure the limit is a multiple of our own page size */ + lim /= ps; + lim *= ps; - return (uint64_t) mem * (uint64_t) page_size(); + return MIN(mem, lim); } -int update_reboot_param_file(const char *param) { - int r = 0; +uint64_t physical_memory_scale(uint64_t v, uint64_t max) { + uint64_t p, m, ps, r; - if (param) { - r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE); + assert(max > 0); + + /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success + * the result is a multiple of the page size (rounds down). */ + + ps = page_size(); + assert(ps > 0); + + p = physical_memory() / ps; + assert(p > 0); + + m = p * v; + if (m / p != v) + return UINT64_MAX; + + m /= max; + + r = m * ps; + if (r / ps != m) + return UINT64_MAX; + + return r; +} + +uint64_t system_tasks_max(void) { + +#if SIZEOF_PID_T == 4 +#define TASKS_MAX ((uint64_t) (INT32_MAX-1)) +#elif SIZEOF_PID_T == 2 +#define TASKS_MAX ((uint64_t) (INT16_MAX-1)) +#else +#error "Unknown pid_t size" +#endif + + _cleanup_free_ char *value = NULL, *root = NULL; + uint64_t a = TASKS_MAX, b = TASKS_MAX; + + /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this + * limit: + * + * a) the maximum value for the pid_t type + * b) the cgroups pids_max attribute for the system + * c) the kernel's configure maximum PID value + * + * And then pick the smallest of the three */ + + if (read_one_line_file("/proc/sys/kernel/pid_max", &value) >= 0) + (void) safe_atou64(value, &a); + + if (cg_get_root_path(&root) >= 0) { + value = mfree(value); + + if (cg_get_attribute("pids", root, "pids.max", &value) >= 0) + (void) safe_atou64(value, &b); + } + + return MIN3(TASKS_MAX, + a <= 0 ? TASKS_MAX : a, + b <= 0 ? TASKS_MAX : b); +} + +uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { + uint64_t t, m; + + assert(max > 0); + + /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages + * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */ + + t = system_tasks_max(); + assert(t > 0); + + m = t * v; + if (m / t != v) /* overflow? */ + return UINT64_MAX; + + return m / max; +} + +int update_reboot_parameter_and_warn(const char *param) { + int r; + + if (isempty(param)) { + if (unlink("/run/systemd/reboot-param") < 0) { + if (errno == ENOENT) + return 0; + + return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m"); + } + + return 0; + } + + RUN_WITH_UMASK(0022) { + r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE); if (r < 0) - return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m"); - } else - (void) unlink(REBOOT_PARAM_FILE); + return log_warning_errno(r, "Failed to write reboot parameter file: %m"); + } return 0; } diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h index 3225269a..bb2fc318 100644 --- a/src/systemd/src/basic/util.h +++ b/src/systemd/src/basic/util.h @@ -41,13 +41,9 @@ #include <time.h> #include <unistd.h> -#if 0 /* NM_IGNORED */ #include "formats-util.h" -#endif /* NM_IGNORED */ #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif /* NM_IGNORED */ #include "time-util.h" size_t page_size(void) _pure_; @@ -65,6 +61,10 @@ static inline const char* one_zero(bool b) { return b ? "1" : "0"; } +static inline const char* enable_disable(bool b) { + return b ? "enable" : "disable"; +} + void execute_directories(const char* const* directories, usec_t timeout, char *argv[]); bool plymouth_running(void); @@ -90,6 +90,7 @@ int prot_from_flags(int flags) _const_; int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); bool in_initrd(void); +void in_initrd_force(bool value); void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), @@ -179,15 +180,17 @@ static inline unsigned log2u_round_up(unsigned x) { return log2u(x - 1) + 1; } -bool id128_is_valid(const char *s) _pure_; - int container_get_leader(const char *machine, pid_t *pid); int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd); int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd); uint64_t physical_memory(void); +uint64_t physical_memory_scale(uint64_t v, uint64_t max); + +uint64_t system_tasks_max(void); +uint64_t system_tasks_max_scale(uint64_t v, uint64_t max); -int update_reboot_param_file(const char *param); +int update_reboot_parameter_and_warn(const char *param); int version(void); diff --git a/src/systemd/src/libsystemd-network/arp-util.c b/src/systemd/src/libsystemd-network/arp-util.c index 0c898145..8c678626 100644 --- a/src/systemd/src/libsystemd-network/arp-util.c +++ b/src/systemd/src/libsystemd-network/arp-util.c @@ -81,7 +81,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_ }; union sockaddr_union link = { .ll.sll_family = AF_PACKET, - .ll.sll_protocol = htons(ETH_P_ARP), + .ll.sll_protocol = htobe16(ETH_P_ARP), .ll.sll_ifindex = ifindex, .ll.sll_halen = ETH_ALEN, .ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, @@ -114,17 +114,17 @@ static int arp_send_packet(int fd, int ifindex, bool announce) { union sockaddr_union link = { .ll.sll_family = AF_PACKET, - .ll.sll_protocol = htons(ETH_P_ARP), + .ll.sll_protocol = htobe16(ETH_P_ARP), .ll.sll_ifindex = ifindex, .ll.sll_halen = ETH_ALEN, .ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, }; struct ether_arp arp = { - .ea_hdr.ar_hrd = htons(ARPHRD_ETHER), /* HTYPE */ - .ea_hdr.ar_pro = htons(ETHERTYPE_IP), /* PTYPE */ + .ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */ + .ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */ .ea_hdr.ar_hln = ETH_ALEN, /* HLEN */ .ea_hdr.ar_pln = sizeof(be32_t), /* PLEN */ - .ea_hdr.ar_op = htons(ARPOP_REQUEST), /* REQUEST */ + .ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */ }; int r; diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c index c7a3eac5..c1fa8763 100644 --- a/src/systemd/src/libsystemd-network/dhcp-identifier.c +++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c @@ -19,9 +19,7 @@ #include "nm-sd-adapt.h" -#if 0 /* NM_IGNORED */ #include "libudev.h" -#endif /* NM_IGNORED */ #include "sd-id128.h" #include "dhcp-identifier.h" @@ -29,9 +27,10 @@ #include "network-internal.h" #include "siphash24.h" #include "sparse-endian.h" -#if 0 /* NM_IGNORED */ #include "udev-util.h" #include "virt.h" + +#if 0 /* NM_IGNORED */ #else /* NM_IGNORED */ #include <net/if.h> #endif /* NM_IGNORED */ @@ -39,6 +38,37 @@ #define SYSTEMD_PEN 43793 #define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09) +int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) { + struct duid d; + + assert_cc(sizeof(d.raw) >= MAX_DUID_LEN); + if (duid_len > MAX_DUID_LEN) + return -EINVAL; + + switch (duid_type) { + case DUID_TYPE_LLT: + if (duid_len <= sizeof(d.llt)) + return -EINVAL; + break; + case DUID_TYPE_EN: + if (duid_len != sizeof(d.en)) + return -EINVAL; + break; + case DUID_TYPE_LL: + if (duid_len <= sizeof(d.ll)) + return -EINVAL; + break; + case DUID_TYPE_UUID: + if (duid_len != sizeof(d.uuid)) + return -EINVAL; + break; + default: + /* accept unknown type in order to be forward compatible */ + break; + } + return 0; +} + int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; uint64_t hash; diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.h b/src/systemd/src/libsystemd-network/dhcp-identifier.h index babae15c..1cc0f9fb 100644 --- a/src/systemd/src/libsystemd-network/dhcp-identifier.h +++ b/src/systemd/src/libsystemd-network/dhcp-identifier.h @@ -26,7 +26,6 @@ #include "unaligned.h" typedef enum DUIDType { - DUID_TYPE_RAW = 0, DUID_TYPE_LLT = 1, DUID_TYPE_EN = 2, DUID_TYPE_LL = 3, @@ -40,27 +39,28 @@ typedef enum DUIDType { */ #define MAX_DUID_LEN 128 +/* https://tools.ietf.org/html/rfc3315#section-9.1 */ struct duid { be16_t type; union { struct { - /* DHCP6_DUID_LLT */ + /* DUID_TYPE_LLT */ uint16_t htype; uint32_t time; uint8_t haddr[0]; } _packed_ llt; struct { - /* DHCP6_DUID_EN */ + /* DUID_TYPE_EN */ uint32_t pen; uint8_t id[8]; } _packed_ en; struct { - /* DHCP6_DUID_LL */ + /* DUID_TYPE_LL */ int16_t htype; uint8_t haddr[0]; } _packed_ ll; struct { - /* DHCP6_DUID_UUID */ + /* DUID_TYPE_UUID */ sd_id128_t uuid; } _packed_ uuid; struct { @@ -69,34 +69,6 @@ struct duid { }; } _packed_; +int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len); int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len); int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id); - -static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) { - struct duid d; - - assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL); - - switch (duid_type) { - case DUID_TYPE_LLT: - if (duid_len <= sizeof(d.llt)) - return -EINVAL; - break; - case DUID_TYPE_EN: - if (duid_len != sizeof(d.en)) - return -EINVAL; - break; - case DUID_TYPE_LL: - if (duid_len <= sizeof(d.ll)) - return -EINVAL; - break; - case DUID_TYPE_UUID: - if (duid_len != sizeof(d.uuid)) - return -EINVAL; - break; - default: - /* accept unknown type in order to be forward compatible */ - break; - } - return 0; -} diff --git a/src/systemd/src/libsystemd-network/dhcp-internal.h b/src/systemd/src/libsystemd-network/dhcp-internal.h index 4662b0d8..99f69089 100644 --- a/src/systemd/src/libsystemd-network/dhcp-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-internal.h @@ -65,4 +65,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum); #define DHCP_CLIENT_DONT_DESTROY(client) \ _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) -#define log_dhcp_client(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) +#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) +#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c index 15a0bb7b..f1856d0a 100644 --- a/src/systemd/src/libsystemd-network/dhcp-network.c +++ b/src/systemd/src/libsystemd-network/dhcp-network.c @@ -109,9 +109,9 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link, return -errno; link->ll.sll_family = AF_PACKET; - link->ll.sll_protocol = htons(ETH_P_IP); + link->ll.sll_protocol = htobe16(ETH_P_IP); link->ll.sll_ifindex = ifindex; - link->ll.sll_hatype = htons(arp_type); + link->ll.sll_hatype = htobe16(arp_type); link->ll.sll_halen = mac_addr_len; memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len); diff --git a/src/systemd/src/libsystemd-network/dhcp-protocol.h b/src/systemd/src/libsystemd-network/dhcp-protocol.h index 3e32484c..5cf7abbf 100644 --- a/src/systemd/src/libsystemd-network/dhcp-protocol.h +++ b/src/systemd/src/libsystemd-network/dhcp-protocol.h @@ -59,7 +59,7 @@ typedef struct DHCPPacket DHCPPacket; #define DHCP_IP_UDP_SIZE (int32_t)(sizeof(struct udphdr) + DHCP_IP_SIZE) #define DHCP_MESSAGE_SIZE (int32_t)(sizeof(DHCPMessage)) #define DHCP_DEFAULT_MIN_SIZE 576 /* the minimum internet hosts must be able to receive */ -#define DHCP_MIN_OPTIONS_SIZE DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE +#define DHCP_MIN_OPTIONS_SIZE (DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE) #define DHCP_MAGIC_COOKIE (uint32_t)(0x63825363) enum { diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h index 749086d3..945c3b97 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h @@ -55,7 +55,8 @@ struct DHCP6IA { typedef struct DHCP6IA DHCP6IA; -#define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) +#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) +#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__) int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, size_t optlen, const void *optval); diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h index 7592bc43..becc162f 100644 --- a/src/systemd/src/libsystemd-network/lldp-internal.h +++ b/src/systemd/src/libsystemd-network/lldp-internal.h @@ -28,6 +28,8 @@ #include "prioq.h" struct sd_lldp { + unsigned n_ref; + int ifindex; int fd; diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.c b/src/systemd/src/libsystemd-network/lldp-neighbor.c index ce1d89b6..afede1e7 100644 --- a/src/systemd/src/libsystemd-network/lldp-neighbor.c +++ b/src/systemd/src/libsystemd-network/lldp-neighbor.c @@ -199,7 +199,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { assert(n); if (n->raw_size < sizeof(struct ether_header)) { - log_lldp("Recieved truncated packet, ignoring."); + log_lldp("Received truncated packet, ignoring."); return -EBADMSG; } @@ -362,9 +362,16 @@ end_marker: void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) { assert(n); - if (n->ttl > 0) - n->until = usec_add(now(clock_boottime_or_monotonic()), n->ttl * USEC_PER_SEC); - else + if (n->ttl > 0) { + usec_t base; + + /* Use the packet's timestamp if there is one known */ + base = triple_timestamp_by_clock(&n->timestamp, clock_boottime_or_monotonic()); + if (base <= 0 || base == USEC_INFINITY) + base = now(clock_boottime_or_monotonic()); /* Otherwise, take the current time */ + + n->until = usec_add(base, n->ttl * USEC_PER_SEC); + } else n->until = 0; if (n->lldp) @@ -590,11 +597,11 @@ done: return 0; } -_public_ int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret) { +_public_ int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec) { assert_return(n, -EINVAL); - assert_return(ret, -EINVAL); + assert_return(ret_sec, -EINVAL); - *ret = n->ttl; + *ret_sec = n->ttl; return 0; } @@ -653,7 +660,7 @@ _public_ int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint return 0; } -int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) { +_public_ int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) { _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; int r; @@ -670,7 +677,7 @@ int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t ra return r; *ret = n; - n = 0; + n = NULL; return r; } @@ -681,7 +688,7 @@ _public_ int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) { assert(n->raw_size >= sizeof(struct ether_header)); n->rindex = sizeof(struct ether_header); - return 0; + return n->rindex < n->raw_size; } _public_ int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n) { @@ -695,7 +702,7 @@ _public_ int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n) { if (n->rindex + 2 > n->raw_size) /* Truncated message */ return -EBADMSG; - length = LLDP_NEIGHBOR_LENGTH(n); + length = LLDP_NEIGHBOR_TLV_LENGTH(n); if (n->rindex + 2 + length > n->raw_size) return -EBADMSG; @@ -713,7 +720,7 @@ _public_ int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type) { if (n->rindex + 2 > n->raw_size) return -EBADMSG; - *type = LLDP_NEIGHBOR_TYPE(n); + *type = LLDP_NEIGHBOR_TLV_TYPE(n); return 0; } @@ -745,14 +752,14 @@ _public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], u if (r == 0) return -ENXIO; - length = LLDP_NEIGHBOR_LENGTH(n); + length = LLDP_NEIGHBOR_TLV_LENGTH(n); if (length < 4) return -EBADMSG; if (n->rindex + 2 + length > n->raw_size) return -EBADMSG; - d = LLDP_NEIGHBOR_DATA(n); + d = LLDP_NEIGHBOR_TLV_DATA(n); memcpy(oui, d, 3); *subtype = d[3]; @@ -784,8 +791,7 @@ _public_ int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, if (n->rindex + 2 > n->raw_size) return -EBADMSG; - length = LLDP_NEIGHBOR_LENGTH(n); - + length = LLDP_NEIGHBOR_TLV_LENGTH(n); if (n->rindex + 2 + length > n->raw_size) return -EBADMSG; @@ -794,3 +800,16 @@ _public_ int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, return 0; } + +_public_ int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret) { + assert_return(n, -EINVAL); + assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP); + assert_return(clock_supported(clock), -EOPNOTSUPP); + assert_return(ret, -EINVAL); + + if (!triple_timestamp_is_set(&n->timestamp)) + return -ENODATA; + + *ret = triple_timestamp_by_clock(&n->timestamp, clock); + return 0; +} diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.h b/src/systemd/src/libsystemd-network/lldp-neighbor.h index f203bfa6..c1a7606d 100644 --- a/src/systemd/src/libsystemd-network/lldp-neighbor.h +++ b/src/systemd/src/libsystemd-network/lldp-neighbor.h @@ -43,6 +43,8 @@ struct sd_lldp_neighbor { sd_lldp *lldp; unsigned n_ref; + triple_timestamp timestamp; + usec_t until; unsigned prioq_idx; @@ -81,18 +83,18 @@ static inline void *LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor *n) { return (uint8_t*) n + ALIGN(sizeof(sd_lldp_neighbor)); } -static inline uint8_t LLDP_NEIGHBOR_TYPE(const sd_lldp_neighbor *n) { +static inline uint8_t LLDP_NEIGHBOR_TLV_TYPE(const sd_lldp_neighbor *n) { return ((uint8_t*) LLDP_NEIGHBOR_RAW(n))[n->rindex] >> 1; } -static inline size_t LLDP_NEIGHBOR_LENGTH(const sd_lldp_neighbor *n) { +static inline size_t LLDP_NEIGHBOR_TLV_LENGTH(const sd_lldp_neighbor *n) { uint8_t *p; p = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex; return p[1] + (((size_t) (p[0] & 1)) << 8); } -static inline void* LLDP_NEIGHBOR_DATA(const sd_lldp_neighbor *n) { +static inline void* LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor *n) { return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2; } diff --git a/src/systemd/src/libsystemd-network/lldp-network.c b/src/systemd/src/libsystemd-network/lldp-network.c index 658448f6..bba3a752 100644 --- a/src/systemd/src/libsystemd-network/lldp-network.c +++ b/src/systemd/src/libsystemd-network/lldp-network.c @@ -59,7 +59,8 @@ int lldp_network_bind_raw_socket(int ifindex) { assert(ifindex > 0); - fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, htons(ETHERTYPE_LLDP)); + fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, + htobe16(ETHERTYPE_LLDP)); if (fd < 0) return -errno; diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c index 55fcc1da..46bddfeb 100644 --- a/src/systemd/src/libsystemd-network/network-internal.c +++ b/src/systemd/src/libsystemd-network/network-internal.c @@ -26,16 +26,16 @@ #include "sd-ndisc.h" #include "alloc-util.h" -#if 0 /* NM_IGNORED */ #include "condition.h" #include "conf-parser.h" -#endif /* NM_IGNORED */ #include "dhcp-lease-internal.h" +#include "ether-addr-util.h" #include "hexdecoct.h" #include "log.h" #include "network-internal.h" #include "parse-util.h" #include "siphash24.h" +#include "socket-util.h" #include "string-util.h" #include "strv.h" #include "utf8.h" @@ -105,16 +105,16 @@ bool net_match_config(const struct ether_addr *match_mac, const char *dev_type, const char *dev_name) { - if (match_host && !condition_test(match_host)) + if (match_host && condition_test(match_host) <= 0) return false; - if (match_virt && !condition_test(match_virt)) + if (match_virt && condition_test(match_virt) <= 0) return false; - if (match_kernel && !condition_test(match_kernel)) + if (match_kernel && condition_test(match_kernel) <= 0) return false; - if (match_arch && !condition_test(match_arch)) + if (match_arch && condition_test(match_arch) <= 0) return false; if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) @@ -180,58 +180,19 @@ int config_parse_net_condition(const char *unit, return 0; } -int config_parse_ifname(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - char **s = data; - _cleanup_free_ char *n = NULL; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - n = strdup(rvalue); - if (!n) - return log_oom(); - - if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue); - return 0; - } - - free(*s); - if (*n) { - *s = n; - n = NULL; - } else - *s = NULL; - - return 0; -} - -int config_parse_ifnames(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +int config_parse_ifnames( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { char ***sv = data; - const char *word, *state; - size_t l; int r; assert(filename); @@ -239,22 +200,27 @@ int config_parse_ifnames(const char *unit, assert(rvalue); assert(data); - FOREACH_WORD(word, l, rvalue, state) { - char *n; + for (;;) { + _cleanup_free_ char *word = NULL; - n = strndup(word, l); - if (!n) - return log_oom(); + r = extract_first_word(&rvalue, &word, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue); + return 0; + } + if (r == 0) + break; - if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue); - free(n); + if (!ifname_valid(word)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue); return 0; } - r = strv_consume(sv, n); + r = strv_push(sv, word); if (r < 0) return log_oom(); + + word = NULL; } return 0; @@ -310,6 +276,8 @@ int config_parse_hwaddr(const char *unit, void *userdata) { struct ether_addr **hwaddr = data; struct ether_addr *n; + const char *start; + size_t offset; int r; assert(filename); @@ -321,14 +289,10 @@ int config_parse_hwaddr(const char *unit, if (!n) return log_oom(); - r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &n->ether_addr_octet[0], - &n->ether_addr_octet[1], - &n->ether_addr_octet[2], - &n->ether_addr_octet[3], - &n->ether_addr_octet[4], - &n->ether_addr_octet[5]); - if (r != 6) { + start = rvalue + strspn(rvalue, WHITESPACE); + r = ether_addr_from_string(start, n, &offset); + + if (r || (start[offset + strspn(start + offset, WHITESPACE)] != '\0')) { log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue); free(n); return 0; @@ -360,8 +324,9 @@ int config_parse_iaid(const char *unit, r = safe_atou32(rvalue, &iaid); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue); - return r; + log_syntax(unit, LOG_ERR, filename, line, r, + "Unable to read IAID, ignoring assignment: %s", rvalue); + return 0; } *((uint32_t *)data) = iaid; @@ -385,28 +350,28 @@ void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) { int deserialize_in_addrs(struct in_addr **ret, const char *string) { _cleanup_free_ struct in_addr *addresses = NULL; int size = 0; - const char *word, *state; - size_t len; assert(ret); assert(string); - FOREACH_WORD(word, len, string, state) { - _cleanup_free_ char *addr_str = NULL; + for (;;) { + _cleanup_free_ char *word = NULL; struct in_addr *new_addresses; int r; + r = extract_first_word(&string, &word, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + new_addresses = realloc(addresses, (size + 1) * sizeof(struct in_addr)); if (!new_addresses) return -ENOMEM; else addresses = new_addresses; - addr_str = strndup(word, len); - if (!addr_str) - return -ENOMEM; - - r = inet_pton(AF_INET, addr_str, &(addresses[size])); + r = inet_pton(AF_INET, word, &(addresses[size])); if (r <= 0) continue; @@ -419,45 +384,48 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) { return size; } -void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, - size_t size) { +void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, size_t size) { unsigned i; assert(f); assert(addresses); assert(size); - for (i = 0; i < size; i++) - fprintf(f, SD_NDISC_ADDRESS_FORMAT_STR"%s", - SD_NDISC_ADDRESS_FORMAT_VAL(addresses[i]), - (i < (size - 1)) ? " ": ""); + for (i = 0; i < size; i++) { + char buffer[INET6_ADDRSTRLEN]; + + fputs(inet_ntop(AF_INET6, addresses+i, buffer, sizeof(buffer)), f); + + if (i < size - 1) + fputc(' ', f); + } } int deserialize_in6_addrs(struct in6_addr **ret, const char *string) { _cleanup_free_ struct in6_addr *addresses = NULL; int size = 0; - const char *word, *state; - size_t len; assert(ret); assert(string); - FOREACH_WORD(word, len, string, state) { - _cleanup_free_ char *addr_str = NULL; + for (;;) { + _cleanup_free_ char *word = NULL; struct in6_addr *new_addresses; int r; + r = extract_first_word(&string, &word, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + new_addresses = realloc(addresses, (size + 1) * sizeof(struct in6_addr)); if (!new_addresses) return -ENOMEM; else addresses = new_addresses; - addr_str = strndup(word, len); - if (!addr_str) - return -ENOMEM; - - r = inet_pton(AF_INET6, addr_str, &(addresses[size])); + r = inet_pton(AF_INET6, word, &(addresses[size])); if (r <= 0) continue; @@ -498,29 +466,29 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) { _cleanup_free_ struct sd_dhcp_route *routes = NULL; size_t size = 0, allocated = 0; - const char *word, *state; - size_t len; assert(ret); assert(ret_size); assert(ret_allocated); assert(string); - FOREACH_WORD(word, len, string, state) { - /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */ - _cleanup_free_ char* entry = NULL; + /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */ + for (;;) { + _cleanup_free_ char *word = NULL; char *tok, *tok_end; unsigned n; int r; - if (!GREEDY_REALLOC(routes, allocated, size + 1)) - return -ENOMEM; + r = extract_first_word(&string, &word, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; - entry = strndup(word, len); - if (!entry) + if (!GREEDY_REALLOC(routes, allocated, size + 1)) return -ENOMEM; - tok = entry; + tok = word; /* get the subnet */ tok_end = strchr(tok, '/'); diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h index 955cc898..5bcd5771 100644 --- a/src/systemd/src/libsystemd-network/network-internal.h +++ b/src/systemd/src/libsystemd-network/network-internal.h @@ -23,7 +23,6 @@ #include "sd-dhcp-lease.h" -#if 0 /* NM_IGNORED */ #include "condition.h" #include "udev.h" @@ -51,10 +50,6 @@ int config_parse_hwaddr(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_ifname(const char *unit, const char *filename, unsigned line, - const char *section, unsigned section_line, const char *lvalue, - int ltype, const char *rvalue, void *data, void *userdata); - int config_parse_ifnames(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); @@ -69,7 +64,6 @@ int config_parse_iaid(const char *unit, const char *filename, unsigned line, int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result); const char *net_get_name(struct udev_device *device); -#endif /* NM_IGNORED */ void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size); int deserialize_in_addrs(struct in_addr **addresses, const char *string); diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index 758dba4b..f740075a 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -55,7 +55,7 @@ struct sd_dhcp_client { sd_event *event; int event_priority; sd_event_source *timeout_resend; - int index; + int ifindex; int fd; union sockaddr_union link; sd_event_source *receive_message; @@ -103,7 +103,7 @@ struct sd_dhcp_client { sd_event_source *timeout_t1; sd_event_source *timeout_t2; sd_event_source *timeout_expire; - sd_dhcp_client_callback_t cb; + sd_dhcp_client_callback_t callback; void *userdata; sd_dhcp_lease *lease; usec_t start_delay; @@ -117,17 +117,26 @@ static const uint8_t default_req_opts[] = { SD_DHCP_OPTION_DOMAIN_NAME_SERVER, }; -static int client_receive_message_raw(sd_event_source *s, int fd, - uint32_t revents, void *userdata); -static int client_receive_message_udp(sd_event_source *s, int fd, - uint32_t revents, void *userdata); +static int client_receive_message_raw( + sd_event_source *s, + int fd, + uint32_t revents, + void *userdata); +static int client_receive_message_udp( + sd_event_source *s, + int fd, + uint32_t revents, + void *userdata); static void client_stop(sd_dhcp_client *client, int error); -int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb, - void *userdata) { +int sd_dhcp_client_set_callback( + sd_dhcp_client *client, + sd_dhcp_client_callback_t cb, + void *userdata) { + assert_return(client, -EINVAL); - client->cb = cb; + client->callback = cb; client->userdata = userdata; return 0; @@ -145,10 +154,10 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { size_t i; assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); switch(option) { + case SD_DHCP_OPTION_PAD: case SD_DHCP_OPTION_OVERLOAD: case SD_DHCP_OPTION_MESSAGE_TYPE: @@ -173,11 +182,12 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { return 0; } -int sd_dhcp_client_set_request_address(sd_dhcp_client *client, - const struct in_addr *last_addr) { +int sd_dhcp_client_set_request_address( + sd_dhcp_client *client, + const struct in_addr *last_addr) { + assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); if (last_addr) client->last_addr = last_addr->s_addr; @@ -187,19 +197,22 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client, return 0; } -int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) { - assert_return(client, -EINVAL); - assert_return (IN_SET(client->state, DHCP_STATE_INIT, - DHCP_STATE_STOPPED), -EBUSY); - assert_return(interface_index > 0, -EINVAL); +int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) { - client->index = interface_index; + assert_return(client, -EINVAL); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY); + assert_return(ifindex > 0, -EINVAL); + client->ifindex = ifindex; return 0; } -int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, - size_t addr_len, uint16_t arp_type) { +int sd_dhcp_client_set_mac( + sd_dhcp_client *client, + const uint8_t *addr, + size_t addr_len, + uint16_t arp_type) { + DHCP_CLIENT_DONT_DESTROY(client); bool need_restart = false; @@ -220,8 +233,7 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, return 0; if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { - log_dhcp_client(client, "Changing MAC address on running DHCP " - "client, restarting"); + log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting"); need_restart = true; client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); } @@ -236,8 +248,11 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, return 0; } -int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type, - const uint8_t **data, size_t *data_len) { +int sd_dhcp_client_get_client_id( + sd_dhcp_client *client, + uint8_t *type, + const uint8_t **data, + size_t *data_len) { assert_return(client, -EINVAL); assert_return(type, -EINVAL); @@ -256,8 +271,12 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type, return 0; } -int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, - const uint8_t *data, size_t data_len) { +int sd_dhcp_client_set_client_id( + sd_dhcp_client *client, + uint8_t type, + const uint8_t *data, + size_t data_len) { + DHCP_CLIENT_DONT_DESTROY(client); bool need_restart = false; @@ -266,14 +285,17 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL); switch (type) { + case ARPHRD_ETHER: if (data_len != ETH_ALEN) return -EINVAL; break; + case ARPHRD_INFINIBAND: if (data_len != INFINIBAND_ALEN) return -EINVAL; break; + default: break; } @@ -301,18 +323,37 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, } #if 0 /* NM_IGNORED */ -int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, - uint16_t duid_type, uint8_t *duid, size_t duid_len) { +/** + * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid + * without further modification. Otherwise, if duid_type is supported, DUID + * is set based on that type. Otherwise, an error is returned. + */ +int sd_dhcp_client_set_iaid_duid( + sd_dhcp_client *client, + uint32_t iaid, + uint16_t duid_type, + const void *duid, + size_t duid_len) { + DHCP_CLIENT_DONT_DESTROY(client); int r; + size_t len; + assert_return(client, -EINVAL); - zero(client->client_id); + assert_return(duid_len == 0 || duid != NULL, -EINVAL); + if (duid != NULL) { + r = dhcp_validate_duid_len(duid_type, duid_len); + if (r < 0) + return r; + } + + zero(client->client_id); client->client_id.type = 255; /* If IAID is not configured, generate it. */ if (iaid == 0) { - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); if (r < 0) @@ -320,22 +361,18 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, } else client->client_id.ns.iaid = htobe32(iaid); - /* If DUID is not configured, generate DUID-EN. */ - if (duid_len == 0) { - r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, - &duid_len); - if (r < 0) - return r; - } else { - r = dhcp_validate_duid_len(client->client_id.type, duid_len); - if (r < 0) - return r; + if (duid != NULL) { client->client_id.ns.duid.type = htobe16(duid_type); memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len); - duid_len += sizeof(client->client_id.ns.duid.type); - } + len = sizeof(client->client_id.ns.duid.type) + duid_len; + } else if (duid_type == DUID_TYPE_EN) { + r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len); + if (r < 0) + return r; + } else + return -EOPNOTSUPP; - client->client_id_len = sizeof(client->client_id.type) + duid_len + + client->client_id_len = sizeof(client->client_id.type) + len + sizeof(client->client_id.ns.iaid); if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { @@ -348,8 +385,10 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, } #endif /* NM_IGNORED */ -int sd_dhcp_client_set_hostname(sd_dhcp_client *client, - const char *hostname) { +int sd_dhcp_client_set_hostname( + sd_dhcp_client *client, + const char *hostname) { + char *new_hostname = NULL; assert_return(client, -EINVAL); @@ -372,8 +411,10 @@ int sd_dhcp_client_set_hostname(sd_dhcp_client *client, return 0; } -int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, - const char *vci) { +int sd_dhcp_client_set_vendor_class_identifier( + sd_dhcp_client *client, + const char *vci) { + char *new_vci = NULL; assert_return(client, -EINVAL); @@ -400,28 +441,29 @@ int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) { int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) { assert_return(client, -EINVAL); - assert_return(ret, -EINVAL); if (client->state != DHCP_STATE_BOUND && client->state != DHCP_STATE_RENEWING && client->state != DHCP_STATE_REBINDING) return -EADDRNOTAVAIL; - *ret = client->lease; + if (ret) + *ret = client->lease; return 0; } static void client_notify(sd_dhcp_client *client, int event) { - if (client->cb) - client->cb(client, event, client->userdata); + assert(client); + + if (client->callback) + client->callback(client, event, client->userdata); } static int client_initialize(sd_dhcp_client *client) { assert_return(client, -EINVAL); - client->receive_message = - sd_event_source_unref(client->receive_message); + client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); @@ -456,8 +498,13 @@ static void client_stop(sd_dhcp_client *client, int error) { client_initialize(client); } -static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret, - uint8_t type, size_t *_optlen, size_t *_optoffset) { +static int client_message_init( + sd_dhcp_client *client, + DHCPPacket **ret, + uint8_t type, + size_t *_optlen, + size_t *_optoffset) { + _cleanup_free_ DHCPPacket *packet = NULL; size_t optlen, optoffset, size; be16_t max_size; @@ -525,7 +572,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret, client->client_id.type = 255; - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid); if (r < 0) return r; @@ -598,8 +645,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret, return 0; } -static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t *optoffset, - const char *fqdn) { +static int client_append_fqdn_option( + DHCPMessage *message, + size_t optlen, + size_t *optoffset, + const char *fqdn) { + uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH]; int r; @@ -616,8 +667,11 @@ static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t return r; } -static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet, - size_t len) { +static int dhcp_client_send_raw( + sd_dhcp_client *client, + DHCPPacket *packet, + size_t len) { + dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT, INADDR_BROADCAST, DHCP_PORT_SERVER, len); @@ -704,8 +758,9 @@ static int client_send_request(sd_dhcp_client *client) { size_t optoffset, optlen; int r; - r = client_message_init(client, &request, DHCP_REQUEST, - &optlen, &optoffset); + assert(client); + + r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset); if (r < 0) return r; @@ -802,18 +857,23 @@ static int client_send_request(sd_dhcp_client *client) { return r; switch (client->state) { + case DHCP_STATE_REQUESTING: log_dhcp_client(client, "REQUEST (requesting)"); break; + case DHCP_STATE_INIT_REBOOT: log_dhcp_client(client, "REQUEST (init-reboot)"); break; + case DHCP_STATE_RENEWING: log_dhcp_client(client, "REQUEST (renewing)"); break; + case DHCP_STATE_REBINDING: log_dhcp_client(client, "REQUEST (rebinding)"); break; + default: log_dhcp_client(client, "REQUEST (invalid)"); break; @@ -824,8 +884,11 @@ static int client_send_request(sd_dhcp_client *client) { static int client_start(sd_dhcp_client *client); -static int client_timeout_resend(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_resend( + sd_event_source *s, + uint64_t usec, + void *userdata) { + sd_dhcp_client *client = userdata; DHCP_CLIENT_DONT_DESTROY(client); usec_t next_timeout = 0; @@ -842,6 +905,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, goto error; switch (client->state) { + case DHCP_STATE_RENEWING: time_left = (client->lease->t2 - client->lease->t1) / 2; @@ -969,8 +1033,10 @@ error: return 0; } -static int client_initialize_io_events(sd_dhcp_client *client, - sd_event_io_handler_t io_callback) { +static int client_initialize_io_events( + sd_dhcp_client *client, + sd_event_io_handler_t io_callback) { + int r; assert(client); @@ -1037,8 +1103,7 @@ error: } -static int client_initialize_events(sd_dhcp_client *client, - sd_event_io_handler_t io_callback) { +static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) { client_initialize_io_events(client, io_callback); client_initialize_time_events(client); @@ -1050,15 +1115,14 @@ static int client_start_delayed(sd_dhcp_client *client) { assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(client->fd < 0, -EBUSY); assert_return(client->xid == 0, -EINVAL); - assert_return(client->state == DHCP_STATE_INIT || - client->state == DHCP_STATE_INIT_REBOOT, -EBUSY); + assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY); client->xid = random_u32(); - r = dhcp_network_bind_raw_socket(client->index, &client->link, + r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid, client->mac_addr, client->mac_addr_len, client->arp_type); if (r < 0) { @@ -1078,8 +1142,7 @@ static int client_start(sd_dhcp_client *client) { return client_start_delayed(client); } -static int client_timeout_expire(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; DHCP_CLIENT_DONT_DESTROY(client); @@ -1101,13 +1164,15 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) DHCP_CLIENT_DONT_DESTROY(client); int r; + assert(client); + client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); client->state = DHCP_STATE_REBINDING; client->attempt = 1; - r = dhcp_network_bind_raw_socket(client->index, &client->link, + r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid, client->mac_addr, client->mac_addr_len, client->arp_type); if (r < 0) { @@ -1119,8 +1184,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) return client_initialize_events(client, client_receive_message_raw); } -static int client_timeout_t1(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; DHCP_CLIENT_DONT_DESTROY(client); @@ -1130,8 +1194,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, return client_initialize_time_events(client); } -static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, - size_t len) { +static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) { _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL; int r; @@ -1182,8 +1245,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, return 0; } -static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, - size_t len) { +static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) { int r; r = dhcp_option_parse(force, len, NULL, NULL, NULL); @@ -1195,8 +1257,7 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, return 0; } -static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, - size_t len) { +static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) { _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL; _cleanup_free_ char *error_message = NULL; int r; @@ -1424,8 +1485,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { return 0; } -static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, - int len) { +static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) { DHCP_CLIENT_DONT_DESTROY(client); char time_string[FORMAT_TIMESPAN_MAX]; int r = 0, notify_event = 0; @@ -1571,11 +1631,15 @@ error: return r; } -static int client_receive_message_udp(sd_event_source *s, int fd, - uint32_t revents, void *userdata) { +static int client_receive_message_udp( + sd_event_source *s, + int fd, + uint32_t revents, + void *userdata) { + sd_dhcp_client *client = userdata; _cleanup_free_ DHCPMessage *message = NULL; - const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } }; + const struct ether_addr zero_mac = {}; const struct ether_addr *expected_chaddr = NULL; uint8_t expected_hlen = 0; ssize_t len, buflen; @@ -1591,14 +1655,14 @@ static int client_receive_message_udp(sd_event_source *s, int fd, if (!message) return -ENOMEM; - len = read(fd, message, buflen); + len = recv(fd, message, buflen, 0); if (len < 0) { if (errno == EAGAIN || errno == EINTR) return 0; - log_dhcp_client(client, "Could not receive message from UDP socket: %m"); - return -errno; - } else if ((size_t)len < sizeof(DHCPMessage)) { + return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m"); + } + if ((size_t) len < sizeof(DHCPMessage)) { log_dhcp_client(client, "Too small to be a DHCP message: ignoring"); return 0; } @@ -1649,8 +1713,12 @@ static int client_receive_message_udp(sd_event_source *s, int fd, return client_handle_message(client, message, len); } -static int client_receive_message_raw(sd_event_source *s, int fd, - uint32_t revents, void *userdata) { +static int client_receive_message_raw( + sd_event_source *s, + int fd, + uint32_t revents, + void *userdata) { + sd_dhcp_client *client = userdata; _cleanup_free_ DHCPPacket *packet = NULL; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; @@ -1725,7 +1793,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { r = client_start(client); if (r >= 0) - log_dhcp_client(client, "STARTED on ifindex %i", client->index); + log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex); return r; } @@ -1769,8 +1837,7 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client) { } sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { - if (!client) - return NULL; + assert_return(client, NULL); return client->event; } @@ -1826,13 +1893,12 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) { client->n_ref = 1; client->state = DHCP_STATE_INIT; - client->index = -1; + client->ifindex = -1; client->fd = -1; client->attempt = 1; client->mtu = DHCP_DEFAULT_MIN_SIZE; client->req_opts_size = ELEMENTSOF(default_req_opts); - client->req_opts = memdup(default_req_opts, client->req_opts_size); if (!client->req_opts) return -ENOMEM; diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 8fa1822f..a05bde63 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -47,7 +47,7 @@ struct sd_dhcp6_client { enum DHCP6State state; sd_event *event; int event_priority; - int index; + int ifindex; struct in6_addr local_address; uint8_t mac_addr[MAX_MAC_ADDR_LEN]; size_t mac_addr_len; @@ -66,7 +66,7 @@ struct sd_dhcp6_client { uint8_t retransmit_count; sd_event_source *timeout_resend; sd_event_source *timeout_resend_expire; - sd_dhcp6_client_callback_t cb; + sd_dhcp6_client_callback_t callback; void *userdata; struct duid duid; size_t duid_len; @@ -113,27 +113,33 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int); static int client_start(sd_dhcp6_client *client, enum DHCP6State state); -int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_callback_t cb, void *userdata) { +int sd_dhcp6_client_set_callback( + sd_dhcp6_client *client, + sd_dhcp6_client_callback_t cb, + void *userdata) { + assert_return(client, -EINVAL); - client->cb = cb; + client->callback = cb; client->userdata = userdata; return 0; } -int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) { - assert_return(client, -EINVAL); - assert_return(interface_index >= -1, -EINVAL); +int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) { + assert_return(client, -EINVAL); + assert_return(ifindex >= -1, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - client->index = interface_index; - + client->ifindex = ifindex; return 0; } -int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address) { +int sd_dhcp6_client_set_local_address( + sd_dhcp6_client *client, + const struct in6_addr *local_address) { + assert_return(client, -EINVAL); assert_return(local_address, -EINVAL); assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL); @@ -182,20 +188,38 @@ static int client_ensure_duid(sd_dhcp6_client *client) { return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); } -int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type, - uint8_t *duid, size_t duid_len) { +/** + * Sets DUID. If duid is non-null, the DUID is set to duid_type + duid + * without further modification. Otherwise, if duid_type is supported, DUID + * is set based on that type. Otherwise, an error is returned. + */ +int sd_dhcp6_client_set_duid( + sd_dhcp6_client *client, + uint16_t duid_type, + const void *duid, + size_t duid_len) { + int r; assert_return(client, -EINVAL); + assert_return(duid_len == 0 || duid != NULL, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - if (duid_len > 0) { + if (duid != NULL) { r = dhcp_validate_duid_len(duid_type, duid_len); if (r < 0) return r; + } + + if (duid != NULL) { client->duid.type = htobe16(duid_type); memcpy(&client->duid.raw.data, duid, duid_len); - client->duid_len = duid_len + sizeof(client->duid.type); - } + client->duid_len = sizeof(client->duid.type) + duid_len; + } else if (duid_type == DUID_TYPE_EN) { + r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); + if (r < 0) + return r; + } else + return -EOPNOTSUPP; return 0; } @@ -236,6 +260,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY); switch(option) { + case SD_DHCP6_OPTION_DNS_SERVERS: case SD_DHCP6_OPTION_DOMAIN_LIST: case SD_DHCP6_OPTION_SNTP_SERVERS: @@ -272,20 +297,25 @@ int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) { } static void client_notify(sd_dhcp6_client *client, int event) { - if (client->cb) - client->cb(client, event, client->userdata); + assert(client); + + if (client->callback) + client->callback(client, event, client->userdata); } static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) { + assert(client); + if (client->lease) { dhcp6_lease_clear_timers(&client->lease->ia); sd_dhcp6_lease_unref(client->lease); } + client->lease = lease; } static int client_reset(sd_dhcp6_client *client) { - assert_return(client, -EINVAL); + assert(client); client_set_lease(client, NULL); @@ -333,6 +363,8 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { usec_t elapsed_usec; be16_t elapsed_time; + assert(client); + len = sizeof(DHCP6Message) + optlen; message = malloc0(len); @@ -431,13 +463,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return 0; } -static int client_timeout_t2(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp6_client *client = userdata; - assert_return(s, -EINVAL); - assert_return(client, -EINVAL); - assert_return(client->lease, -EINVAL); + assert(s); + assert(client); + assert(client->lease); client->lease->ia.timeout_t2 = sd_event_source_unref(client->lease->ia.timeout_t2); @@ -449,13 +480,12 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, return 0; } -static int client_timeout_t1(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp6_client *client = userdata; - assert_return(s, -EINVAL); - assert_return(client, -EINVAL); - assert_return(client->lease, -EINVAL); + assert(s); + assert(client); + assert(client->lease); client->lease->ia.timeout_t1 = sd_event_source_unref(client->lease->ia.timeout_t1); @@ -467,8 +497,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, return 0; } -static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp6_client *client = userdata; DHCP6_CLIENT_DONT_DESTROY(client); enum DHCP6State state; @@ -494,8 +523,7 @@ static usec_t client_timeout_compute_random(usec_t val) { (random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC; } -static int client_timeout_resend(sd_event_source *s, uint64_t usec, - void *userdata) { +static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) { int r = 0; sd_dhcp6_client *client = userdata; usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0; @@ -655,16 +683,18 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { if (client->ia_na.id) return 0; - r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->ia_na.id); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.id); if (r < 0) return r; return 0; } -static int client_parse_message(sd_dhcp6_client *client, - DHCP6Message *message, size_t len, - sd_dhcp6_lease *lease) { +static int client_parse_message( + sd_dhcp6_client *client, + DHCP6Message *message, + size_t len, + sd_dhcp6_lease *lease) { int r; uint8_t *optval, *option, *id = NULL; uint16_t optcode, status; @@ -672,6 +702,11 @@ static int client_parse_message(sd_dhcp6_client *client, bool clientid = false; be32_t iaid_lease; + assert(client); + assert(message); + assert(len >= sizeof(DHCP6Message)); + assert(lease); + option = (uint8_t *)message + sizeof(DHCP6Message); len -= sizeof(DHCP6Message); @@ -816,9 +851,12 @@ static int client_parse_message(sd_dhcp6_client *client, } static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, size_t len) { - int r; _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; bool rapid_commit; + int r; + + assert(client); + assert(reply); if (reply->type != DHCP6_REPLY) return 0; @@ -847,9 +885,9 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si } static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *advertise, size_t len) { - int r; _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL; uint8_t pref_advertise = 0, pref_lease = 0; + int r; if (advertise->type != DHCP6_ADVERTISE) return 0; @@ -880,7 +918,12 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver return r; } -static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) { +static int client_receive_message( + sd_event_source *s, + int fd, uint32_t + revents, + void *userdata) { + sd_dhcp6_client *client = userdata; DHCP6_CLIENT_DONT_DESTROY(client); _cleanup_free_ DHCP6Message *message = NULL; @@ -899,16 +942,18 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, if (!message) return -ENOMEM; - len = read(fd, message, buflen); + len = recv(fd, message, buflen, 0); if (len < 0) { if (errno == EAGAIN || errno == EINTR) return 0; - log_dhcp6_client(client, "Could not receive message from UDP socket: %m"); + return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m"); - return -errno; - } else if ((size_t)len < sizeof(DHCP6Message)) + } + if ((size_t) len < sizeof(DHCP6Message)) { + log_dhcp6_client(client, "Too small to be DHCP6 message: ignoring"); return 0; + } switch(message->type) { case DHCP6_SOLICIT: @@ -929,8 +974,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, break; default: - log_dhcp6_client(client, "unknown message type %d", - message->type); + log_dhcp6_client(client, "Unknown message type %d", message->type); return 0; } @@ -989,10 +1033,9 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, return 0; } - if (r >= 0) { + if (r >= 0) log_dhcp6_client(client, "Recv %s", dhcp6_message_type_to_string(message->type)); - } return 0; } @@ -1004,7 +1047,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(client->state != state, -EINVAL); client->timeout_resend_expire = @@ -1045,7 +1088,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { if (client->lease->ia.lifetime_t1 == 0xffffffff || client->lease->ia.lifetime_t2 == 0xffffffff) { - log_dhcp6_client(client, "infinite T1 0x%08x or T2 0x%08x", + log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x", be32toh(client->lease->ia.lifetime_t1), be32toh(client->lease->ia.lifetime_t2)); @@ -1137,12 +1180,12 @@ int sd_dhcp6_client_is_running(sd_dhcp6_client *client) { } int sd_dhcp6_client_start(sd_dhcp6_client *client) { - int r = 0; enum DHCP6State state = DHCP6_STATE_SOLICITATION; + int r = 0; assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); - assert_return(client->index > 0, -EINVAL); + assert_return(client->ifindex > 0, -EINVAL); assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) &client->local_address) > 0, -EINVAL); if (!IN_SET(client->state, DHCP6_STATE_STOPPED)) @@ -1160,9 +1203,14 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { if (r < 0) return r; - r = dhcp6_network_bind_udp_socket(client->index, &client->local_address); - if (r < 0) - return r; + r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address); + if (r < 0) { + _cleanup_free_ char *p = NULL; + + (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p); + return log_dhcp6_client_errno(client, r, + "Failed to bind to UDP socket at address %s: %m", strna(p)); + } client->fd = r; @@ -1178,7 +1226,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { goto error; r = sd_event_source_set_description(client->receive_message, - "dhcp6-receive-message"); + "dhcp6-receive-message"); if (r < 0) goto error; @@ -1186,8 +1234,8 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { state = DHCP6_STATE_INFORMATION_REQUEST; log_dhcp6_client(client, "Started in %s mode", - client->information_request? "Information request": - "Managed"); + client->information_request? "Information request": + "Managed"); return client_start(client, state); @@ -1224,8 +1272,7 @@ int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) { } sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { - if (!client) - return NULL; + assert_return(client, NULL); return client->event; } @@ -1273,15 +1320,11 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) { return -ENOMEM; client->n_ref = 1; - client->ia_na.type = SD_DHCP6_OPTION_IA_NA; - - client->index = -1; - + client->ifindex = -1; client->fd = -1; client->req_opts_len = ELEMENTSOF(default_req_opts); - client->req_opts = new0(be16_t, client->req_opts_len); if (!client->req_opts) return -ENOMEM; diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c index 9b5ce720..59830795 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c @@ -30,45 +30,30 @@ #include "alloc-util.h" #include "arp-util.h" +#include "ether-addr-util.h" #include "fd-util.h" #include "in-addr-util.h" #include "list.h" #include "random-util.h" -#include "refcnt.h" #include "siphash24.h" +#include "string-util.h" #include "util.h" /* Constants from the RFC */ -#define PROBE_WAIT 1 -#define PROBE_NUM 3 -#define PROBE_MIN 1 -#define PROBE_MAX 2 -#define ANNOUNCE_WAIT 2 -#define ANNOUNCE_NUM 2 -#define ANNOUNCE_INTERVAL 2 -#define MAX_CONFLICTS 10 -#define RATE_LIMIT_INTERVAL 60 -#define DEFEND_INTERVAL 10 - -#define IPV4ACD_NETWORK 0xA9FE0000L -#define IPV4ACD_NETMASK 0xFFFF0000L - -#define log_ipv4acd_full(ll, level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__) - -#define log_ipv4acd_debug(ll, ...) log_ipv4acd_full(ll, LOG_DEBUG, 0, ##__VA_ARGS__) -#define log_ipv4acd_info(ll, ...) log_ipv4acd_full(ll, LOG_INFO, 0, ##__VA_ARGS__) -#define log_ipv4acd_notice(ll, ...) log_ipv4acd_full(ll, LOG_NOTICE, 0, ##__VA_ARGS__) -#define log_ipv4acd_warning(ll, ...) log_ipv4acd_full(ll, LOG_WARNING, 0, ##__VA_ARGS__) -#define log_ipv4acd_error(ll, ...) log_ipv4acd_full(ll, LOG_ERR, 0, ##__VA_ARGS__) - -#define log_ipv4acd_debug_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_DEBUG, error, ##__VA_ARGS__) -#define log_ipv4acd_info_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_INFO, error, ##__VA_ARGS__) -#define log_ipv4acd_notice_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_NOTICE, error, ##__VA_ARGS__) -#define log_ipv4acd_warning_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_WARNING, error, ##__VA_ARGS__) -#define log_ipv4acd_error_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_ERR, error, ##__VA_ARGS__) +#define PROBE_WAIT_USEC (1U * USEC_PER_SEC) +#define PROBE_NUM 3U +#define PROBE_MIN_USEC (1U * USEC_PER_SEC) +#define PROBE_MAX_USEC (2U * USEC_PER_SEC) +#define ANNOUNCE_WAIT_USEC (2U * USEC_PER_SEC) +#define ANNOUNCE_NUM 2U +#define ANNOUNCE_INTERVAL_USEC (2U * USEC_PER_SEC) +#define MAX_CONFLICTS 10U +#define RATE_LIMIT_INTERVAL_USEC (60U * USEC_PER_SEC) +#define DEFEND_INTERVAL_USEC (10U * USEC_PER_SEC) typedef enum IPv4ACDState { IPV4ACD_STATE_INIT, + IPV4ACD_STATE_STARTED, IPV4ACD_STATE_WAITING_PROBE, IPV4ACD_STATE_PROBING, IPV4ACD_STATE_WAITING_ANNOUNCE, @@ -79,156 +64,164 @@ typedef enum IPv4ACDState { } IPv4ACDState; struct sd_ipv4acd { - RefCount n_ref; + unsigned n_ref; IPv4ACDState state; - int index; + int ifindex; int fd; - int iteration; - int conflict; - sd_event_source *receive_message; - sd_event_source *timer; + + unsigned n_iteration; + unsigned n_conflict; + + sd_event_source *receive_message_event_source; + sd_event_source *timer_event_source; + usec_t defend_window; be32_t address; + /* External */ struct ether_addr mac_addr; + sd_event *event; int event_priority; - sd_ipv4acd_callback_t cb; + sd_ipv4acd_callback_t callback; void* userdata; }; -sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll) { - if (ll) - assert_se(REFCNT_INC(ll->n_ref) >= 2); +#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__) +#define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__) + +static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) { + assert(acd); + assert(st < _IPV4ACD_STATE_MAX); + + if (st == acd->state && !reset_counter) + acd->n_iteration++; + else { + acd->state = st; + acd->n_iteration = 0; + } +} + +static void ipv4acd_reset(sd_ipv4acd *acd) { + assert(acd); + + acd->timer_event_source = sd_event_source_unref(acd->timer_event_source); + acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source); + + acd->fd = safe_close(acd->fd); + + ipv4acd_set_state(acd, IPV4ACD_STATE_INIT, true); +} + +sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd) { + if (!acd) + return NULL; + + assert_se(acd->n_ref >= 1); + acd->n_ref++; - return ll; + return acd; } -sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) { - if (!ll || REFCNT_DEC(ll->n_ref) > 0) +sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) { + if (!acd) return NULL; - ll->receive_message = sd_event_source_unref(ll->receive_message); - ll->fd = safe_close(ll->fd); + assert_se(acd->n_ref >= 1); + acd->n_ref--; - ll->timer = sd_event_source_unref(ll->timer); + if (acd->n_ref > 0) + return NULL; - sd_ipv4acd_detach_event(ll); + ipv4acd_reset(acd); + sd_ipv4acd_detach_event(acd); - free(ll); + free(acd); return NULL; } int sd_ipv4acd_new(sd_ipv4acd **ret) { - _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *ll = NULL; + _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *acd = NULL; assert_return(ret, -EINVAL); - ll = new0(sd_ipv4acd, 1); - if (!ll) + acd = new0(sd_ipv4acd, 1); + if (!acd) return -ENOMEM; - ll->n_ref = REFCNT_INIT; - ll->state = IPV4ACD_STATE_INIT; - ll->index = -1; - ll->fd = -1; + acd->n_ref = 1; + acd->state = IPV4ACD_STATE_INIT; + acd->ifindex = -1; + acd->fd = -1; - *ret = ll; - ll = NULL; + *ret = acd; + acd = NULL; return 0; } -static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) { - - assert(ll); - assert(st < _IPV4ACD_STATE_MAX); - - if (st == ll->state && !reset_counter) - ll->iteration++; - else { - ll->state = st; - ll->iteration = 0; - } -} +static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) { + assert(acd); -static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) { - assert(ll); + if (!acd->callback) + return; - if (ll->cb) - ll->cb(ll, event, ll->userdata); + acd->callback(acd, event, acd->userdata); } -static void ipv4acd_stop(sd_ipv4acd *ll) { - assert(ll); +int sd_ipv4acd_stop(sd_ipv4acd *acd) { + assert_return(acd, -EINVAL); - ll->receive_message = sd_event_source_unref(ll->receive_message); - ll->fd = safe_close(ll->fd); + ipv4acd_reset(acd); - ll->timer = sd_event_source_unref(ll->timer); + log_ipv4acd(acd, "STOPPED"); - log_ipv4acd_debug(ll, "STOPPED"); - - ipv4acd_set_state (ll, IPV4ACD_STATE_INIT, true); -} - -int sd_ipv4acd_stop(sd_ipv4acd *ll) { - assert_return(ll, -EINVAL); - - ipv4acd_stop(ll); - - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_STOP); + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP); return 0; } static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata); -static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) { +static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; - usec_t next_timeout; - usec_t time_now; + usec_t next_timeout, time_now; int r; - assert(sec >= 0); - assert(random_sec >= 0); - assert(ll); + assert(acd); - next_timeout = sec * USEC_PER_SEC; + next_timeout = usec; - if (random_sec) - next_timeout += random_u32() % (random_sec * USEC_PER_SEC); + if (random_usec > 0) + next_timeout += (usec_t) random_u64() % random_usec; - assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); + assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0); - r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), - time_now + next_timeout, 0, ipv4acd_on_timeout, ll); + r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd); if (r < 0) return r; - r = sd_event_source_set_priority(timer, ll->event_priority); + r = sd_event_source_set_priority(timer, acd->event_priority); if (r < 0) return r; - r = sd_event_source_set_description(timer, "ipv4acd-timer"); - if (r < 0) - return r; + (void) sd_event_source_set_description(timer, "ipv4acd-timer"); - ll->timer = sd_event_source_unref(ll->timer); - ll->timer = timer; + sd_event_source_unref(acd->timer_event_source); + acd->timer_event_source = timer; timer = NULL; return 0; } -static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) { - assert(ll); +static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) { + assert(acd); assert(arp); /* see the BPF */ - if (memcmp(arp->arp_spa, &ll->address, sizeof(ll->address)) == 0) + if (memcmp(arp->arp_spa, &acd->address, sizeof(acd->address)) == 0) return true; /* the TPA matched instead of the SPA, this is not a conflict */ @@ -236,294 +229,300 @@ static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) { } static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - sd_ipv4acd *ll = userdata; + sd_ipv4acd *acd = userdata; int r = 0; - assert(ll); + assert(acd); + + switch (acd->state) { - switch (ll->state) { - case IPV4ACD_STATE_INIT: + case IPV4ACD_STATE_STARTED: + ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true); - ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true); + if (acd->n_conflict >= MAX_CONFLICTS) { + char ts[FORMAT_TIMESPAN_MAX]; + log_ipv4acd(acd, "Max conflicts reached, delaying by %s", format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0)); - if (ll->conflict >= MAX_CONFLICTS) { - log_ipv4acd_notice(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL); - r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT); + r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); if (r < 0) - goto out; + goto fail; - ll->conflict = 0; + acd->n_conflict = 0; } else { - r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT); + r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC); if (r < 0) - goto out; + goto fail; } break; + case IPV4ACD_STATE_WAITING_PROBE: case IPV4ACD_STATE_PROBING: /* Send a probe */ - r = arp_send_probe(ll->fd, ll->index, ll->address, &ll->mac_addr); + r = arp_send_probe(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP probe: %m"); - goto out; + log_ipv4acd_errno(acd, r, "Failed to send ARP probe: %m"); + goto fail; } else { _cleanup_free_ char *address = NULL; - union in_addr_union addr = { .in.s_addr = ll->address }; + union in_addr_union addr = { .in.s_addr = acd->address }; - r = in_addr_to_string(AF_INET, &addr, &address); - if (r >= 0) - log_ipv4acd_debug(ll, "Probing %s", address); + (void) in_addr_to_string(AF_INET, &addr, &address); + log_ipv4acd(acd, "Probing %s", strna(address)); } - if (ll->iteration < PROBE_NUM - 2) { - ipv4acd_set_state(ll, IPV4ACD_STATE_PROBING, false); + if (acd->n_iteration < PROBE_NUM - 2) { + ipv4acd_set_state(acd, IPV4ACD_STATE_PROBING, false); - r = ipv4acd_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN)); + r = ipv4acd_set_next_wakeup(acd, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC)); if (r < 0) - goto out; + goto fail; } else { - ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_ANNOUNCE, true); + ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_ANNOUNCE, true); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT, 0); + r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_WAIT_USEC, 0); if (r < 0) - goto out; + goto fail; } break; case IPV4ACD_STATE_ANNOUNCING: - if (ll->iteration >= ANNOUNCE_NUM - 1) { - ipv4acd_set_state(ll, IPV4ACD_STATE_RUNNING, false); - + if (acd->n_iteration >= ANNOUNCE_NUM - 1) { + ipv4acd_set_state(acd, IPV4ACD_STATE_RUNNING, false); break; } + + /* fall through */ + case IPV4ACD_STATE_WAITING_ANNOUNCE: /* Send announcement packet */ - r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr); + r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); - goto out; + log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m"); + goto fail; } else - log_ipv4acd_debug(ll, "ANNOUNCE"); + log_ipv4acd(acd, "ANNOUNCE"); - ipv4acd_set_state(ll, IPV4ACD_STATE_ANNOUNCING, false); + ipv4acd_set_state(acd, IPV4ACD_STATE_ANNOUNCING, false); - r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0); + r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) - goto out; + goto fail; - if (ll->iteration == 0) { - ll->conflict = 0; - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_BIND); + if (acd->n_iteration == 0) { + acd->n_conflict = 0; + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_BIND); } break; + default: assert_not_reached("Invalid state."); } -out: - if (r < 0) - sd_ipv4acd_stop(ll); + return 0; - return 1; +fail: + sd_ipv4acd_stop(acd); + return 0; } -static void ipv4acd_on_conflict(sd_ipv4acd *ll) { +static void ipv4acd_on_conflict(sd_ipv4acd *acd) { _cleanup_free_ char *address = NULL; - union in_addr_union addr = { .in.s_addr = ll->address }; - int r; + union in_addr_union addr = { .in.s_addr = acd->address }; - assert(ll); + assert(acd); - ll->conflict++; + acd->n_conflict++; - r = in_addr_to_string(AF_INET, &addr, &address); - if (r >= 0) - log_ipv4acd_debug(ll, "Conflict on %s (%u)", address, ll->conflict); + (void) in_addr_to_string(AF_INET, &addr, &address); + log_ipv4acd(acd, "Conflict on %s (%u)", strna(address), acd->n_conflict); - ipv4acd_stop(ll); - - ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT); + ipv4acd_reset(acd); + ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_CONFLICT); } -static int ipv4acd_on_packet(sd_event_source *s, int fd, - uint32_t revents, void *userdata) { - sd_ipv4acd *ll = userdata; +static int ipv4acd_on_packet( + sd_event_source *s, + int fd, + uint32_t revents, + void *userdata) { + + sd_ipv4acd *acd = userdata; struct ether_arp packet; + ssize_t n; int r; - assert(ll); + assert(s); + assert(acd); assert(fd >= 0); - r = read(fd, &packet, sizeof(struct ether_arp)); - if (r < (int) sizeof(struct ether_arp)) - goto out; + n = recv(fd, &packet, sizeof(struct ether_arp), 0); + if (n < 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; + + log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m"); + goto fail; + } + if ((size_t) n != sizeof(struct ether_arp)) { + log_ipv4acd(acd, "Ignoring too short ARP packet."); + return 0; + } + + switch (acd->state) { - switch (ll->state) { case IPV4ACD_STATE_ANNOUNCING: case IPV4ACD_STATE_RUNNING: - if (ipv4acd_arp_conflict(ll, &packet)) { + + if (ipv4acd_arp_conflict(acd, &packet)) { usec_t ts; - assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &ts) >= 0); + assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &ts) >= 0); /* Defend address */ - if (ts > ll->defend_window) { - ll->defend_window = ts + DEFEND_INTERVAL * USEC_PER_SEC; - r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr); + if (ts > acd->defend_window) { + acd->defend_window = ts + DEFEND_INTERVAL_USEC; + r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) { - log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m"); - goto out; + log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m"); + goto fail; } else - log_ipv4acd_debug(ll, "DEFEND"); + log_ipv4acd(acd, "DEFEND"); } else - ipv4acd_on_conflict(ll); + ipv4acd_on_conflict(acd); } - break; + case IPV4ACD_STATE_WAITING_PROBE: case IPV4ACD_STATE_PROBING: case IPV4ACD_STATE_WAITING_ANNOUNCE: /* BPF ensures this packet indicates a conflict */ - ipv4acd_on_conflict(ll); - + ipv4acd_on_conflict(acd); break; + default: assert_not_reached("Invalid state."); } -out: - if (r < 0) - sd_ipv4acd_stop(ll); + return 0; - return 1; +fail: + sd_ipv4acd_stop(acd); + return 0; } -int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index) { - assert_return(ll, -EINVAL); - assert_return(interface_index > 0, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); +int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int ifindex) { + assert_return(acd, -EINVAL); + assert_return(ifindex > 0, -EINVAL); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->index = interface_index; + acd->ifindex = ifindex; return 0; } -int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr) { + assert_return(acd, -EINVAL); assert_return(addr, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - memcpy(&ll->mac_addr, addr, ETH_ALEN); + acd->mac_addr = *addr; return 0; } -int sd_ipv4acd_detach_event(sd_ipv4acd *ll) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_detach_event(sd_ipv4acd *acd) { + assert_return(acd, -EINVAL); - ll->event = sd_event_unref(ll->event); + acd->event = sd_event_unref(acd->event); return 0; } -int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority) { +int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority) { int r; - assert_return(ll, -EINVAL); - assert_return(!ll->event, -EBUSY); + assert_return(acd, -EINVAL); + assert_return(!acd->event, -EBUSY); if (event) - ll->event = sd_event_ref(event); + acd->event = sd_event_ref(event); else { - r = sd_event_default(&ll->event); + r = sd_event_default(&acd->event); if (r < 0) return r; } - ll->event_priority = priority; + acd->event_priority = priority; return 0; } -int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata) { + assert_return(acd, -EINVAL); - ll->cb = cb; - ll->userdata = userdata; + acd->callback = cb; + acd->userdata = userdata; return 0; } -int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address) { - assert_return(ll, -EINVAL); +int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) { + assert_return(acd, -EINVAL); assert_return(address, -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->address = address->s_addr; + acd->address = address->s_addr; return 0; } -int sd_ipv4acd_is_running(sd_ipv4acd *ll) { - assert_return(ll, false); +int sd_ipv4acd_is_running(sd_ipv4acd *acd) { + assert_return(acd, false); - return ll->state != IPV4ACD_STATE_INIT; + return acd->state != IPV4ACD_STATE_INIT; } -static bool ether_addr_is_nul(const struct ether_addr *addr) { - const struct ether_addr nul_addr = {}; - - assert(addr); - - return memcmp(addr, &nul_addr, sizeof(struct ether_addr)) == 0; -} - -#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) - -int sd_ipv4acd_start(sd_ipv4acd *ll) { +int sd_ipv4acd_start(sd_ipv4acd *acd) { int r; - assert_return(ll, -EINVAL); - assert_return(ll->event, -EINVAL); - assert_return(ll->index > 0, -EINVAL); - assert_return(ll->address != 0, -EINVAL); - assert_return(!ether_addr_is_nul(&ll->mac_addr), -EINVAL); - assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY); + assert_return(acd, -EINVAL); + assert_return(acd->event, -EINVAL); + assert_return(acd->ifindex > 0, -EINVAL); + assert_return(acd->address != 0, -EINVAL); + assert_return(!ether_addr_is_null(&acd->mac_addr), -EINVAL); + assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - ll->defend_window = 0; - - r = arp_network_bind_raw_socket(ll->index, ll->address, &ll->mac_addr); + r = arp_network_bind_raw_socket(acd->ifindex, acd->address, &acd->mac_addr); if (r < 0) - goto out; + return r; - ll->fd = safe_close(ll->fd); - ll->fd = r; + safe_close(acd->fd); + acd->fd = r; + acd->defend_window = 0; + acd->n_conflict = 0; - r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd, - EPOLLIN, ipv4acd_on_packet, ll); + r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd); if (r < 0) - goto out; + goto fail; - r = sd_event_source_set_priority(ll->receive_message, ll->event_priority); + r = sd_event_source_set_priority(acd->receive_message_event_source, acd->event_priority); if (r < 0) - goto out; + goto fail; - r = sd_event_source_set_description(ll->receive_message, "ipv4acd-receive-message"); - if (r < 0) - goto out; + (void) sd_event_source_set_description(acd->receive_message_event_source, "ipv4acd-receive-message"); - r = ipv4acd_set_next_wakeup(ll, 0, 0); + r = ipv4acd_set_next_wakeup(acd, 0, 0); if (r < 0) - goto out; -out: - if (r < 0) { - ipv4acd_stop(ll); - return r; - } + goto fail; + ipv4acd_set_state(acd, IPV4ACD_STATE_STARTED, true); return 0; + +fail: + ipv4acd_reset(acd); + return r; } diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c index 391be15a..dc2fa370 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c @@ -30,16 +30,17 @@ #include "sd-ipv4ll.h" #include "alloc-util.h" +#include "ether-addr-util.h" #include "in-addr-util.h" #include "list.h" #include "random-util.h" -#include "refcnt.h" #include "siphash24.h" #include "sparse-endian.h" +#include "string-util.h" #include "util.h" -#define IPV4LL_NETWORK 0xA9FE0000L -#define IPV4LL_NETMASK 0xFFFF0000L +#define IPV4LL_NETWORK UINT32_C(0xA9FE0000) +#define IPV4LL_NETMASK UINT32_C(0xFFFF0000) #define IPV4LL_DONT_DESTROY(ll) \ _cleanup_(sd_ipv4ll_unrefp) _unused_ sd_ipv4ll *_dont_destroy_##ll = sd_ipv4ll_ref(ll) @@ -48,16 +49,28 @@ struct sd_ipv4ll { unsigned n_ref; sd_ipv4acd *acd; + be32_t address; /* the address pushed to ACD */ - struct random_data *random_data; - char *random_data_state; + struct ether_addr mac; + + struct { + le64_t value; + le64_t generation; + } seed; + bool seed_set; /* External */ be32_t claimed_address; - sd_ipv4ll_callback_t cb; + + sd_ipv4ll_callback_t callback; void* userdata; }; +#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__) +#define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__) + +static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); + sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) { if (!ll) return NULL; @@ -79,16 +92,11 @@ sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) { return NULL; sd_ipv4acd_unref(ll->acd); - - free(ll->random_data); - free(ll->random_data_state); free(ll); return NULL; } -static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); - int sd_ipv4ll_new(sd_ipv4ll **ret) { _cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL; int r; @@ -116,44 +124,32 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) { } int sd_ipv4ll_stop(sd_ipv4ll *ll) { - int r; - assert_return(ll, -EINVAL); - r = sd_ipv4acd_stop(ll->acd); - if (r < 0) - return r; - - return 0; + return sd_ipv4acd_stop(ll->acd); } -int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) { +int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int ifindex) { assert_return(ll, -EINVAL); + assert_return(ifindex > 0, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); - return sd_ipv4acd_set_index(ll->acd, interface_index); + return sd_ipv4acd_set_ifindex(ll->acd, ifindex); } -#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) - int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) { int r; assert_return(ll, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); - if (!ll->random_data) { - uint64_t seed; - - /* If no random data is set, generate some from the MAC */ - seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); - - assert_cc(sizeof(unsigned) <= 8); - - r = sd_ipv4ll_set_address_seed(ll, (unsigned) htole64(seed)); - if (r < 0) - return r; - } + r = sd_ipv4acd_set_mac(ll->acd, addr); + if (r < 0) + return r; - return sd_ipv4acd_set_mac(ll->acd, addr); + ll->mac = *addr; + return 0; } int sd_ipv4ll_detach_event(sd_ipv4ll *ll) { @@ -163,21 +159,15 @@ int sd_ipv4ll_detach_event(sd_ipv4ll *ll) { } int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority) { - int r; - assert_return(ll, -EINVAL); - r = sd_ipv4acd_attach_event(ll->acd, event, priority); - if (r < 0) - return r; - - return 0; + return sd_ipv4acd_attach_event(ll->acd, event, priority); } int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata) { assert_return(ll, -EINVAL); - ll->cb = cb; + ll->callback = cb; ll->userdata = userdata; return 0; @@ -195,32 +185,12 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address) { return 0; } -int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed) { - _cleanup_free_ struct random_data *random_data = NULL; - _cleanup_free_ char *random_data_state = NULL; - int r; - +int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed) { assert_return(ll, -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); - random_data = new0(struct random_data, 1); - if (!random_data) - return -ENOMEM; - - random_data_state = new0(char, 128); - if (!random_data_state) - return -ENOMEM; - - r = initstate_r(seed, random_data_state, 128, random_data); - if (r < 0) - return r; - - free(ll->random_data); - ll->random_data = random_data; - random_data = NULL; - - free(ll->random_data_state); - ll->random_data_state = random_data_state; - random_data_state = NULL; + ll->seed.value = htole64(seed); + ll->seed_set = true; return 0; } @@ -232,20 +202,12 @@ int sd_ipv4ll_is_running(sd_ipv4ll *ll) { } static bool ipv4ll_address_is_valid(const struct in_addr *address) { - uint32_t addr; - assert(address); if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address)) return false; - addr = be32toh(address->s_addr); - - if ((addr & 0x0000FF00) == 0x0000 || - (addr & 0x0000FF00) == 0xFF00) - return false; - - return true; + return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U); } int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { @@ -264,48 +226,67 @@ int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { return 0; } +#define PICK_HASH_KEY SD_ID128_MAKE(15,ac,82,a6,d6,3f,49,78,98,77,5d,0c,69,02,94,0b) + static int ipv4ll_pick_address(sd_ipv4ll *ll) { - struct in_addr in_addr; + _cleanup_free_ char *address = NULL; be32_t addr; - int r; - int32_t random; assert(ll); - assert(ll->random_data); do { - r = random_r(ll->random_data, &random); - if (r < 0) - return r; - addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK); - } while (addr == ll->address || - (ntohl(addr) & 0x0000FF00) == 0x0000 || - (ntohl(addr) & 0x0000FF00) == 0xFF00); + uint64_t h; - in_addr.s_addr = addr; + h = siphash24(&ll->seed, sizeof(ll->seed), PICK_HASH_KEY.bytes); - r = sd_ipv4ll_set_address(ll, &in_addr); - if (r < 0) - return r; + /* Increase the generation counter by one */ + ll->seed.generation = htole64(le64toh(ll->seed.generation) + 1); - return 0; + addr = htobe32((h & UINT32_C(0x0000FFFF)) | IPV4LL_NETWORK); + } while (addr == ll->address || + IN_SET(be32toh(addr) & 0x0000FF00U, 0x0000U, 0xFF00U)); + + (void) in_addr_to_string(AF_INET, &(union in_addr_union) { .in.s_addr = addr }, &address); + log_ipv4ll(ll, "Picked new IP address %s.", strna(address)); + + return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr }); } +#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) + int sd_ipv4ll_start(sd_ipv4ll *ll) { int r; + bool picked_address = false; assert_return(ll, -EINVAL); - assert_return(ll->random_data, -EINVAL); + assert_return(!ether_addr_is_null(&ll->mac), -EINVAL); + assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY); + + /* If no random seed is set, generate some from the MAC address */ + if (!ll->seed_set) + ll->seed.value = htole64(siphash24(ll->mac.ether_addr_octet, ETH_ALEN, MAC_HASH_KEY.bytes)); + + /* Restart the generation counter. */ + ll->seed.generation = 0; if (ll->address == 0) { r = ipv4ll_pick_address(ll); if (r < 0) return r; + + picked_address = true; } r = sd_ipv4acd_start(ll->acd); - if (r < 0) + if (r < 0) { + + /* We couldn't start? If so, let's forget the picked address again, the user might make a change and + * retry, and we want the new data to take effect when picking an address. */ + if (picked_address) + ll->address = 0; + return r; + } return 0; } @@ -313,8 +294,8 @@ int sd_ipv4ll_start(sd_ipv4ll *ll) { static void ipv4ll_client_notify(sd_ipv4ll *ll, int event) { assert(ll); - if (ll->cb) - ll->cb(ll, event, ll->userdata); + if (ll->callback) + ll->callback(ll, event, ll->userdata); } void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { @@ -326,17 +307,17 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { assert(ll); switch (event) { + case SD_IPV4ACD_EVENT_STOP: ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_STOP); - ll->claimed_address = 0; - break; + case SD_IPV4ACD_EVENT_BIND: ll->claimed_address = ll->address; ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_BIND); - break; + case SD_IPV4ACD_EVENT_CONFLICT: /* if an address was already bound we must call up to the user to handle this, otherwise we just try again */ @@ -355,6 +336,7 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) { } break; + default: assert_not_reached("Invalid IPv4ACD event."); } diff --git a/src/systemd/src/libsystemd-network/sd-lldp.c b/src/systemd/src/libsystemd-network/sd-lldp.c index 71d15812..f1ae6dac 100644 --- a/src/systemd/src/libsystemd-network/sd-lldp.c +++ b/src/systemd/src/libsystemd-network/sd-lldp.c @@ -45,7 +45,6 @@ static void lldp_flush_neighbors(sd_lldp *lldp) { static void lldp_callback(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n) { assert(lldp); - assert(n); log_lldp("Invoking callback for '%c'.", event); @@ -140,6 +139,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) { if (lldp_neighbor_equal(n, old)) { /* Is this equal, then restart the TTL counter, but don't do anyting else. */ + old->timestamp = n->timestamp; lldp_start_timer(lldp, old); lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old); return 0; @@ -173,7 +173,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) { finish: if (old) - lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, n); + lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, old); return r; } @@ -204,6 +204,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; ssize_t space, length; sd_lldp *lldp = userdata; + struct timespec ts; assert(fd >= 0); assert(lldp); @@ -217,21 +218,41 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v return -ENOMEM; length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT); - if (length < 0) + if (length < 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; + return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); + } if ((size_t) length != n->raw_size) { log_lldp("Packet size mismatch."); return -EINVAL; } + /* Try to get the timestamp of this packet if it is known */ + if (ioctl(fd, SIOCGSTAMPNS, &ts) >= 0) + triple_timestamp_from_realtime(&n->timestamp, timespec_load(&ts)); + else + triple_timestamp_get(&n->timestamp); + return lldp_handle_datagram(lldp, n); } +static void lldp_reset(sd_lldp *lldp) { + assert(lldp); + + lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source); + lldp->io_event_source = sd_event_source_unref(lldp->io_event_source); + lldp->fd = safe_close(lldp->fd); +} + _public_ int sd_lldp_start(sd_lldp *lldp) { int r; assert_return(lldp, -EINVAL); + assert_return(lldp->event, -EINVAL); + assert_return(lldp->ifindex > 0, -EINVAL); if (lldp->fd >= 0) return 0; @@ -242,24 +263,21 @@ _public_ int sd_lldp_start(sd_lldp *lldp) { if (lldp->fd < 0) return lldp->fd; - if (lldp->event) { - r = sd_event_add_io(lldp->event, &lldp->io_event_source, lldp->fd, EPOLLIN, lldp_receive_datagram, lldp); - if (r < 0) - goto fail; + r = sd_event_add_io(lldp->event, &lldp->io_event_source, lldp->fd, EPOLLIN, lldp_receive_datagram, lldp); + if (r < 0) + goto fail; - r = sd_event_source_set_priority(lldp->io_event_source, lldp->event_priority); - if (r < 0) - goto fail; + r = sd_event_source_set_priority(lldp->io_event_source, lldp->event_priority); + if (r < 0) + goto fail; - (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io"); - } + (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io"); + log_lldp("Started LLDP client"); return 1; fail: - lldp->io_event_source = sd_event_source_unref(lldp->io_event_source); - lldp->fd = safe_close(lldp->fd); - + lldp_reset(lldp); return r; } @@ -269,10 +287,9 @@ _public_ int sd_lldp_stop(sd_lldp *lldp) { if (lldp->fd < 0) return 0; - lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source); - lldp->io_event_source = sd_event_source_unref(lldp->io_event_source); - lldp->fd = safe_close(lldp->fd); + log_lldp("Stopping LLDP client"); + lldp_reset(lldp); lldp_flush_neighbors(lldp); return 1; @@ -307,6 +324,12 @@ _public_ int sd_lldp_detach_event(sd_lldp *lldp) { return 0; } +_public_ sd_event* sd_lldp_get_event(sd_lldp *lldp) { + assert_return(lldp, NULL); + + return lldp->event; +} + _public_ int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata) { assert_return(lldp, -EINVAL); @@ -316,39 +339,60 @@ _public_ int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *us return 0; } +_public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) { + assert_return(lldp, -EINVAL); + assert_return(ifindex > 0, -EINVAL); + assert_return(lldp->fd < 0, -EBUSY); + + lldp->ifindex = ifindex; + return 0; +} + +_public_ sd_lldp* sd_lldp_ref(sd_lldp *lldp) { + + if (!lldp) + return NULL; + + assert(lldp->n_ref > 0); + lldp->n_ref++; + + return lldp; +} + _public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) { if (!lldp) return NULL; + assert(lldp->n_ref > 0); + lldp->n_ref --; + + if (lldp->n_ref > 0) + return NULL; + + lldp_reset(lldp); + sd_lldp_detach_event(lldp); lldp_flush_neighbors(lldp); hashmap_free(lldp->neighbor_by_id); prioq_free(lldp->neighbor_by_expiry); - - sd_event_source_unref(lldp->io_event_source); - sd_event_source_unref(lldp->timer_event_source); - sd_event_unref(lldp->event); - safe_close(lldp->fd); - free(lldp); return NULL; } -_public_ int sd_lldp_new(sd_lldp **ret, int ifindex) { +_public_ int sd_lldp_new(sd_lldp **ret) { _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL; int r; assert_return(ret, -EINVAL); - assert_return(ifindex > 0, -EINVAL); lldp = new0(sd_lldp, 1); if (!lldp) return -ENOMEM; + lldp->n_ref = 1; lldp->fd = -1; - lldp->ifindex = ifindex; lldp->neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX; lldp->capability_mask = (uint16_t) -1; @@ -488,11 +532,10 @@ _public_ int sd_lldp_set_filter_address(sd_lldp *lldp, const struct ether_addr * /* In order to deal nicely with bridges that send back our own packets, allow one address to be filtered, so * that our own can be filtered out here. */ - if (!addr) { + if (addr) + lldp->filter_address = *addr; + else zero(lldp->filter_address); - return 0; - } - lldp->filter_address = *addr; return 0; } diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c index 31e8e7fa..0d400661 100644 --- a/src/systemd/src/libsystemd/sd-event/sd-event.c +++ b/src/systemd/src/libsystemd/sd-event/sd-event.c @@ -23,9 +23,7 @@ #include <sys/timerfd.h> #include <sys/wait.h> -#if 0 /* NM_IGNORED */ #include "sd-daemon.h" -#endif #include "sd-event.h" #include "sd-id128.h" @@ -34,17 +32,11 @@ #include "hashmap.h" #include "list.h" #include "macro.h" -#if 0 /* NM_IGNORED */ #include "missing.h" -#endif #include "prioq.h" -#if 0 /* NM_IGNORED */ #include "process-util.h" -#endif #include "set.h" -#if 0 /* NM_IGNORED */ #include "signal-util.h" -#endif #include "string-table.h" #include "string-util.h" #include "time-util.h" @@ -119,8 +111,8 @@ struct sd_event_source { int64_t priority; unsigned pending_index; unsigned prepare_index; - unsigned pending_iteration; - unsigned prepare_iteration; + uint64_t pending_iteration; + uint64_t prepare_iteration; LIST_FIELDS(sd_event_source, sources); @@ -225,9 +217,8 @@ struct sd_event { pid_t original_pid; - unsigned iteration; - dual_timestamp timestamp; - usec_t timestamp_boottime; + uint64_t iteration; + triple_timestamp timestamp; int state; bool exit_requested:1; @@ -1082,12 +1073,16 @@ _public_ int sd_event_add_time( assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); + if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */ + return -EOPNOTSUPP; + + type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */ + if (type < 0) + return -EOPNOTSUPP; + if (!callback) callback = time_exit_callback; - type = clock_to_event_source_type(clock); - assert_return(type >= 0, -EOPNOTSUPP); - d = event_get_clock_data(e, type); assert(d); @@ -1156,8 +1151,7 @@ _public_ int sd_event_add_signal( int r; assert_return(e, -EINVAL); - assert_return(sig > 0, -EINVAL); - assert_return(sig < _NSIG, -EINVAL); + assert_return(SIGNAL_VALID(sig), -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -2212,7 +2206,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { if (_unlikely_(n != sizeof(si))) return -EIO; - assert(si.ssi_signo < _NSIG); + assert(SIGNAL_VALID(si.ssi_signo)); read_one = true; @@ -2539,8 +2533,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { goto finish; } - dual_timestamp_get(&e->timestamp); - e->timestamp_boottime = now(CLOCK_BOOTTIME); + triple_timestamp_get(&e->timestamp); for (i = 0; i < m; i++) { @@ -2581,7 +2574,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; - r = process_timer(e, e->timestamp_boottime, &e->boottime); + r = process_timer(e, e->timestamp.boottime, &e->boottime); if (r < 0) goto finish; @@ -2593,7 +2586,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; - r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm); + r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm); if (r < 0) goto finish; @@ -2767,40 +2760,24 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { assert_return(e, -EINVAL); assert_return(usec, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); - assert_return(IN_SET(clock, - CLOCK_REALTIME, - CLOCK_REALTIME_ALARM, - CLOCK_MONOTONIC, - CLOCK_BOOTTIME, - CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP); - - if (!dual_timestamp_is_set(&e->timestamp)) { + + if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock)) + return -EOPNOTSUPP; + + /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here, + * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for + * the purpose of getting the time this doesn't matter. */ + if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported()) + return -EOPNOTSUPP; + + if (!triple_timestamp_is_set(&e->timestamp)) { /* Implicitly fall back to now() if we never ran * before and thus have no cached time. */ *usec = now(clock); return 1; } - switch (clock) { - - case CLOCK_REALTIME: - case CLOCK_REALTIME_ALARM: - *usec = e->timestamp.realtime; - break; - - case CLOCK_MONOTONIC: - *usec = e->timestamp.monotonic; - break; - - case CLOCK_BOOTTIME: - case CLOCK_BOOTTIME_ALARM: - *usec = e->timestamp_boottime; - break; - - default: - assert_not_reached("Unknown clock?"); - } - + *usec = triple_timestamp_by_clock(&e->timestamp, clock); return 0; } @@ -2902,4 +2879,12 @@ _public_ int sd_event_get_watchdog(sd_event *e) { return e->watchdog; } + +_public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) { + assert_return(e, -EINVAL); + assert_return(!event_pid_changed(e), -ECHILD); + + *ret = e->iteration; + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.c b/src/systemd/src/libsystemd/sd-id128/id128-util.c new file mode 100644 index 00000000..c16052d8 --- /dev/null +++ b/src/systemd/src/libsystemd/sd-id128/id128-util.c @@ -0,0 +1,200 @@ +/*** + This file is part of systemd. + + Copyright 2016 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "nm-sd-adapt.h" + +#include <fcntl.h> +#include <unistd.h> + +#include "fd-util.h" +#include "hexdecoct.h" +#include "id128-util.h" +#include "io-util.h" +#include "stdio-util.h" + +#if 0 /* NM_IGNORED */ +char *id128_to_uuid_string(sd_id128_t id, char s[37]) { + unsigned n, k = 0; + + assert(s); + + /* Similar to sd_id128_to_string() but formats the result as UUID instead of plain hex chars */ + + for (n = 0; n < 16; n++) { + + if (IN_SET(n, 4, 6, 8, 10)) + s[k++] = '-'; + + s[k++] = hexchar(id.bytes[n] >> 4); + s[k++] = hexchar(id.bytes[n] & 0xF); + } + + assert(k == 36); + + s[k] = 0; + + return s; +} + +bool id128_is_valid(const char *s) { + size_t i, l; + + assert(s); + + l = strlen(s); + if (l == 32) { + + /* Plain formatted 128bit hex string */ + + for (i = 0; i < l; i++) { + char c = s[i]; + + if (!(c >= '0' && c <= '9') && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z')) + return false; + } + + } else if (l == 36) { + + /* Formatted UUID */ + + for (i = 0; i < l; i++) { + char c = s[i]; + + if ((i == 8 || i == 13 || i == 18 || i == 23)) { + if (c != '-') + return false; + } else { + if (!(c >= '0' && c <= '9') && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z')) + return false; + } + } + + } else + return false; + + return true; +} +#endif /* NM_IGNORED */ + +int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) { + char buffer[36 + 2]; + ssize_t l; + + assert(fd >= 0); + assert(f < _ID128_FORMAT_MAX); + + /* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both + * optionally followed by a newline and nothing else. ID files should really be newline terminated, but if they + * aren't that's OK too, following the rule of "Be conservative in what you send, be liberal in what you + * accept". */ + + l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 32/33 or 36/37 chars */ + if (l < 0) + return (int) l; + if (l == 0) /* empty? */ + return -ENOMEDIUM; + + switch (l) { + + case 33: /* plain UUID with trailing newline */ + if (buffer[32] != '\n') + return -EINVAL; + + /* fall through */ + case 32: /* plain UUID without trailing newline */ + if (f == ID128_UUID) + return -EINVAL; + + buffer[32] = 0; + break; + + case 37: /* RFC UUID with trailing newline */ + if (buffer[36] != '\n') + return -EINVAL; + + /* fall through */ + case 36: /* RFC UUID without trailing newline */ + if (f == ID128_PLAIN) + return -EINVAL; + + buffer[36] = 0; + break; + + default: + return -EINVAL; + } + + return sd_id128_from_string(buffer, ret); +} + +int id128_read(const char *p, Id128Format f, sd_id128_t *ret) { + _cleanup_close_ int fd = -1; + + fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + return id128_read_fd(fd, f, ret); +} + +#if 0 /* NM_IGNORED */ +int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) { + char buffer[36 + 2]; + size_t sz; + int r; + + assert(fd >= 0); + assert(f < _ID128_FORMAT_MAX); + + if (f != ID128_UUID) { + sd_id128_to_string(id, buffer); + buffer[32] = '\n'; + sz = 33; + } else { + id128_to_uuid_string(id, buffer); + buffer[36] = '\n'; + sz = 37; + } + + r = loop_write(fd, buffer, sz, false); + if (r < 0) + return r; + + if (do_sync) { + if (fsync(fd) < 0) + return -errno; + } + + return r; +} + +int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) { + _cleanup_close_ int fd = -1; + + fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); + if (fd < 0) + return -errno; + + return id128_write_fd(fd, f, id, do_sync); +} +#endif /* NM_IGNORED */ diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.h b/src/systemd/src/libsystemd/sd-id128/id128-util.h new file mode 100644 index 00000000..3ba59acb --- /dev/null +++ b/src/systemd/src/libsystemd/sd-id128/id128-util.h @@ -0,0 +1,45 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdbool.h> + +#include "sd-id128.h" +#include "macro.h" + +char *id128_to_uuid_string(sd_id128_t id, char s[37]); + +/* Like SD_ID128_FORMAT_STR, but formats as UUID, not in plain format */ +#define ID128_UUID_FORMAT_STR "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" + +bool id128_is_valid(const char *s) _pure_; + +typedef enum Id128Format { + ID128_ANY, + ID128_PLAIN, /* formatted as 32 hex chars as-is */ + ID128_UUID, /* formatted as 36 character uuid string */ + _ID128_FORMAT_MAX, +} Id128Format; + +int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret); +int id128_read(const char *p, Id128Format f, sd_id128_t *ret); + +int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync); +int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync); diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c index 01b805a1..9408c32b 100644 --- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c +++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c @@ -27,6 +27,7 @@ #include "fd-util.h" #include "hexdecoct.h" +#include "id128-util.h" #include "io-util.h" #include "macro.h" #include "random-util.h" @@ -47,6 +48,7 @@ _public_ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]) { return s; } +#endif /* NM_IGNORED */ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) { unsigned n, i; @@ -54,7 +56,6 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) { bool is_guid = false; assert_return(s, -EINVAL); - assert_return(ret, -EINVAL); for (n = 0, i = 0; n < 16;) { int a, b; @@ -92,125 +93,60 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) { if (s[i] != 0) return -EINVAL; - *ret = t; + if (ret) + *ret = t; return 0; } -static sd_id128_t make_v4_uuid(sd_id128_t id) { - /* Stolen from generate_random_uuid() of drivers/char/random.c - * in the kernel sources */ - - /* Set UUID version to 4 --- truly random generation */ - id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40; - - /* Set the UUID variant to DCE */ - id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80; - - return id; -} -#endif - _public_ int sd_id128_get_machine(sd_id128_t *ret) { - static thread_local sd_id128_t saved_machine_id; - static thread_local bool saved_machine_id_valid = false; - _cleanup_close_ int fd = -1; - char buf[33]; - unsigned j; - sd_id128_t t; + static thread_local sd_id128_t saved_machine_id = {}; int r; assert_return(ret, -EINVAL); - if (saved_machine_id_valid) { - *ret = saved_machine_id; - return 0; - } + if (sd_id128_is_null(saved_machine_id)) { + r = id128_read("/etc/machine-id", ID128_PLAIN, &saved_machine_id); + if (r < 0) + return r; - fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return -errno; - - r = loop_read_exact(fd, buf, 33, false); - if (r < 0) - return r; - if (buf[32] !='\n') - return -EIO; - - for (j = 0; j < 16; j++) { - int a, b; - - a = unhexchar(buf[j*2]); - b = unhexchar(buf[j*2+1]); - - if (a < 0 || b < 0) - return -EIO; - - t.bytes[j] = a << 4 | b; + if (sd_id128_is_null(saved_machine_id)) + return -EINVAL; } - saved_machine_id = t; - saved_machine_id_valid = true; - - *ret = t; + *ret = saved_machine_id; return 0; } _public_ int sd_id128_get_boot(sd_id128_t *ret) { - static thread_local sd_id128_t saved_boot_id; - static thread_local bool saved_boot_id_valid = false; - _cleanup_close_ int fd = -1; - char buf[36]; - unsigned j; - sd_id128_t t; - char *p; + static thread_local sd_id128_t saved_boot_id = {}; int r; assert_return(ret, -EINVAL); - if (saved_boot_id_valid) { - *ret = saved_boot_id; - return 0; + if (sd_id128_is_null(saved_boot_id)) { + r = id128_read("/proc/sys/kernel/random/boot_id", ID128_UUID, &saved_boot_id); + if (r < 0) + return r; } - fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return -errno; - - r = loop_read_exact(fd, buf, 36, false); - if (r < 0) - return r; - - for (j = 0, p = buf; j < 16; j++) { - int a, b; - - if (p >= buf + 35) - return -EIO; - - if (*p == '-') { - p++; - if (p >= buf + 35) - return -EIO; - } - - a = unhexchar(p[0]); - b = unhexchar(p[1]); - - if (a < 0 || b < 0) - return -EIO; + *ret = saved_boot_id; + return 0; +} - t.bytes[j] = a << 4 | b; +#if 0 /* NM_IGNORED */ +static sd_id128_t make_v4_uuid(sd_id128_t id) { + /* Stolen from generate_random_uuid() of drivers/char/random.c + * in the kernel sources */ - p += 2; - } + /* Set UUID version to 4 --- truly random generation */ + id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40; - saved_boot_id = t; - saved_boot_id_valid = true; + /* Set the UUID variant to DCE */ + id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80; - *ret = t; - return 0; + return id; } -#if 0 /* NM_IGNORED */ _public_ int sd_id128_randomize(sd_id128_t *ret) { sd_id128_t t; int r; diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h index 374ff877..9a90c2ed 100644 --- a/src/systemd/src/systemd/sd-dhcp-client.h +++ b/src/systemd/src/systemd/sd-dhcp-client.h @@ -84,28 +84,57 @@ enum { typedef struct sd_dhcp_client sd_dhcp_client; -typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, - void *userdata); -int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb, - void *userdata); - -int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option); -int sd_dhcp_client_set_request_address(sd_dhcp_client *client, - const struct in_addr *last_address); -int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast); -int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index); -int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, - size_t addr_len, uint16_t arp_type); -int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, - const uint8_t *data, size_t data_len); -int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, - uint16_t duid_type, uint8_t *duid, size_t duid_len); -int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type, - const uint8_t **data, size_t *data_len); -int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu); -int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname); -int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci); -int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret); +typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata); +int sd_dhcp_client_set_callback( + sd_dhcp_client *client, + sd_dhcp_client_callback_t cb, + void *userdata); + +int sd_dhcp_client_set_request_option( + sd_dhcp_client *client, + uint8_t option); +int sd_dhcp_client_set_request_address( + sd_dhcp_client *client, + const struct in_addr *last_address); +int sd_dhcp_client_set_request_broadcast( + sd_dhcp_client *client, + int broadcast); +int sd_dhcp_client_set_ifindex( + sd_dhcp_client *client, + int interface_index); +int sd_dhcp_client_set_mac( + sd_dhcp_client *client, + const uint8_t *addr, + size_t addr_len, + uint16_t arp_type); +int sd_dhcp_client_set_client_id( + sd_dhcp_client *client, + uint8_t type, + const uint8_t *data, + size_t data_len); +int sd_dhcp_client_set_iaid_duid( + sd_dhcp_client *client, + uint32_t iaid, + uint16_t duid_type, + const void *duid, + size_t duid_len); +int sd_dhcp_client_get_client_id( + sd_dhcp_client *client, + uint8_t *type, + const uint8_t **data, + size_t *data_len); +int sd_dhcp_client_set_mtu( + sd_dhcp_client *client, + uint32_t mtu); +int sd_dhcp_client_set_hostname( + sd_dhcp_client *client, + const char *hostname); +int sd_dhcp_client_set_vendor_class_identifier( + sd_dhcp_client *client, + const char *vci); +int sd_dhcp_client_get_lease( + sd_dhcp_client *client, + sd_dhcp_lease **ret); int sd_dhcp_client_stop(sd_dhcp_client *client); int sd_dhcp_client_start(sd_dhcp_client *client); @@ -115,7 +144,10 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client); int sd_dhcp_client_new(sd_dhcp_client **ret); -int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority); +int sd_dhcp_client_attach_event( + sd_dhcp_client *client, + sd_event *event, + int64_t priority); int sd_dhcp_client_detach_event(sd_dhcp_client *client); sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client); diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h index 4604cb63..7819f0d2 100644 --- a/src/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/src/systemd/sd-dhcp6-client.h @@ -76,29 +76,52 @@ enum { typedef struct sd_dhcp6_client sd_dhcp6_client; -typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event, - void *userdata); -int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, - sd_dhcp6_client_callback_t cb, void *userdata); - -int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index); -int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address); -int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr, - size_t addr_len, uint16_t arp_type); -int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type, - uint8_t *duid, size_t duid_len); -int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid); -int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled); -int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled); -int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, - uint16_t option); - -int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret); +typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event, void *userdata); +int sd_dhcp6_client_set_callback( + sd_dhcp6_client *client, + sd_dhcp6_client_callback_t cb, + void *userdata); + +int sd_dhcp6_client_set_ifindex( + sd_dhcp6_client *client, + int interface_index); +int sd_dhcp6_client_set_local_address( + sd_dhcp6_client *client, + const struct in6_addr *local_address); +int sd_dhcp6_client_set_mac( + sd_dhcp6_client *client, + const uint8_t *addr, + size_t addr_len, + uint16_t arp_type); +int sd_dhcp6_client_set_duid( + sd_dhcp6_client *client, + uint16_t duid_type, + const void *duid, + size_t duid_len); +int sd_dhcp6_client_set_iaid( + sd_dhcp6_client *client, + uint32_t iaid); +int sd_dhcp6_client_set_information_request( + sd_dhcp6_client *client, + int enabled); +int sd_dhcp6_client_get_information_request( + sd_dhcp6_client *client, + int *enabled); +int sd_dhcp6_client_set_request_option( + sd_dhcp6_client *client, + uint16_t option); + +int sd_dhcp6_client_get_lease( + sd_dhcp6_client *client, + sd_dhcp6_lease **ret); int sd_dhcp6_client_stop(sd_dhcp6_client *client); int sd_dhcp6_client_start(sd_dhcp6_client *client); int sd_dhcp6_client_is_running(sd_dhcp6_client *client); -int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority); +int sd_dhcp6_client_attach_event( + sd_dhcp6_client *client, + sd_event *event, + int64_t priority); int sd_dhcp6_client_detach_event(sd_dhcp6_client *client); sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client); sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client); diff --git a/src/systemd/src/systemd/sd-event.h b/src/systemd/src/systemd/sd-event.h index 531ace1c..cc26b7df 100644 --- a/src/systemd/src/systemd/sd-event.h +++ b/src/systemd/src/systemd/sd-event.h @@ -104,6 +104,7 @@ int sd_event_get_tid(sd_event *e, pid_t *tid); int sd_event_get_exit_code(sd_event *e, int *code); int sd_event_set_watchdog(sd_event *e, int b); int sd_event_get_watchdog(sd_event *e); +int sd_event_get_iteration(sd_event *e, uint64_t *ret); sd_event_source* sd_event_source_ref(sd_event_source *s); sd_event_source* sd_event_source_unref(sd_event_source *s); diff --git a/src/systemd/src/systemd/sd-ipv4acd.h b/src/systemd/src/systemd/sd-ipv4acd.h index 9e3e14a3..16d99983 100644 --- a/src/systemd/src/systemd/sd-ipv4acd.h +++ b/src/systemd/src/systemd/sd-ipv4acd.h @@ -37,20 +37,20 @@ enum { }; typedef struct sd_ipv4acd sd_ipv4acd; -typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *ll, int event, void *userdata); - -int sd_ipv4acd_detach_event(sd_ipv4acd *ll); -int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority); -int sd_ipv4acd_get_address(sd_ipv4acd *ll, struct in_addr *address); -int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata); -int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr); -int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index); -int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address); -int sd_ipv4acd_is_running(sd_ipv4acd *ll); -int sd_ipv4acd_start(sd_ipv4acd *ll); -int sd_ipv4acd_stop(sd_ipv4acd *ll); -sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll); -sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll); +typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *acd, int event, void *userdata); + +int sd_ipv4acd_detach_event(sd_ipv4acd *acd); +int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority); +int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address); +int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata); +int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr); +int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index); +int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address); +int sd_ipv4acd_is_running(sd_ipv4acd *acd); +int sd_ipv4acd_start(sd_ipv4acd *acd); +int sd_ipv4acd_stop(sd_ipv4acd *acd); +sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd); +sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd); int sd_ipv4acd_new(sd_ipv4acd **ret); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4acd, sd_ipv4acd_unref); diff --git a/src/systemd/src/systemd/sd-ipv4ll.h b/src/systemd/src/systemd/sd-ipv4ll.h index 6fa38a22..1109ec52 100644 --- a/src/systemd/src/systemd/sd-ipv4ll.h +++ b/src/systemd/src/systemd/sd-ipv4ll.h @@ -43,15 +43,15 @@ int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority); int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address); int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata); int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr); -int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index); +int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index); int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address); -int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed); +int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed); int sd_ipv4ll_is_running(sd_ipv4ll *ll); int sd_ipv4ll_start(sd_ipv4ll *ll); int sd_ipv4ll_stop(sd_ipv4ll *ll); sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll); sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll); -int sd_ipv4ll_new (sd_ipv4ll **ret); +int sd_ipv4ll_new(sd_ipv4ll **ret); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4ll, sd_ipv4ll_unref); diff --git a/src/systemd/src/systemd/sd-lldp.h b/src/systemd/src/systemd/sd-lldp.h index 4f2a3b50..3f35eebe 100644 --- a/src/systemd/src/systemd/sd-lldp.h +++ b/src/systemd/src/systemd/sd-lldp.h @@ -23,6 +23,7 @@ #include <inttypes.h> #include <net/ethernet.h> +#include <sys/types.h> #include "sd-event.h" @@ -30,23 +31,18 @@ _SD_BEGIN_DECLARATIONS; -typedef struct sd_lldp sd_lldp; -typedef struct sd_lldp_neighbor sd_lldp_neighbor; - -#define SD_LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e } - /* IEEE 802.3AB Clause 9: TLV Types */ enum { - SD_LLDP_TYPE_END = 0, - SD_LLDP_TYPE_CHASSIS_ID = 1, - SD_LLDP_TYPE_PORT_ID = 2, - SD_LLDP_TYPE_TTL = 3, - SD_LLDP_TYPE_PORT_DESCRIPTION = 4, - SD_LLDP_TYPE_SYSTEM_NAME = 5, - SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6, - SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7, - SD_LLDP_TYPE_MGMT_ADDRESS = 8, - SD_LLDP_TYPE_PRIVATE = 127, + SD_LLDP_TYPE_END = 0, + SD_LLDP_TYPE_CHASSIS_ID = 1, + SD_LLDP_TYPE_PORT_ID = 2, + SD_LLDP_TYPE_TTL = 3, + SD_LLDP_TYPE_PORT_DESCRIPTION = 4, + SD_LLDP_TYPE_SYSTEM_NAME = 5, + SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6, + SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7, + SD_LLDP_TYPE_MGMT_ADDRESS = 8, + SD_LLDP_TYPE_PRIVATE = 127, }; /* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */ @@ -63,28 +59,28 @@ enum { /* IEEE 802.3AB Clause 9.5.3: Port subtype */ enum { - SD_LLDP_PORT_SUBTYPE_RESERVED = 0, - SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1, - SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2, - SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3, - SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4, - SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5, - SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6, - SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7, + SD_LLDP_PORT_SUBTYPE_RESERVED = 0, + SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1, + SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2, + SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3, + SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4, + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5, + SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6, + SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7, }; enum { - SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0, - SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1, - SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2, - SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3, - SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4, - SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5, - SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6, - SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7, - SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8, - SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9, - SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10, + SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0, + SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1, + SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2, + SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3, + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4, + SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5, + SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6, + SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7, + SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8, + SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9, + SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10, }; #define SD_LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1) @@ -100,20 +96,22 @@ enum { SD_LLDP_SYSTEM_CAPABILITIES_SVLAN| \ SD_LLDP_SYSTEM_CAPABILITIES_TPMR)) - #define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 } #define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f } enum { - SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1, - SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2, - SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3, - SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4, - SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5, - SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6, - SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7, + SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1, + SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2, + SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3, + SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4, + SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5, + SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6, + SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7, }; +typedef struct sd_lldp sd_lldp; +typedef struct sd_lldp_neighbor sd_lldp_neighbor; + typedef enum sd_lldp_event { SD_LLDP_EVENT_ADDED = 'a', SD_LLDP_EVENT_REMOVED = 'r', @@ -123,7 +121,8 @@ typedef enum sd_lldp_event { typedef void (*sd_lldp_callback_t)(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata); -int sd_lldp_new(sd_lldp **ret, int ifindex); +int sd_lldp_new(sd_lldp **ret); +sd_lldp* sd_lldp_ref(sd_lldp *lldp); sd_lldp* sd_lldp_unref(sd_lldp *lldp); int sd_lldp_start(sd_lldp *lldp); @@ -131,8 +130,10 @@ int sd_lldp_stop(sd_lldp *lldp); int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int64_t priority); int sd_lldp_detach_event(sd_lldp *lldp); +sd_event *sd_lldp_get_event(sd_lldp *lldp); int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata); +int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex); /* Controls how much and what to store in the neighbors database */ int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n); @@ -148,6 +149,7 @@ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n); /* Access to LLDP frame metadata */ int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address); int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address); +int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret); int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size); /* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */ @@ -155,7 +157,7 @@ int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const vo int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size); int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret); -int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret); +int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec); int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret); diff --git a/src/systemd/src/systemd/sd-ndisc.h b/src/systemd/src/systemd/sd-ndisc.h index 29bcbe8e..9f7d4ef7 100644 --- a/src/systemd/src/systemd/sd-ndisc.h +++ b/src/systemd/src/systemd/sd-ndisc.h @@ -22,6 +22,8 @@ #include <inttypes.h> #include <net/ethernet.h> +#include <netinet/in.h> +#include <sys/types.h> #include "sd-event.h" @@ -29,55 +31,99 @@ _SD_BEGIN_DECLARATIONS; +/* Neightbor Discovery Options, RFC 4861, Section 4.6 and + * https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-5 */ enum { - SD_NDISC_EVENT_STOP = 0, - SD_NDISC_EVENT_TIMEOUT = 1, + SD_NDISC_OPTION_SOURCE_LL_ADDRESS = 1, + SD_NDISC_OPTION_TARGET_LL_ADDRESS = 2, + SD_NDISC_OPTION_PREFIX_INFORMATION = 3, + SD_NDISC_OPTION_MTU = 5, + SD_NDISC_OPTION_ROUTE_INFORMATION = 24, + SD_NDISC_OPTION_RDNSS = 25, + SD_NDISC_OPTION_FLAGS_EXTENSION = 26, + SD_NDISC_OPTION_DNSSL = 31, + SD_NDISC_OPTION_CAPTIVE_PORTAL = 37, +}; + +/* Route preference, RFC 4191, Section 2.1 */ +enum { + SD_NDISC_PREFERENCE_LOW = 3U, + SD_NDISC_PREFERENCE_MEDIUM = 0U, + SD_NDISC_PREFERENCE_HIGH = 1U, }; typedef struct sd_ndisc sd_ndisc; +typedef struct sd_ndisc_router sd_ndisc_router; -typedef void(*sd_ndisc_router_callback_t)(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata); -typedef void(*sd_ndisc_prefix_onlink_callback_t)(sd_ndisc *nd, const struct in6_addr *prefix, unsigned prefixlen, - unsigned lifetime, void *userdata); -typedef void(*sd_ndisc_prefix_autonomous_callback_t)(sd_ndisc *nd, const struct in6_addr *prefix, unsigned prefixlen, - unsigned lifetime_prefered, unsigned lifetime_valid, void *userdata); -typedef void(*sd_ndisc_callback_t)(sd_ndisc *nd, int event, void *userdata); - -int sd_ndisc_set_callback(sd_ndisc *nd, - sd_ndisc_router_callback_t rcb, - sd_ndisc_prefix_onlink_callback_t plcb, - sd_ndisc_prefix_autonomous_callback_t pacb, - sd_ndisc_callback_t cb, - void *userdata); -int sd_ndisc_set_index(sd_ndisc *nd, int interface_index); -int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); +typedef enum sd_ndisc_event { + SD_NDISC_EVENT_TIMEOUT = 't', + SD_NDISC_EVENT_ROUTER = 'r', +} sd_ndisc_event; -int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority); -int sd_ndisc_detach_event(sd_ndisc *nd); -sd_event *sd_ndisc_get_event(sd_ndisc *nd); +typedef void (*sd_ndisc_callback_t)(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata); +int sd_ndisc_new(sd_ndisc **ret); sd_ndisc *sd_ndisc_ref(sd_ndisc *nd); sd_ndisc *sd_ndisc_unref(sd_ndisc *nd); -int sd_ndisc_new(sd_ndisc **ret); - -int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *mtu); +int sd_ndisc_start(sd_ndisc *nd); int sd_ndisc_stop(sd_ndisc *nd); -int sd_ndisc_router_discovery_start(sd_ndisc *nd); -#define SD_NDISC_ADDRESS_FORMAT_STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" +int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority); +int sd_ndisc_detach_event(sd_ndisc *nd); +sd_event *sd_ndisc_get_event(sd_ndisc *nd); + +int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata); +int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index); +int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); -#define SD_NDISC_ADDRESS_FORMAT_VAL(address) \ - be16toh((address).s6_addr16[0]), \ - be16toh((address).s6_addr16[1]), \ - be16toh((address).s6_addr16[2]), \ - be16toh((address).s6_addr16[3]), \ - be16toh((address).s6_addr16[4]), \ - be16toh((address).s6_addr16[5]), \ - be16toh((address).s6_addr16[6]), \ - be16toh((address).s6_addr16[7]) +int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *ret); +int sd_ndisc_get_hop_limit(sd_ndisc *nd, uint8_t *ret); + +int sd_ndisc_router_from_raw(sd_ndisc_router **ret, const void *raw, size_t raw_size); +sd_ndisc_router *sd_ndisc_router_ref(sd_ndisc_router *rt); +sd_ndisc_router *sd_ndisc_router_unref(sd_ndisc_router *rt); + +int sd_ndisc_router_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr); +int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret); +int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *size); + +int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret); +int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret_flags); +int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret); +int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint16_t *ret_lifetime); +int sd_ndisc_router_get_mtu(sd_ndisc_router *rt, uint32_t *ret); + +/* Generic option access */ +int sd_ndisc_router_option_rewind(sd_ndisc_router *rt); +int sd_ndisc_router_option_next(sd_ndisc_router *rt); +int sd_ndisc_router_option_get_type(sd_ndisc_router *rt, uint8_t *ret); +int sd_ndisc_router_option_is_type(sd_ndisc_router *rt, uint8_t type); +int sd_ndisc_router_option_get_raw(sd_ndisc_router *rt, const void **ret, size_t *size); + +/* Specific option access: SD_NDISC_OPTION_PREFIX_INFORMATION */ +int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint32_t *ret); +int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint32_t *ret); +int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret); +int sd_ndisc_router_prefix_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr); +int sd_ndisc_router_prefix_get_prefixlen(sd_ndisc_router *rt, unsigned *prefixlen); + +/* Specific option access: SD_NDISC_OPTION_ROUTE_INFORMATION */ +int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint32_t *ret); +int sd_ndisc_router_route_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr); +int sd_ndisc_router_route_get_prefixlen(sd_ndisc_router *rt, unsigned *prefixlen); +int sd_ndisc_router_route_get_preference(sd_ndisc_router *rt, unsigned *ret); + +/* Specific option access: SD_NDISC_OPTION_RDNSS */ +int sd_ndisc_router_rdnss_get_addresses(sd_ndisc_router *rt, const struct in6_addr **ret); +int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret); + +/* Specific option access: SD_NDISC_OPTION_DNSSL */ +int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret); +int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router, sd_ndisc_router_unref); _SD_END_DECLARATIONS; diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index e1734b6d..8851c242 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -1,5 +1,7 @@ SUBDIRS = config +@GNOME_CODE_COVERAGE_RULES@ + AM_CPPFLAGS = \ -I$(top_srcdir)/shared \ -I$(top_builddir)/shared \ @@ -12,7 +14,10 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) + +AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) noinst_PROGRAMS = \ test-general \ @@ -47,6 +52,7 @@ test_ip6_config_LDADD = \ test_route_manager_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ + $(GUDEV_CFLAGS) \ -I$(top_srcdir)/src/platform/tests \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 @@ -56,7 +62,7 @@ test_route_manager_fake_SOURCES = \ test-route-manager.c test_route_manager_fake_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_route_manager_linux_SOURCES = \ $(top_srcdir)/src/platform/tests/test-common.c \ @@ -64,6 +70,7 @@ test_route_manager_linux_SOURCES = \ test_route_manager_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ + $(GUDEV_CFLAGS) \ -I$(top_srcdir)/src/platform/tests \ -DSETUP=nm_linux_platform_setup \ -DKERNEL_HACKS=1 @@ -123,7 +130,6 @@ test_systemd_SOURCES = \ test-systemd.c test_systemd_LDADD = \ - $(top_builddir)/src/libNetworkManager-base.la \ $(top_builddir)/src/libsystemd-nm.la ####### utils test ####### diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index 2296c2b0..a4ca2212 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -102,8 +102,9 @@ TESTS = test-ip4-config$(EXEEXT) test-ip6-config$(EXEEXT) \ test-wired-defname$(EXEEXT) test-utils$(EXEEXT) subdir = src/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -159,7 +160,7 @@ am_test_route_manager_fake_OBJECTS = \ test_route_manager_fake_OBJECTS = \ $(am_test_route_manager_fake_OBJECTS) test_route_manager_fake_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la am_test_route_manager_linux_OBJECTS = \ test_route_manager_linux-test-common.$(OBJEXT) \ test_route_manager_linux-test-route-manager.$(OBJEXT) @@ -169,9 +170,7 @@ test_route_manager_linux_DEPENDENCIES = \ $(top_builddir)/src/libNetworkManager.la am_test_systemd_OBJECTS = test_systemd-test-systemd.$(OBJEXT) test_systemd_OBJECTS = $(am_test_systemd_OBJECTS) -test_systemd_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager-base.la \ - $(top_builddir)/src/libsystemd-nm.la +test_systemd_DEPENDENCIES = $(top_builddir)/src/libsystemd-nm.la test_systemd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_systemd_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -533,6 +532,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -589,13 +589,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -607,6 +608,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -667,6 +670,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -702,6 +707,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -776,8 +782,10 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) +AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) ####### ip4 config test ####### test_ip4_config_SOURCES = \ @@ -798,6 +806,7 @@ test_ip6_config_LDADD = \ ####### route manager test ####### test_route_manager_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ + $(GUDEV_CFLAGS) \ -I$(top_srcdir)/src/platform/tests \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 @@ -807,7 +816,7 @@ test_route_manager_fake_SOURCES = \ test-route-manager.c test_route_manager_fake_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_route_manager_linux_SOURCES = \ $(top_srcdir)/src/platform/tests/test-common.c \ @@ -815,6 +824,7 @@ test_route_manager_linux_SOURCES = \ test_route_manager_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ + $(GUDEV_CFLAGS) \ -I$(top_srcdir)/src/platform/tests \ -DSETUP=nm_linux_platform_setup \ -DKERNEL_HACKS=1 @@ -874,7 +884,6 @@ test_systemd_SOURCES = \ test-systemd.c test_systemd_LDADD = \ - $(top_builddir)/src/libNetworkManager-base.la \ $(top_builddir)/src/libsystemd-nm.la @@ -1633,6 +1642,8 @@ uninstall-am: .PRECIOUS: Makefile +@GNOME_CODE_COVERAGE_RULES@ + ########################################### @VALGRIND_RULES@ diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am index 17876e4d..d0cb797d 100644 --- a/src/tests/config/Makefile.am +++ b/src/tests/config/Makefile.am @@ -9,8 +9,8 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ - -DSRCDIR=\""$(srcdir)"\" \ - -DBUILDDIR=\""$(builddir)"\" + -DSRCDIR=\""$(abs_srcdir)"\" \ + -DBUILDDIR=\""$(abs_builddir)"\" noinst_PROGRAMS = \ test-config @@ -21,13 +21,14 @@ test_config_SOURCES = \ test-config.c test_config_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @VALGRIND_RULES@ TESTS = test-config EXTRA_DIST = \ NetworkManager.conf \ + NetworkManager.state \ bad.conf \ global-dns-invalid.conf \ conf.d/00-overrides.conf \ diff --git a/src/tests/config/Makefile.in b/src/tests/config/Makefile.in index 7197ee1f..89c18941 100644 --- a/src/tests/config/Makefile.in +++ b/src/tests/config/Makefile.in @@ -92,8 +92,9 @@ noinst_PROGRAMS = test-config$(EXEEXT) TESTS = test-config$(EXEEXT) subdir = src/tests/config ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -116,7 +117,8 @@ PROGRAMS = $(noinst_PROGRAMS) am_test_config_OBJECTS = nm-test-device.$(OBJEXT) \ test-config.$(OBJEXT) test_config_OBJECTS = $(am_test_config_OBJECTS) -test_config_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +test_config_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManagerTest.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -422,6 +424,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -478,13 +481,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -496,6 +500,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -556,6 +562,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -591,6 +599,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -663,8 +672,8 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ - -DSRCDIR=\""$(srcdir)"\" \ - -DBUILDDIR=\""$(builddir)"\" + -DSRCDIR=\""$(abs_srcdir)"\" \ + -DBUILDDIR=\""$(abs_builddir)"\" test_config_SOURCES = \ nm-test-device.c \ @@ -672,10 +681,11 @@ test_config_SOURCES = \ test-config.c test_config_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la EXTRA_DIST = \ NetworkManager.conf \ + NetworkManager.state \ bad.conf \ global-dns-invalid.conf \ conf.d/00-overrides.conf \ diff --git a/src/tests/config/NetworkManager.state b/src/tests/config/NetworkManager.state new file mode 100644 index 00000000..1b9d604a --- /dev/null +++ b/src/tests/config/NetworkManager.state @@ -0,0 +1,4 @@ +[main] +NetworkingEnabled=true +WirelessEnabled=true +WWANEnabled=true diff --git a/src/tests/config/nm-test-device.c b/src/tests/config/nm-test-device.c index 04ccaec2..1ae964ee 100644 --- a/src/tests/config/nm-test-device.c +++ b/src/tests/config/nm-test-device.c @@ -38,17 +38,6 @@ nm_test_device_init (NMTestDevice *self) /* We jump over NMDevice's construct/destruct methods, which require NMPlatform * and NMConnectionProvider to be initialized. */ - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - return PARENT_CLASS->constructor (type, - n_construct_params, - construct_params); -} - static void constructed (GObject *object) { @@ -73,7 +62,6 @@ nm_test_device_class_init (NMTestDeviceClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - object_class->constructor = constructor; object_class->constructed = constructed; object_class->dispose = dispose; @@ -85,6 +73,6 @@ nm_test_device_new (const char *hwaddr) { return g_object_new (NM_TYPE_TEST_DEVICE, NM_DEVICE_IFACE, "dummy", - NM_DEVICE_HW_ADDRESS, hwaddr, + NM_DEVICE_PERM_HW_ADDRESS, hwaddr, NULL); } diff --git a/src/tests/config/nm-test-device.h b/src/tests/config/nm-test-device.h index c3532c9c..dfb8ff78 100644 --- a/src/tests/config/nm-test-device.h +++ b/src/tests/config/nm-test-device.h @@ -23,8 +23,6 @@ #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_TEST_DEVICE (nm_test_device_get_type ()) #define NM_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEST_DEVICE, NMTestDevice)) #define NM_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) @@ -45,6 +43,4 @@ GType nm_test_device_get_type (void); NMDevice *nm_test_device_new (const char *hwaddr); -G_END_DECLS - -#endif /* NM_DEVICE_H */ +#endif /* __NETWORKMANAGER_TEST_DEVICE_H__ */ diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index b6d88edf..73358d02 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -27,7 +27,7 @@ #include "nm-fake-platform.h" #include "nm-bus-manager.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /********************************************************************************/ @@ -930,6 +930,65 @@ test_config_enable (void) /*****************************************************************************/ +static void +test_config_state_file (void) +{ + NMConfig *config; + const NMConfigState *state; + gs_free_error GError *error = NULL; + gboolean ret; + gs_free char *file_data = NULL; + gsize file_size; + const char *const TMP_FILE = BUILDDIR "/tmp.state"; + + ret = g_file_get_contents (SRCDIR "/NetworkManager.state", &file_data, &file_size, &error); + nmtst_assert_success (ret, error); + ret = g_file_set_contents (TMP_FILE, file_data, file_size, &error); + nmtst_assert_success (ret, error); + + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", + "--state-file", TMP_FILE, NULL); + g_assert (config); + + state = nm_config_state_get (config); + g_assert (state); + + g_assert_cmpint (state->net_enabled, ==, TRUE); + g_assert_cmpint (state->wifi_enabled, ==, TRUE); + g_assert_cmpint (state->wwan_enabled, ==, TRUE); + + nm_config_state_set (config, TRUE, TRUE, + NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, FALSE, + NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED, TRUE, + NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED, FALSE); + + state = nm_config_state_get (config); + g_assert (state); + + g_assert_cmpint (state->net_enabled, ==, FALSE); + g_assert_cmpint (state->wifi_enabled, ==, TRUE); + g_assert_cmpint (state->wwan_enabled, ==, FALSE); + + g_object_unref (config); + + /* Reload configuration */ + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", + "--state-file", TMP_FILE, NULL); + g_assert (config); + + state = nm_config_state_get (config); + g_assert (state); + + g_assert_cmpint (state->net_enabled, ==, FALSE); + g_assert_cmpint (state->wifi_enabled, ==, TRUE); + g_assert_cmpint (state->wwan_enabled, ==, FALSE); + + g_object_unref (config); + unlink (TMP_FILE); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -960,6 +1019,8 @@ main (int argc, char **argv) g_test_add_func ("/config/enable", test_config_enable); + g_test_add_func ("/config/state-file", test_config_state_file); + /* This one has to come last, because it leaves its values in * nm-config.c's global variables, and there's no way to reset * those to NULL. diff --git a/src/tests/test-dcb.c b/src/tests/test-dcb.c index e8e1ec86..0a133de3 100644 --- a/src/tests/test-dcb.c +++ b/src/tests/test-dcb.c @@ -24,7 +24,7 @@ #include "nm-dcb.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" typedef struct { guint num; diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c index 64b47bd3..ab2b15b5 100644 --- a/src/tests/test-general-with-expect.c +++ b/src/tests/test-general-with-expect.c @@ -30,7 +30,7 @@ #include "NetworkManagerUtils.h" #include "nm-multi-index.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #ifndef CLOCK_BOOTTIME #define CLOCK_BOOTTIME 7 diff --git a/src/tests/test-general.c b/src/tests/test-general.c index f714deec..9769ead1 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -26,7 +26,7 @@ #include "NetworkManagerUtils.h" #include "nm-core-internal.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /* Reference implementation for nm_utils_ip6_address_clear_host_address. * Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index 9d38dc27..95b221bc 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -26,7 +26,7 @@ #include "nm-ip4-config.h" #include "nm-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static NMIP4Config * build_test_config (void) @@ -161,18 +161,18 @@ test_compare_with_source (void) /* Address */ addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); - addr.source = NM_IP_CONFIG_SOURCE_VPN; + addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (b, &addr); /* Route */ route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1"); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_route (b, &route); /* Assert that the configs are basically the same, eg that the source is ignored */ @@ -193,31 +193,31 @@ test_add_address_with_source (void) /* Test that a higher priority source is not overwritten */ addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); test_addr = nm_ip4_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); - addr.source = NM_IP_CONFIG_SOURCE_VPN; + addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (a, &addr); test_addr = nm_ip4_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ nm_ip4_config_del_address (a, 0); - addr.source = NM_IP_CONFIG_SOURCE_KERNEL; + addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip4_config_add_address (a, &addr); test_addr = nm_ip4_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); test_addr = nm_ip4_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -233,31 +233,31 @@ test_add_route_with_source (void) /* Test that a higher priority source is not overwritten */ route = *nmtst_platform_ip4_route ("1.2.3.4", 24, "1.2.3.1"); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); test_route = nm_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_route (a, &route); test_route = nm_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ nm_ip4_config_del_route (a, 0); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; + route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip4_config_add_route (a, &route); test_route = nm_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); test_route = nm_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 5a2bb589..3eceec0c 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -26,7 +26,7 @@ #include "nm-ip6-config.h" #include "nm-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static NMIP6Config * build_test_config (void) @@ -132,18 +132,18 @@ test_compare_with_source (void) /* Address */ addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); - addr.source = NM_IP_CONFIG_SOURCE_VPN; + addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (b, &addr); /* Route */ route = *nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2"); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_route (a, &route); - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_route (b, &route); /* Assert that the configs are basically the same, eg that the source is ignored */ @@ -164,31 +164,31 @@ test_add_address_with_source (void) /* Test that a higher priority source is not overwritten */ addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); test_addr = nm_ip6_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); - addr.source = NM_IP_CONFIG_SOURCE_VPN; + addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (a, &addr); test_addr = nm_ip6_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ nm_ip6_config_del_address (a, 0); - addr.source = NM_IP_CONFIG_SOURCE_KERNEL; + addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip6_config_add_address (a, &addr); test_addr = nm_ip6_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - addr.source = NM_IP_CONFIG_SOURCE_USER; + addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); test_addr = nm_ip6_config_get_address (a, 0); - g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -204,31 +204,31 @@ test_add_route_with_source (void) /* Test that a higher priority source is not overwritten */ route = *nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2"); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_route (a, &route); test_route = nm_ip6_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_route (a, &route); test_route = nm_ip6_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ nm_ip6_config_del_route (a, 0); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; + route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip6_config_add_route (a, &route); test_route = nm_ip6_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_route (a, &route); test_route = nm_ip6_config_get_route (a, 0); - g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c index 31b6e177..32bc9734 100644 --- a/src/tests/test-resolvconf-capture.c +++ b/src/tests/test-resolvconf-capture.c @@ -28,7 +28,7 @@ #include "nm-ip6-config.h" #include "nm-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static void test_capture_empty (void) diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c index c753174d..b81c263c 100644 --- a/src/tests/test-route-manager.c +++ b/src/tests/test-route-manager.c @@ -23,12 +23,11 @@ #include <arpa/inet.h> #include <linux/rtnetlink.h> -#include "test-common.h" - #include "nm-platform.h" +#include "nm-platform-utils.h" #include "nm-route-manager.h" -#include "nm-test-utils.h" +#include "test-common.h" typedef struct { int ifindex0, ifindex1; @@ -45,7 +44,7 @@ setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_ route.ifindex = ifindex; route.mss = 0; - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "6.6.6.0", &route.network); route.plen = 24; route.gateway = INADDR_ANY; @@ -53,7 +52,7 @@ setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_ route.mss = mss_of_first_route; g_array_append_val (routes, route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "7.0.0.0", &route.network); route.plen = 8; inet_pton (AF_INET, "6.6.6.1", &route.gateway); @@ -87,21 +86,21 @@ setup_dev1_ip4 (int ifindex) route.mss)) g_assert_not_reached (); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "6.6.6.0", &route.network); route.plen = 24; route.gateway = INADDR_ANY; route.metric = 20; g_array_append_val (routes, route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "7.0.0.0", &route.network); route.plen = 8; route.gateway = INADDR_ANY; route.metric = 22; g_array_append_val (routes, route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "8.0.0.0", &route.network); route.plen = 8; inet_pton (AF_INET, "6.6.6.2", &route.gateway); @@ -121,14 +120,14 @@ update_dev0_ip4 (int ifindex) route.ifindex = ifindex; route.mss = 0; - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "6.6.6.0", &route.network); route.plen = 24; route.gateway = INADDR_ANY; route.metric = 20; g_array_append_val (routes, route); - route.source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); inet_pton (AF_INET, "7.0.0.0", &route.network); route.plen = 8; route.gateway = INADDR_ANY; @@ -163,7 +162,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP4Route state1[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex0, @@ -173,7 +172,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("7.0.0.0"), .plen = 8, .ifindex = fixture->ifindex0, @@ -183,7 +182,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("7.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -193,7 +192,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex1, @@ -203,7 +202,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("8.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -216,7 +215,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP4Route state2[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex0, @@ -226,7 +225,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("7.0.0.0"), .plen = 8, .ifindex = fixture->ifindex0, @@ -236,7 +235,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("7.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -246,7 +245,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex1, @@ -256,7 +255,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("8.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -269,7 +268,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP4Route state3[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("7.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -279,7 +278,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex1, @@ -289,7 +288,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("8.0.0.0"), .plen = 8, .ifindex = fixture->ifindex1, @@ -299,7 +298,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data) .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE), }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet4_from_string ("6.6.6.0"), .plen = 24, .ifindex = fixture->ifindex1, @@ -542,7 +541,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP6Route state1[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex0, @@ -551,7 +550,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex0, @@ -560,7 +559,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), .plen = 64, .ifindex = fixture->ifindex0, @@ -569,7 +568,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -578,7 +577,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -587,7 +586,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -596,7 +595,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:d34d::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -608,7 +607,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP6Route state2[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex0, @@ -617,7 +616,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex0, @@ -626,7 +625,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), .plen = 64, .ifindex = fixture->ifindex0, @@ -635,7 +634,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -644,7 +643,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -653,7 +652,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -662,7 +661,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:d34d::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -674,7 +673,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) NMPlatformIP6Route state3[] = { { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -683,7 +682,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -692,7 +691,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -701,7 +700,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:1337::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -710,7 +709,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:8086::"), .plen = 48, .ifindex = fixture->ifindex1, @@ -719,7 +718,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data) .mss = 0, }, { - .source = NM_IP_CONFIG_SOURCE_USER, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), .network = *nmtst_inet6_from_string ("2001:db8:d34d::"), .plen = 64, .ifindex = fixture->ifindex1, @@ -787,6 +786,7 @@ static void _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NMPlatformIPXRoute *route) { const NMPlatformIPXRoute *r; + NMPlatformIPXRoute c; g_assert (route); @@ -800,11 +800,18 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM } else { char buf[sizeof (_nm_utils_to_string_buffer)]; - if (!r || vtable->route_cmp (route, r) != 0) + if (r) { + if (vtable->is_ip4) + c.r4 = route->r4; + else + c.r6 = route->r6; + c.rx.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (c.rx.rt_source); + } + if (!r || vtable->route_cmp (r, &c) != 0) { g_error ("Invalid route. Expect %s, has %s", - vtable->route_to_string (route, NULL, 0), + vtable->route_to_string (&c, NULL, 0), vtable->route_to_string (r, buf, sizeof (buf))); - g_assert (r); + } } } diff --git a/src/tests/test-systemd.c b/src/tests/test-systemd.c index 936bff20..744b55c9 100644 --- a/src/tests/test-systemd.c +++ b/src/tests/test-systemd.c @@ -25,7 +25,52 @@ #include "sd-lldp.h" #include "sd-event.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" + +/***************************************************************************** + * Stub implementations of libNetworkManagerBase symbols + *****************************************************************************/ + +gboolean +nm_utils_get_testing_initialized (void) +{ + return TRUE; +} + +void +_nm_utils_set_testing (NMUtilsTestFlags flags) +{ + g_assert_not_reached (); +} + +gint32 +nm_utils_get_monotonic_timestamp_s (void) +{ + return 1; +} + +NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL]; + +void +_nm_log_impl (const char *file, + guint line, + const char *func, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *fmt, + ...) +{ +} + +gboolean +nm_logging_setup (const char *level, + const char *domains, + char **bad_domains, + GError **error) +{ + return TRUE; +} /*****************************************************************************/ @@ -39,6 +84,12 @@ test_dhcp_create (void) g_assert (r == 0); g_assert (client4); + if (/* never true */ client4 == (gpointer) &r) { + /* we don't want to call this, but ensure that the linker + * includes all these symbols. */ + sd_dhcp_client_start (client4); + } + sd_dhcp_client_unref (client4); } @@ -48,10 +99,9 @@ static void test_lldp_create (void) { sd_lldp *lldp = NULL; - int ifindex = 1; int r; - r = sd_lldp_new (&lldp, ifindex); + r = sd_lldp_new (&lldp); g_assert (r == 0); g_assert (lldp); diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c index 6fc3978b..000a9d1e 100644 --- a/src/tests/test-utils.c +++ b/src/tests/test-utils.c @@ -26,7 +26,7 @@ #include "nm-core-utils.c" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static void test_stable_privacy (void) @@ -34,21 +34,93 @@ test_stable_privacy (void) struct in6_addr addr1; inet_pton (AF_INET6, "1234::", &addr1); - _set_stable_privacy (&addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL); + _set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL); nmtst_assert_ip6_address (&addr1, "1234::4ceb:14cd:3d54:793f"); /* We get an address without the UUID. */ inet_pton (AF_INET6, "1::", &addr1); - _set_stable_privacy (&addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL); + _set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL); nmtst_assert_ip6_address (&addr1, "1::11aa:2530:9144:dafa"); /* We get a different address in a different network. */ inet_pton (AF_INET6, "2::", &addr1); - _set_stable_privacy (&addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL); + _set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL); nmtst_assert_ip6_address (&addr1, "2::338e:8d:c11:8726"); + + inet_pton (AF_INET6, "1234::", &addr1); + _set_stable_privacy (NM_UTILS_STABLE_TYPE_STABLE_ID, &addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL); + nmtst_assert_ip6_address (&addr1, "1234::ad4c:ae44:3d30:af1e"); + + inet_pton (AF_INET6, "1234::", &addr1); + _set_stable_privacy (NM_UTILS_STABLE_TYPE_STABLE_ID, &addr1, "eth666", "stable-id-1", 0, (guint8 *) "key", 3, NULL); + nmtst_assert_ip6_address (&addr1, "1234::4944:67b0:7a6c:1cf"); +} + +/*****************************************************************************/ + +static void +_do_test_hw_addr (NMUtilsStableType stable_type, + const char *stable_id, + const guint8 *secret_key, + gsize key_len, + const char *ifname, + const char *current_mac_address, + const char *generate_mac_address_mask, + const char **expected) +{ + gs_free char *generated = NULL; + const char **e; + gboolean found = FALSE; + + for (e = expected; *e; e++) { + g_assert (*e); + g_assert (nm_utils_hwaddr_valid (*e, ETH_ALEN)); + } + + generated = _hw_addr_gen_stable_eth (stable_type, + stable_id, + secret_key, + key_len, + ifname, + current_mac_address, + generate_mac_address_mask); + + g_assert (generated); + g_assert (nm_utils_hwaddr_valid (generated, ETH_ALEN)); + for (e = expected; *e; e++) { + if (!nm_utils_hwaddr_matches (generated, -1, *e, -1)) + continue; + g_assert (!found); + found = TRUE; + g_assert_cmpstr (generated, ==, *e); + } + g_assert (found); +} +#define do_test_hw_addr(stable_type, stable_id, secret_key, ifname, current_mac_address, generate_mac_address_mask, ...) \ + _do_test_hw_addr ((stable_type), (stable_id), (const guint8 *) ""secret_key"", NM_STRLEN (secret_key), (ifname), ""current_mac_address"", generate_mac_address_mask, (const char *[]) { __VA_ARGS__, NULL }) + +static void +test_hw_addr_gen_stable_eth (void) +{ + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", NULL, "06:0D:CD:0C:9E:2C"); + do_test_hw_addr (NM_UTILS_STABLE_TYPE_STABLE_ID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", NULL, "C6:AE:A9:9A:76:09"); + + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "FF:FF:FF:00:00:00", "00:23:45:0C:9E:2C"); + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "03:23:45:67:89:ab", "FF:FF:FF:00:00:00", "02:23:45:0C:9E:2C"); + + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "00:00:00:00:00:00", "06:0D:CD:0C:9E:2C"); + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00", "04:0D:CD:0C:9E:2C"); + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00", "04:0D:CD:0C:9E:2C"); + + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 00:00:00:00:00:00", "04:0D:CD:0C:9E:2C"); + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 02:00:00:00:00:00", "06:0D:CD:0C:9E:2C"); + + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "00:00:00:00:00:00 E9:60:CE:F5:ED:2F", "06:0D:CD:0C:9E:2C"); + + do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00", "06:0D:CD:0C:9E:2C", "04:0D:CD:0C:9E:2C"); } -/*******************************************/ +/*****************************************************************************/ NMTST_DEFINE (); @@ -58,6 +130,7 @@ main (int argc, char **argv) nmtst_init_with_logging (&argc, &argv, NULL, "ALL"); g_test_add_func ("/utils/stable_privacy", test_stable_privacy); + g_test_add_func ("/utils/hw_addr_gen_stable_eth", test_hw_addr_gen_stable_eth); return g_test_run (); } diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c index 6edd5ff2..3ae3a19d 100644 --- a/src/tests/test-wired-defname.c +++ b/src/tests/test-wired-defname.c @@ -24,7 +24,7 @@ #include "nm-setting-connection.h" #include "nm-device-ethernet-utils.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" static NMConnection * _new_connection (const char *id) @@ -41,12 +41,28 @@ _new_connection (const char *id) /*******************************************/ +static char * +_get_default_wired_name (GSList *list) +{ + gs_free NMConnection **v = NULL; + guint l, i; + + l = g_slist_length (list); + v = g_new0 (NMConnection *, l + 1); + for (i = 0; list; list = list->next, i++) + v[i] = NM_CONNECTION (list->data); + g_assert (i == l); + return nm_device_ethernet_utils_get_default_wired_name (v); +} + +/*******************************************/ + static void test_defname_no_connections (void) { gs_free char *name = NULL; - name = nm_device_ethernet_utils_get_default_wired_name (NULL); + name = _get_default_wired_name (NULL); g_assert_cmpstr (name, ==, "Wired connection 1"); } @@ -62,7 +78,7 @@ test_defname_no_conflict (void) list = g_slist_append (list, _new_connection ("work wifi")); list = g_slist_append (list, _new_connection ("random gsm connection")); - name = nm_device_ethernet_utils_get_default_wired_name (list); + name = _get_default_wired_name (list); g_assert_cmpstr (name, ==, "Wired connection 1"); g_slist_free_full (list, g_object_unref); @@ -80,7 +96,7 @@ test_defname_conflict (void) list = g_slist_append (list, _new_connection ("Wired connection 1")); list = g_slist_append (list, _new_connection ("random gsm connection")); - name = nm_device_ethernet_utils_get_default_wired_name (list); + name = _get_default_wired_name (list); g_assert_cmpstr (name, ==, "Wired connection 2"); g_slist_free_full (list, g_object_unref); @@ -102,7 +118,7 @@ test_defname_multiple_conflicts (void) list = g_slist_append (list, _new_connection ("work wifi")); list = g_slist_append (list, _new_connection ("a vpn")); - name = nm_device_ethernet_utils_get_default_wired_name (list); + name = _get_default_wired_name (list); g_assert_cmpstr (name, ==, "Wired connection 4"); g_slist_free_full (list, g_object_unref); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index cb8474aa..92c5bd8f 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -27,6 +27,8 @@ #include <arpa/inet.h> #include <errno.h> #include <stdlib.h> +#include <unistd.h> +#include <syslog.h> #include "nm-vpn-connection.h" #include "nm-ip4-config.h" @@ -48,8 +50,6 @@ #include "nmdbus-vpn-connection.h" -G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) - typedef enum { /* Only system secrets */ SECRETS_REQ_SYSTEM = 0, @@ -78,6 +78,24 @@ typedef enum { STATE_FAILED, } VpnState; +enum { + VPN_STATE_CHANGED, + INTERNAL_STATE_CHANGED, + INTERNAL_RETRY_AFTER_FAILURE, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +NM_GOBJECT_PROPERTIES_DEFINE (NMVpnConnection, + PROP_VPN_STATE, + PROP_BANNER, +#define PROP_IP4_CONFIG 2000 +#define PROP_IP6_CONFIG 2001 +#define PROP_MASTER 2002 +); + typedef struct { gboolean service_can_persist; gboolean connection_can_persist; @@ -126,29 +144,45 @@ typedef struct { guint32 mtu; } NMVpnConnectionPrivate; -#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVpnConnectionPrivate)) - -enum { - VPN_STATE_CHANGED, - INTERNAL_STATE_CHANGED, - INTERNAL_RETRY_AFTER_FAILURE, - - LAST_SIGNAL +struct _NMVpnConnection { + NMActiveConnection parent; + NMVpnConnectionPrivate _priv; }; -static guint signals[LAST_SIGNAL] = { 0 }; +struct _NMVpnConnectionClass { + NMActiveConnectionClass parent; -enum { - PROP_0, - PROP_VPN_STATE, - PROP_BANNER, - PROP_IP4_CONFIG, - PROP_IP6_CONFIG, - PROP_MASTER = 2000, + /* Signals */ + void (*vpn_state_changed) (NMVpnConnection *self, + NMVpnConnectionState new_state, + NMVpnConnectionStateReason reason); + + /* not exported over D-Bus */ + void (*internal_state_changed) (NMVpnConnection *self, + NMVpnConnectionState new_state, + NMVpnConnectionState old_state, + NMVpnConnectionStateReason reason); - LAST_PROP + void (*internal_failed_retry) (NMVpnConnection *self); }; +G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) + +#define NM_VPN_CONNECTION_GET_PRIVATE(self) \ + ({ \ + /* preserve the const-ness of self. Unfortunately, that + * way, @self cannot be a void pointer */ \ + typeof (self) _self = (self); \ + \ + /* Get compiler error if variable is of wrong type */ \ + _nm_unused const NMVpnConnection *_self2 = (_self); \ + \ + nm_assert (NM_IS_VPN_CONNECTION (_self)); \ + &_self->_priv; \ + }) + +/*****************************************************************************/ + static NMSettingsConnection *_get_settings_connection (NMVpnConnection *self, gboolean allow_missing); @@ -493,7 +527,7 @@ _set_vpn_state (NMVpnConnection *self, new_external_state, old_external_state, reason); - g_object_notify (G_OBJECT (self), NM_VPN_CONNECTION_VPN_STATE); + _notify (self, PROP_VPN_STATE); } switch (vpn_state) { @@ -681,7 +715,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32 if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32)) route.gateway = 0; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; nm_ip4_config_add_route (config, &route); @@ -693,7 +727,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32 memset (&route, 0, sizeof (route)); route.network = parent_gw; route.plen = 32; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; nm_ip4_config_add_route (config, &route); @@ -733,7 +767,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128)) route.gateway = in6addr_any; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; nm_ip6_config_add_route (config, &route); @@ -745,7 +779,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, memset (&route, 0, sizeof (route)); route.network = *parent_gw; route.plen = 128; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; nm_ip6_config_add_route (config, &route); @@ -1246,7 +1280,7 @@ process_generic_config (NMVpnConnection *self, GVariant *dict) g_clear_pointer (&priv->banner, g_free); if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &str)) { priv->banner = g_strdup (str); - g_object_notify (G_OBJECT (self), NM_VPN_CONNECTION_BANNER); + _notify (self, PROP_BANNER); } /* External world-visible address of the VPN server */ @@ -1338,6 +1372,8 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) const char *str; GVariant *v; gboolean b; + guint i, n; + int ip_ifindex; g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT)); @@ -1365,7 +1401,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) priv->has_ip6 = FALSE; } - config = nm_ip4_config_new (nm_vpn_connection_get_ip_ifindex (self, TRUE)); + ip_ifindex = nm_vpn_connection_get_ip_ifindex (self, TRUE); + if (ip_ifindex <= 0) + g_return_if_reached (); + + config = nm_ip4_config_new (ip_ifindex); nm_ip4_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN); memset (&address, 0, sizeof (address)); @@ -1389,7 +1429,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) address.plen = u32; if (address.address && address.plen && address.plen <= 32) { - address.source = NM_IP_CONFIG_SOURCE_VPN; + address.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (config, &address); } else { _LOGW ("invalid IP4 config received!"); @@ -1424,9 +1464,17 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) route_metric = nm_vpn_connection_get_ip4_route_metric (self); - if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) { + if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b) + && b) { + if (priv->ip4_config) { + n = nm_ip4_config_get_num_routes (priv->ip4_config); + for (i = 0; i < n; i++) + nm_ip4_config_add_route (config, nm_ip4_config_get_route (priv->ip4_config, i)); + } + } else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) { while (g_variant_iter_next (iter, "@au", &v)) { NMPlatformIP4Route route = { 0, }; + guint32 plen; switch (g_variant_n_children (v)) { case 5: @@ -1434,14 +1482,15 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) /* fallthrough */ case 4: g_variant_get_child (v, 0, "u", &route.network); - g_variant_get_child (v, 1, "u", &route.plen); + g_variant_get_child (v, 1, "u", &plen); g_variant_get_child (v, 2, "u", &route.gateway); /* 4th item is unused route metric */ route.metric = route_metric; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; - if (route.plen > 32) + if (plen > 32 || plen == 0) break; + route.plen = plen; /* Ignore host routes to the VPN gateway since NM adds one itself * below. Since NM knows more about the routing situation than @@ -1473,7 +1522,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) } else { priv->ip4_config = config; nm_exported_object_export (NM_EXPORTED_OBJECT (config)); - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP4_CONFIG); + g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP4_CONFIG); } nm_vpn_connection_config_maybe_complete (self, TRUE); @@ -1490,6 +1539,8 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) const char *str; GVariant *v; gboolean b; + guint i, n; + int ip_ifindex; g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT)); @@ -1504,7 +1555,11 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) return; } - config = nm_ip6_config_new (priv->ip_ifindex); + ip_ifindex = nm_vpn_connection_get_ip_ifindex (self, TRUE); + if (ip_ifindex <= 0) + g_return_if_reached (); + + config = nm_ip6_config_new (ip_ifindex); nm_ip6_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN); memset (&address, 0, sizeof (address)); @@ -1532,7 +1587,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) address.plen = u32; if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen && address.plen <= 128) { - address.source = NM_IP_CONFIG_SOURCE_VPN; + address.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (config, &address); } else { _LOGW ("invalid IP6 config received!"); @@ -1566,7 +1621,14 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) route_metric = nm_vpn_connection_get_ip6_route_metric (self); - if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &iter)) { + if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, "b", &b) + && b) { + if (priv->ip6_config) { + n = nm_ip6_config_get_num_routes (priv->ip6_config); + for (i = 0; i < n; i++) + nm_ip6_config_add_route (config, nm_ip6_config_get_route (priv->ip6_config, i)); + } + } else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &iter)) { GVariant *dest, *next_hop; guint32 prefix, metric; @@ -1578,13 +1640,13 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) if (!ip6_addr_from_variant (dest, &route.network)) goto next; - if (prefix > 128) + if (prefix > 128 || prefix == 0) goto next; route.plen = prefix; ip6_addr_from_variant (next_hop, &route.gateway); route.metric = route_metric; - route.source = NM_IP_CONFIG_SOURCE_VPN; + route.rt_source = NM_IP_CONFIG_SOURCE_VPN; /* Ignore host routes to the VPN gateway since NM adds one itself. * Since NM knows more about the routing situation than the VPN @@ -1615,7 +1677,7 @@ next: } else { priv->ip6_config = config; nm_exported_object_export (NM_EXPORTED_OBJECT (config)); - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP6_CONFIG); + g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP6_CONFIG); } nm_vpn_connection_config_maybe_complete (self, TRUE); @@ -1933,6 +1995,41 @@ _daemon_exec_timeout (gpointer data) return G_SOURCE_REMOVE; } +static int +_get_log_level (void) +{ + NMLogLevel level; + + /* curiously enough, nm-logging also uses syslog. But it + * maps NMLogLevel differently to the syslog levels then we + * do here. + * + * The reason is, that LOG_NOTICE is already something worth + * highlighting in the journal, but we have 3 levels that are + * lower then LOG_NOTICE (LOGL_TRACE, LOGL_DEBUG, LOGL_INFO), + * On the other hand, syslog only defines LOG_DEBUG and LOG_INFO. + * Thus, we must map them differently. + * + * Inside the VPN plugin, you might want to treat LOG_NOTICE as + * as low severity, not worthy to be highlighted (like NM does). */ + + level = nm_logging_get_level (LOGD_VPN_PLUGIN); + if (level != _LOGL_OFF) { + if (level <= LOGL_TRACE) + return LOG_DEBUG; + if (level <= LOGL_DEBUG) + return LOG_INFO; + if (level <= LOGL_INFO) + return LOG_NOTICE; + if (level <= LOGL_WARN) + return LOG_WARNING; + if (level <= LOGL_ERR) + return LOG_ERR; + } + + return LOG_EMERG; +} + static gboolean nm_vpn_service_daemon_exec (NMVpnConnection *self, GError **error) { @@ -1941,20 +2038,50 @@ nm_vpn_service_daemon_exec (NMVpnConnection *self, GError **error) char *vpn_argv[4]; gboolean success = FALSE; GError *spawn_error = NULL; - int i = 0; + guint i, j, n_environ; + gs_free char **envp = NULL; + char env_log_level[NM_STRLEN ("NM_VPN_LOG_LEVEL=") + 100]; + char env_log_syslog[NM_STRLEN ("NM_VPN_LOG_SYSLOG=") + 10]; + const int N_ENVIRON_EXTRA = 3; + char **p_environ; g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), FALSE); + priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + i = 0; vpn_argv[i++] = (char *) nm_vpn_plugin_info_get_program (priv->plugin_info); + g_return_val_if_fail (vpn_argv[0], FALSE); if (nm_vpn_plugin_info_supports_multiple (priv->plugin_info)) { vpn_argv[i++] = "--bus-name"; vpn_argv[i++] = priv->bus_name; } - vpn_argv[i] = NULL; - g_assert (vpn_argv[0]); + vpn_argv[i++] = NULL; + + /* we include <unistd.h> and "config.h" defines _GNU_SOURCE for us. So, we have @environ. */ + p_environ = environ; + n_environ = p_environ ? g_strv_length (p_environ) : 0; + envp = g_new (char *, n_environ + N_ENVIRON_EXTRA); + for (i = 0, j = 0; j < n_environ; j++) { + if ( g_str_has_prefix (p_environ[j], "NM_VPN_LOG_LEVEL=") + || g_str_has_prefix (p_environ[j], "NM_VPN_LOG_SYSLOG=")) + continue; + envp[i++] = p_environ[j]; + } - success = g_spawn_async (NULL, vpn_argv, NULL, 0, nm_utils_setpgid, NULL, &pid, &spawn_error); + /* NM_VPN_LOG_LEVEL: the syslog logging level for the plugin. */ + envp[i++] = nm_sprintf_buf (env_log_level, "NM_VPN_LOG_LEVEL=%d", _get_log_level ()); + + /* NM_VPN_LOG_SYSLOG: whether to log to stdout or syslog. If NetworkManager itself runs in + * foreground, we also want the plugin to log to stdout. + * If the plugin runs in background, the plugin should prefer logging to syslog. Otherwise + * logging messages will be lost (unless using journald, in which case it wouldn't matter). */ + envp[i++] = nm_sprintf_buf (env_log_syslog, "NM_VPN_LOG_SYSLOG=%c", nm_logging_syslog_enabled () ? '1' : '0'); + + envp[i++] = NULL; + nm_assert (i <= n_environ + N_ENVIRON_EXTRA); + + success = g_spawn_async (NULL, vpn_argv, envp, 0, nm_utils_setpgid, NULL, &pid, &spawn_error); if (success) { _LOGI ("Started the VPN service, PID %ld", (long int) pid); @@ -2030,10 +2157,8 @@ nm_vpn_connection_activate (NMVpnConnection *self, s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self)); g_return_if_fail (s_vpn); - service = nm_vpn_plugin_info_lookup_property (plugin_info, - NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, - "service"); - g_return_if_fail (service); + service = nm_vpn_plugin_info_get_service (plugin_info); + nm_assert (service); if (nm_vpn_plugin_info_supports_multiple (plugin_info)) { const char *path; @@ -2421,7 +2546,7 @@ device_changed (NMActiveConnection *active, NMDevice *new_device, NMDevice *old_device) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (active); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE ((NMVpnConnection *) active); if (!_service_and_connection_can_persist (NM_VPN_CONNECTION (active))) return; @@ -2494,7 +2619,7 @@ dispose (GObject *object) static void finalize (GObject *object) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE ((NMVpnConnection *) object); g_free (priv->banner); g_free (priv->ip_iface); @@ -2515,7 +2640,7 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE ((NMVpnConnection *) object); NMDevice *parent_dev; switch (prop_id) { @@ -2547,8 +2672,6 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) GObjectClass *object_class = G_OBJECT_CLASS (connection_class); NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class); - g_type_class_add_private (connection_class, sizeof (NMVpnConnectionPrivate)); - /* virtual methods */ object_class->get_property = get_property; object_class->dispose = dispose; @@ -2556,51 +2679,49 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) active_class->device_state_changed = device_state_changed; active_class->device_changed = device_changed; - g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); - - /* properties */ - g_object_class_install_property - (object_class, PROP_VPN_STATE, - g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "", - NM_VPN_CONNECTION_STATE_UNKNOWN, - NM_VPN_CONNECTION_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property - (object_class, PROP_BANNER, - g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + obj_properties[PROP_VPN_STATE] = + g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "", + NM_VPN_CONNECTION_STATE_UNKNOWN, + NM_VPN_CONNECTION_STATE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BANNER] = + g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_override_property (object_class, PROP_MASTER, + NM_ACTIVE_CONNECTION_MASTER); g_object_class_override_property (object_class, PROP_IP4_CONFIG, NM_ACTIVE_CONNECTION_IP4_CONFIG); g_object_class_override_property (object_class, PROP_IP6_CONFIG, NM_ACTIVE_CONNECTION_IP6_CONFIG); - /* signals */ signals[VPN_STATE_CHANGED] = - g_signal_new ("vpn-state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + g_signal_new ("vpn-state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); signals[INTERNAL_STATE_CHANGED] = - g_signal_new (NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + g_signal_new (NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); signals[INTERNAL_RETRY_AFTER_FAILURE] = - g_signal_new (NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); + g_signal_new (NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (connection_class), NMDBUS_TYPE_VPN_CONNECTION_SKELETON, diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index 68374329..3fe56054 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -47,27 +47,7 @@ #define NM_VPN_ROUTE_METRIC_DEFAULT 50 - -struct _NMVpnConnection { - NMActiveConnection parent; -}; - -typedef struct { - NMActiveConnectionClass parent; - - /* Signals */ - void (*vpn_state_changed) (NMVpnConnection *self, - NMVpnConnectionState new_state, - NMVpnConnectionStateReason reason); - - /* not exported over D-Bus */ - void (*internal_state_changed) (NMVpnConnection *self, - NMVpnConnectionState new_state, - NMVpnConnectionState old_state, - NMVpnConnectionStateReason reason); - - void (*internal_failed_retry) (NMVpnConnection *self); -} NMVpnConnectionClass; +typedef struct _NMVpnConnectionClass NMVpnConnectionClass; GType nm_vpn_connection_get_type (void); diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index f557e27a..9ccd882d 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -22,7 +22,6 @@ #ifndef __NETWORKMANAGER_VPN_MANAGER_H__ #define __NETWORKMANAGER_VPN_MANAGER_H__ -#include "nm-default.h" #include "nm-vpn-connection.h" #define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) |