diff options
| author | Michael Biebl <biebl@debian.org> | 2016-01-20 16:26:51 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-01-20 16:26:51 +0100 |
| commit | 494f296a3baab08522617b24b1f126d8f9a17502 (patch) | |
| tree | c8ef32fb0dd1c4ff35a0b38e787abb58692de0cd /libnm-core | |
| parent | 54f6333410ffd570e62717d9e77c5c987175e397 (diff) | |
Imported Upstream version 1.1.90 upstream/1.1.90
Diffstat (limited to 'libnm-core')
90 files changed, 7872 insertions, 527 deletions
diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am index d76a48da..527a1c24 100644 --- a/libnm-core/Makefile.am +++ b/libnm-core/Makefile.am @@ -3,11 +3,13 @@ include $(GLIB_MAKEFILE) SUBDIRS = . tests AM_CPPFLAGS = \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ + -I${top_srcdir}/shared \ + -I${top_builddir}/shared \ -DG_LOG_DOMAIN=\""libnm"\" \ -DLOCALEDIR=\"$(datadir)/locale\" \ - -DNETWORKMANAGER_COMPILATION \ + -DNMCONFDIR=\"$(nmconfdir)\" \ + -DNMLIBDIR=\"$(nmlibdir)\" \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) @@ -34,9 +36,9 @@ libnm_core_la_LIBADD = \ $(UUID_LIBS) if WITH_GNUTLS -AM_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +AM_CPPFLAGS += $(GNUTLS_CFLAGS) libnm_core_la_SOURCES += crypto_gnutls.c -libnm_core_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) +libnm_core_la_LIBADD += $(GNUTLS_LIBS) endif if WITH_NSS diff --git a/libnm-core/Makefile.in b/libnm-core/Makefile.in index f4b6bcd0..7ca647e2 100644 --- a/libnm-core/Makefile.in +++ b/libnm-core/Makefile.in @@ -93,9 +93,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_GNUTLS_TRUE@am__append_1 = $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +@WITH_GNUTLS_TRUE@am__append_1 = $(GNUTLS_CFLAGS) @WITH_GNUTLS_TRUE@am__append_2 = crypto_gnutls.c -@WITH_GNUTLS_TRUE@am__append_3 = $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) +@WITH_GNUTLS_TRUE@am__append_3 = $(GNUTLS_LIBS) @WITH_NSS_TRUE@am__append_4 = $(NSS_CFLAGS) @WITH_NSS_TRUE@am__append_5 = crypto_nss.c @WITH_NSS_TRUE@am__append_6 = $(NSS_LIBS) @@ -124,14 +124,14 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = -@WITH_GNUTLS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \ -@WITH_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) +@WITH_GNUTLS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @WITH_NSS_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libnm_core_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) am__libnm_core_la_SOURCES_DIST = $(core_build)/nm-core-enum-types.c \ - $(core)/crypto.c $(core)/nm-connection.c $(core)/nm-errors.c \ + $(core)/crypto.c $(core)/nm-connection.c \ + $(core)/nm-dbus-utils.c $(core)/nm-errors.c \ $(core)/nm-keyfile-reader.c $(core)/nm-keyfile-utils.c \ $(core)/nm-keyfile-writer.c $(core)/nm-property-compare.c \ $(core)/nm-setting-8021x.c $(core)/nm-setting-adsl.c \ @@ -140,37 +140,42 @@ am__libnm_core_la_SOURCES_DIST = $(core_build)/nm-core-enum-types.c \ $(core)/nm-setting-cdma.c $(core)/nm-setting-connection.c \ $(core)/nm-setting-dcb.c $(core)/nm-setting-generic.c \ $(core)/nm-setting-gsm.c $(core)/nm-setting-infiniband.c \ - $(core)/nm-setting-ip-config.c $(core)/nm-setting-ip4-config.c \ - $(core)/nm-setting-ip6-config.c $(core)/nm-setting-olpc-mesh.c \ - $(core)/nm-setting-ppp.c $(core)/nm-setting-pppoe.c \ - $(core)/nm-setting-serial.c $(core)/nm-setting-team-port.c \ - $(core)/nm-setting-team.c $(core)/nm-setting-vlan.c \ - $(core)/nm-setting-vpn.c $(core)/nm-setting-wimax.c \ - $(core)/nm-setting-wired.c \ + $(core)/nm-setting-ip-config.c $(core)/nm-setting-ip-tunnel.c \ + $(core)/nm-setting-ip4-config.c \ + $(core)/nm-setting-ip6-config.c $(core)/nm-setting-macvlan.c \ + $(core)/nm-setting-olpc-mesh.c $(core)/nm-setting-ppp.c \ + $(core)/nm-setting-pppoe.c $(core)/nm-setting-serial.c \ + $(core)/nm-setting-team-port.c $(core)/nm-setting-team.c \ + $(core)/nm-setting-tun.c $(core)/nm-setting-vlan.c \ + $(core)/nm-setting-vpn.c $(core)/nm-setting-vxlan.c \ + $(core)/nm-setting-wimax.c $(core)/nm-setting-wired.c \ $(core)/nm-setting-wireless-security.c \ $(core)/nm-setting-wireless.c $(core)/nm-setting.c \ $(core)/nm-simple-connection.c $(core)/nm-utils.c \ + $(core)/nm-vpn-editor-plugin.c $(core)/nm-vpn-plugin-info.c \ $(core)/crypto.h $(core)/nm-connection-private.h \ - $(core)/nm-core-internal.h $(core)/nm-keyfile-internal.h \ - $(core)/nm-keyfile-utils.h $(core)/nm-property-compare.h \ - $(core)/nm-setting-private.h $(core)/nm-utils-private.h \ - crypto_gnutls.c crypto_nss.c + $(core)/nm-core-internal.h $(core)/nm-core-types-internal.h \ + $(core)/nm-keyfile-internal.h $(core)/nm-keyfile-utils.h \ + $(core)/nm-property-compare.h $(core)/nm-setting-private.h \ + $(core)/nm-utils-private.h crypto_gnutls.c crypto_nss.c am__objects_1 = nm-core-enum-types.lo crypto.lo nm-connection.lo \ - nm-errors.lo nm-keyfile-reader.lo nm-keyfile-utils.lo \ - nm-keyfile-writer.lo nm-property-compare.lo \ - nm-setting-8021x.lo nm-setting-adsl.lo nm-setting-bluetooth.lo \ - nm-setting-bond.lo nm-setting-bridge-port.lo \ - nm-setting-bridge.lo nm-setting-cdma.lo \ - nm-setting-connection.lo nm-setting-dcb.lo \ + nm-dbus-utils.lo nm-errors.lo nm-keyfile-reader.lo \ + nm-keyfile-utils.lo nm-keyfile-writer.lo \ + nm-property-compare.lo nm-setting-8021x.lo nm-setting-adsl.lo \ + nm-setting-bluetooth.lo nm-setting-bond.lo \ + nm-setting-bridge-port.lo nm-setting-bridge.lo \ + nm-setting-cdma.lo nm-setting-connection.lo nm-setting-dcb.lo \ nm-setting-generic.lo nm-setting-gsm.lo \ nm-setting-infiniband.lo nm-setting-ip-config.lo \ - nm-setting-ip4-config.lo nm-setting-ip6-config.lo \ + nm-setting-ip-tunnel.lo nm-setting-ip4-config.lo \ + nm-setting-ip6-config.lo nm-setting-macvlan.lo \ nm-setting-olpc-mesh.lo nm-setting-ppp.lo nm-setting-pppoe.lo \ nm-setting-serial.lo nm-setting-team-port.lo \ - nm-setting-team.lo nm-setting-vlan.lo nm-setting-vpn.lo \ - nm-setting-wimax.lo nm-setting-wired.lo \ - nm-setting-wireless-security.lo nm-setting-wireless.lo \ - nm-setting.lo nm-simple-connection.lo nm-utils.lo + nm-setting-team.lo nm-setting-tun.lo nm-setting-vlan.lo \ + nm-setting-vpn.lo nm-setting-vxlan.lo nm-setting-wimax.lo \ + nm-setting-wired.lo nm-setting-wireless-security.lo \ + nm-setting-wireless.lo nm-setting.lo nm-simple-connection.lo \ + nm-utils.lo nm-vpn-editor-plugin.lo nm-vpn-plugin-info.lo am__objects_2 = @WITH_GNUTLS_TRUE@am__objects_3 = crypto_gnutls.lo @WITH_NSS_TRUE@am__objects_4 = crypto_nss.lo @@ -330,7 +335,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CKDB_PATH = @CKDB_PATH@ CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ @@ -342,8 +346,6 @@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ @@ -353,6 +355,7 @@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ +DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -407,16 +410,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ +LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -453,6 +453,8 @@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@ +NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -481,7 +483,6 @@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ @@ -496,6 +497,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@ +SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ @@ -556,6 +559,7 @@ mkdir_p = @mkdir_p@ nmbinary = @nmbinary@ nmconfdir = @nmconfdir@ nmdatadir = @nmdatadir@ +nmlibdir = @nmlibdir@ nmrundir = @nmrundir@ nmstatedir = @nmstatedir@ oldincludedir = @oldincludedir@ @@ -563,6 +567,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -579,16 +584,17 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ SUBDIRS = . tests -AM_CPPFLAGS = -I${top_srcdir}/include -I${top_builddir}/include \ +AM_CPPFLAGS = -I${top_srcdir}/shared -I${top_builddir}/shared \ -DG_LOG_DOMAIN=\""libnm"\" -DLOCALEDIR=\"$(datadir)/locale\" \ - -DNETWORKMANAGER_COMPILATION \ + -DNMCONFDIR=\"$(nmconfdir)\" -DNMLIBDIR=\"$(nmlibdir)\" \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(GLIB_CFLAGS) \ $(am__append_1) $(am__append_4) noinst_LTLIBRARIES = libnm-core.la core = $(top_srcdir)/libnm-core core_build = $(top_builddir)/libnm-core libnm_core_headers = \ - $(top_builddir)/include/nm-version-macros.h \ + $(top_builddir)/shared/nm-version-macros.h \ $(core_build)/nm-core-enum-types.h \ $(core)/nm-connection.h \ $(core)/nm-core-types.h \ @@ -607,16 +613,20 @@ libnm_core_headers = \ $(core)/nm-setting-gsm.h \ $(core)/nm-setting-infiniband.h \ $(core)/nm-setting-ip-config.h \ + $(core)/nm-setting-ip-tunnel.h \ $(core)/nm-setting-ip4-config.h \ $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-macvlan.h \ $(core)/nm-setting-olpc-mesh.h \ $(core)/nm-setting-ppp.h \ $(core)/nm-setting-pppoe.h \ $(core)/nm-setting-serial.h \ $(core)/nm-setting-team-port.h \ $(core)/nm-setting-team.h \ + $(core)/nm-setting-tun.h \ $(core)/nm-setting-vlan.h \ $(core)/nm-setting-vpn.h \ + $(core)/nm-setting-vxlan.h \ $(core)/nm-setting-wimax.h \ $(core)/nm-setting-wired.h \ $(core)/nm-setting-wireless-security.h \ @@ -625,12 +635,15 @@ libnm_core_headers = \ $(core)/nm-simple-connection.h \ $(core)/nm-utils.h \ $(core)/nm-version.h \ - $(core)/nm-vpn-dbus-interface.h + $(core)/nm-vpn-dbus-interface.h \ + $(core)/nm-vpn-editor-plugin.h \ + $(core)/nm-vpn-plugin-info.h libnm_core_private_headers = \ $(core)/crypto.h \ $(core)/nm-connection-private.h \ $(core)/nm-core-internal.h \ + $(core)/nm-core-types-internal.h \ $(core)/nm-keyfile-internal.h \ $(core)/nm-keyfile-utils.h \ $(core)/nm-property-compare.h \ @@ -641,6 +654,7 @@ libnm_core_sources = \ $(core_build)/nm-core-enum-types.c \ $(core)/crypto.c \ $(core)/nm-connection.c \ + $(core)/nm-dbus-utils.c \ $(core)/nm-errors.c \ $(core)/nm-keyfile-reader.c \ $(core)/nm-keyfile-utils.c \ @@ -659,23 +673,29 @@ libnm_core_sources = \ $(core)/nm-setting-gsm.c \ $(core)/nm-setting-infiniband.c \ $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip-tunnel.c \ $(core)/nm-setting-ip4-config.c \ $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-macvlan.c \ $(core)/nm-setting-olpc-mesh.c \ $(core)/nm-setting-ppp.c \ $(core)/nm-setting-pppoe.c \ $(core)/nm-setting-serial.c \ $(core)/nm-setting-team-port.c \ $(core)/nm-setting-team.c \ + $(core)/nm-setting-tun.c \ $(core)/nm-setting-vlan.c \ $(core)/nm-setting-vpn.c \ + $(core)/nm-setting-vxlan.c \ $(core)/nm-setting-wimax.c \ $(core)/nm-setting-wired.c \ $(core)/nm-setting-wireless-security.c \ $(core)/nm-setting-wireless.c \ $(core)/nm-setting.c \ $(core)/nm-simple-connection.c \ - $(core)/nm-utils.c + $(core)/nm-utils.c \ + $(core)/nm-vpn-editor-plugin.c \ + $(core)/nm-vpn-plugin-info.c # header/source defines are in Makefile.libnm-core, so they can be shared @@ -753,6 +773,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_nss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-core-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dbus-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-keyfile-reader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-keyfile-utils.Plo@am__quote@ @@ -771,16 +792,20 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-gsm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-infiniband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip-tunnel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip6-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-macvlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-olpc-mesh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ppp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-pppoe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-serial.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-team-port.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-tun.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-vlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-vpn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-vxlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wimax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wired.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wireless-security.Plo@am__quote@ @@ -788,6 +813,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-simple-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-editor-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-plugin-info.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -831,6 +858,13 @@ nm-connection.lo: $(core)/nm-connection.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-connection.lo `test -f '$(core)/nm-connection.c' || echo '$(srcdir)/'`$(core)/nm-connection.c +nm-dbus-utils.lo: $(core)/nm-dbus-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-dbus-utils.lo -MD -MP -MF $(DEPDIR)/nm-dbus-utils.Tpo -c -o nm-dbus-utils.lo `test -f '$(core)/nm-dbus-utils.c' || echo '$(srcdir)/'`$(core)/nm-dbus-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dbus-utils.Tpo $(DEPDIR)/nm-dbus-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-dbus-utils.c' object='nm-dbus-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) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dbus-utils.lo `test -f '$(core)/nm-dbus-utils.c' || echo '$(srcdir)/'`$(core)/nm-dbus-utils.c + nm-errors.lo: $(core)/nm-errors.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-errors.lo -MD -MP -MF $(DEPDIR)/nm-errors.Tpo -c -o nm-errors.lo `test -f '$(core)/nm-errors.c' || echo '$(srcdir)/'`$(core)/nm-errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-errors.Tpo $(DEPDIR)/nm-errors.Plo @@ -957,6 +991,13 @@ nm-setting-ip-config.lo: $(core)/nm-setting-ip-config.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-setting-ip-config.lo `test -f '$(core)/nm-setting-ip-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip-config.c +nm-setting-ip-tunnel.lo: $(core)/nm-setting-ip-tunnel.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-setting-ip-tunnel.lo -MD -MP -MF $(DEPDIR)/nm-setting-ip-tunnel.Tpo -c -o nm-setting-ip-tunnel.lo `test -f '$(core)/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ip-tunnel.Tpo $(DEPDIR)/nm-setting-ip-tunnel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-ip-tunnel.c' object='nm-setting-ip-tunnel.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-setting-ip-tunnel.lo `test -f '$(core)/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip-tunnel.c + nm-setting-ip4-config.lo: $(core)/nm-setting-ip4-config.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-setting-ip4-config.lo -MD -MP -MF $(DEPDIR)/nm-setting-ip4-config.Tpo -c -o nm-setting-ip4-config.lo `test -f '$(core)/nm-setting-ip4-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip4-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ip4-config.Tpo $(DEPDIR)/nm-setting-ip4-config.Plo @@ -971,6 +1012,13 @@ nm-setting-ip6-config.lo: $(core)/nm-setting-ip6-config.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-setting-ip6-config.lo `test -f '$(core)/nm-setting-ip6-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip6-config.c +nm-setting-macvlan.lo: $(core)/nm-setting-macvlan.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-setting-macvlan.lo -MD -MP -MF $(DEPDIR)/nm-setting-macvlan.Tpo -c -o nm-setting-macvlan.lo `test -f '$(core)/nm-setting-macvlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-macvlan.Tpo $(DEPDIR)/nm-setting-macvlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-macvlan.c' object='nm-setting-macvlan.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-setting-macvlan.lo `test -f '$(core)/nm-setting-macvlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-macvlan.c + nm-setting-olpc-mesh.lo: $(core)/nm-setting-olpc-mesh.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-setting-olpc-mesh.lo -MD -MP -MF $(DEPDIR)/nm-setting-olpc-mesh.Tpo -c -o nm-setting-olpc-mesh.lo `test -f '$(core)/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`$(core)/nm-setting-olpc-mesh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-olpc-mesh.Tpo $(DEPDIR)/nm-setting-olpc-mesh.Plo @@ -1013,6 +1061,13 @@ nm-setting-team.lo: $(core)/nm-setting-team.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-setting-team.lo `test -f '$(core)/nm-setting-team.c' || echo '$(srcdir)/'`$(core)/nm-setting-team.c +nm-setting-tun.lo: $(core)/nm-setting-tun.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-setting-tun.lo -MD -MP -MF $(DEPDIR)/nm-setting-tun.Tpo -c -o nm-setting-tun.lo `test -f '$(core)/nm-setting-tun.c' || echo '$(srcdir)/'`$(core)/nm-setting-tun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-tun.Tpo $(DEPDIR)/nm-setting-tun.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-tun.c' object='nm-setting-tun.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-setting-tun.lo `test -f '$(core)/nm-setting-tun.c' || echo '$(srcdir)/'`$(core)/nm-setting-tun.c + nm-setting-vlan.lo: $(core)/nm-setting-vlan.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-setting-vlan.lo -MD -MP -MF $(DEPDIR)/nm-setting-vlan.Tpo -c -o nm-setting-vlan.lo `test -f '$(core)/nm-setting-vlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-vlan.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-vlan.Tpo $(DEPDIR)/nm-setting-vlan.Plo @@ -1027,6 +1082,13 @@ nm-setting-vpn.lo: $(core)/nm-setting-vpn.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-setting-vpn.lo `test -f '$(core)/nm-setting-vpn.c' || echo '$(srcdir)/'`$(core)/nm-setting-vpn.c +nm-setting-vxlan.lo: $(core)/nm-setting-vxlan.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-setting-vxlan.lo -MD -MP -MF $(DEPDIR)/nm-setting-vxlan.Tpo -c -o nm-setting-vxlan.lo `test -f '$(core)/nm-setting-vxlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-vxlan.Tpo $(DEPDIR)/nm-setting-vxlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-vxlan.c' object='nm-setting-vxlan.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-setting-vxlan.lo `test -f '$(core)/nm-setting-vxlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-vxlan.c + nm-setting-wimax.lo: $(core)/nm-setting-wimax.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-setting-wimax.lo -MD -MP -MF $(DEPDIR)/nm-setting-wimax.Tpo -c -o nm-setting-wimax.lo `test -f '$(core)/nm-setting-wimax.c' || echo '$(srcdir)/'`$(core)/nm-setting-wimax.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-wimax.Tpo $(DEPDIR)/nm-setting-wimax.Plo @@ -1076,6 +1138,20 @@ nm-utils.lo: $(core)/nm-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 nm-utils.lo `test -f '$(core)/nm-utils.c' || echo '$(srcdir)/'`$(core)/nm-utils.c +nm-vpn-editor-plugin.lo: $(core)/nm-vpn-editor-plugin.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-vpn-editor-plugin.lo -MD -MP -MF $(DEPDIR)/nm-vpn-editor-plugin.Tpo -c -o nm-vpn-editor-plugin.lo `test -f '$(core)/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`$(core)/nm-vpn-editor-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-vpn-editor-plugin.Tpo $(DEPDIR)/nm-vpn-editor-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-vpn-editor-plugin.c' object='nm-vpn-editor-plugin.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-vpn-editor-plugin.lo `test -f '$(core)/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`$(core)/nm-vpn-editor-plugin.c + +nm-vpn-plugin-info.lo: $(core)/nm-vpn-plugin-info.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-vpn-plugin-info.lo -MD -MP -MF $(DEPDIR)/nm-vpn-plugin-info.Tpo -c -o nm-vpn-plugin-info.lo `test -f '$(core)/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`$(core)/nm-vpn-plugin-info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-vpn-plugin-info.Tpo $(DEPDIR)/nm-vpn-plugin-info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-vpn-plugin-info.c' object='nm-vpn-plugin-info.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-vpn-plugin-info.lo `test -f '$(core)/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`$(core)/nm-vpn-plugin-info.c + mostlyclean-libtool: -rm -f *.lo diff --git a/libnm-core/Makefile.libnm-core b/libnm-core/Makefile.libnm-core index 0b606f32..fe8cc8a6 100644 --- a/libnm-core/Makefile.libnm-core +++ b/libnm-core/Makefile.libnm-core @@ -6,7 +6,7 @@ core = $(top_srcdir)/libnm-core core_build = $(top_builddir)/libnm-core libnm_core_headers = \ - $(top_builddir)/include/nm-version-macros.h \ + $(top_builddir)/shared/nm-version-macros.h \ $(core_build)/nm-core-enum-types.h \ $(core)/nm-connection.h \ $(core)/nm-core-types.h \ @@ -25,16 +25,20 @@ libnm_core_headers = \ $(core)/nm-setting-gsm.h \ $(core)/nm-setting-infiniband.h \ $(core)/nm-setting-ip-config.h \ + $(core)/nm-setting-ip-tunnel.h \ $(core)/nm-setting-ip4-config.h \ $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-macvlan.h \ $(core)/nm-setting-olpc-mesh.h \ $(core)/nm-setting-ppp.h \ $(core)/nm-setting-pppoe.h \ $(core)/nm-setting-serial.h \ $(core)/nm-setting-team-port.h \ $(core)/nm-setting-team.h \ + $(core)/nm-setting-tun.h \ $(core)/nm-setting-vlan.h \ $(core)/nm-setting-vpn.h \ + $(core)/nm-setting-vxlan.h \ $(core)/nm-setting-wimax.h \ $(core)/nm-setting-wired.h \ $(core)/nm-setting-wireless-security.h \ @@ -43,12 +47,15 @@ libnm_core_headers = \ $(core)/nm-simple-connection.h \ $(core)/nm-utils.h \ $(core)/nm-version.h \ - $(core)/nm-vpn-dbus-interface.h + $(core)/nm-vpn-dbus-interface.h \ + $(core)/nm-vpn-editor-plugin.h \ + $(core)/nm-vpn-plugin-info.h libnm_core_private_headers = \ $(core)/crypto.h \ $(core)/nm-connection-private.h \ $(core)/nm-core-internal.h \ + $(core)/nm-core-types-internal.h \ $(core)/nm-keyfile-internal.h \ $(core)/nm-keyfile-utils.h \ $(core)/nm-property-compare.h \ @@ -59,6 +66,7 @@ libnm_core_sources = \ $(core_build)/nm-core-enum-types.c \ $(core)/crypto.c \ $(core)/nm-connection.c \ + $(core)/nm-dbus-utils.c \ $(core)/nm-errors.c \ $(core)/nm-keyfile-reader.c \ $(core)/nm-keyfile-utils.c \ @@ -77,21 +85,27 @@ libnm_core_sources = \ $(core)/nm-setting-gsm.c \ $(core)/nm-setting-infiniband.c \ $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip-tunnel.c \ $(core)/nm-setting-ip4-config.c \ $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-macvlan.c \ $(core)/nm-setting-olpc-mesh.c \ $(core)/nm-setting-ppp.c \ $(core)/nm-setting-pppoe.c \ $(core)/nm-setting-serial.c \ $(core)/nm-setting-team-port.c \ $(core)/nm-setting-team.c \ + $(core)/nm-setting-tun.c \ $(core)/nm-setting-vlan.c \ $(core)/nm-setting-vpn.c \ + $(core)/nm-setting-vxlan.c \ $(core)/nm-setting-wimax.c \ $(core)/nm-setting-wired.c \ $(core)/nm-setting-wireless-security.c \ $(core)/nm-setting-wireless.c \ $(core)/nm-setting.c \ $(core)/nm-simple-connection.c \ - $(core)/nm-utils.c + $(core)/nm-utils.c \ + $(core)/nm-vpn-editor-plugin.c \ + $(core)/nm-vpn-plugin-info.c diff --git a/libnm-core/crypto.c b/libnm-core/crypto.c index 205d22c6..559ac52b 100644 --- a/libnm-core/crypto.c +++ b/libnm-core/crypto.c @@ -23,13 +23,12 @@ #include "config.h" -#include <glib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> +#include "nm-default.h" #include "crypto.h" #include "nm-errors.h" diff --git a/libnm-core/crypto.h b/libnm-core/crypto.h index 434f108d..c77ada5a 100644 --- a/libnm-core/crypto.h +++ b/libnm-core/crypto.h @@ -24,7 +24,7 @@ #ifndef __CRYPTO_H__ #define __CRYPTO_H__ -#include <glib.h> +#include "nm-default.h" #define MD5_HASH_LEN 20 #define CIPHER_DES_EDE3_CBC "DES-EDE3-CBC" diff --git a/libnm-core/crypto_gnutls.c b/libnm-core/crypto_gnutls.c index 96dddb90..3f90c77d 100644 --- a/libnm-core/crypto_gnutls.c +++ b/libnm-core/crypto_gnutls.c @@ -18,19 +18,17 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright 2007 - 2009 Red Hat, Inc. + * Copyright 2007 - 2015 Red Hat, Inc. */ #include "config.h" -#include <glib.h> -#include <glib/gi18n-lib.h> - -#include <gcrypt.h> #include <gnutls/gnutls.h> +#include <gnutls/crypto.h> #include <gnutls/x509.h> #include <gnutls/pkcs12.h> +#include "nm-default.h" #include "crypto.h" #include "nm-errors.h" @@ -68,8 +66,9 @@ crypto_decrypt (const char *cipher, gsize *out_len, GError **error) { - gcry_cipher_hd_t ctx; - gcry_error_t err; + gnutls_cipher_hd_t ctx; + gnutls_datum_t key_dt, iv_dt; + int err; int cipher_mech, i; char *output = NULL; gboolean success = FALSE; @@ -79,13 +78,13 @@ crypto_decrypt (const char *cipher, return NULL; if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) { - cipher_mech = GCRY_CIPHER_3DES; + cipher_mech = GNUTLS_CIPHER_3DES_CBC; real_iv_len = SALT_LEN; } else if (!strcmp (cipher, CIPHER_DES_CBC)) { - cipher_mech = GCRY_CIPHER_DES; + cipher_mech = GNUTLS_CIPHER_DES_CBC; real_iv_len = SALT_LEN; } else if (!strcmp (cipher, CIPHER_AES_CBC)) { - cipher_mech = GCRY_CIPHER_AES; + cipher_mech = GNUTLS_CIPHER_AES_128_CBC; real_iv_len = 16; } else { g_set_error (error, NM_CRYPTO_ERROR, @@ -105,39 +104,26 @@ crypto_decrypt (const char *cipher, output = g_malloc0 (data_len); - err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0); - if (err) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERROR_DECRYPTION_FAILED, - _("Failed to initialize the decryption cipher context: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); - goto out; - } + key_dt.data = (unsigned char *) key; + key_dt.size = key_len; + iv_dt.data = (unsigned char *) iv; + iv_dt.size = iv_len; - err = gcry_cipher_setkey (ctx, key, key_len); - if (err) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERROR_DECRYPTION_FAILED, - _("Failed to set symmetric key for decryption: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); - goto out; - } - - err = gcry_cipher_setiv (ctx, iv, iv_len); - if (err) { + err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt); + if (err < 0) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED, - _("Failed to set IV for decryption: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); + _("Failed to initialize the decryption cipher context: %s (%s)"), + gnutls_strerror_name (err), gnutls_strerror (err)); goto out; } - err = gcry_cipher_decrypt (ctx, output, data_len, data, data_len); - if (err) { + err = gnutls_cipher_decrypt2 (ctx, data, data_len, output, data_len); + if (err < 0) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED, - _("Failed to decrypt the private key: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); + _("Failed to decrypt the private key: %s (%s)"), + gnutls_strerror_name (err), gnutls_strerror (err)); goto out; } pad_len = output[data_len - 1]; @@ -174,7 +160,7 @@ out: output = NULL; } } - gcry_cipher_close (ctx); + gnutls_cipher_deinit (ctx); return output; } @@ -189,26 +175,24 @@ crypto_encrypt (const char *cipher, gsize *out_len, GError **error) { - gcry_cipher_hd_t ctx; - gcry_error_t err; + gnutls_cipher_hd_t ctx; + gnutls_datum_t key_dt, iv_dt; + int err; int cipher_mech; char *output = NULL; gboolean success = FALSE; gsize padded_buf_len, pad_len, output_len; char *padded_buf = NULL; guint32 i; - gsize salt_len; if (!crypto_init (error)) return NULL; - if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) { - cipher_mech = GCRY_CIPHER_3DES; - salt_len = SALT_LEN; - } else if (!strcmp (cipher, CIPHER_AES_CBC)) { - cipher_mech = GCRY_CIPHER_AES; - salt_len = iv_len; - } else { + if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) + cipher_mech = GNUTLS_CIPHER_3DES_CBC; + else if (!strcmp (cipher, CIPHER_AES_CBC)) + cipher_mech = GNUTLS_CIPHER_AES_128_CBC; + else { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_UNKNOWN_CIPHER, _("Private key cipher '%s' was unknown."), @@ -229,40 +213,26 @@ crypto_encrypt (const char *cipher, output = g_malloc0 (output_len); - err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0); - if (err) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERROR_ENCRYPTION_FAILED, - _("Failed to initialize the encryption cipher context: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); - goto out; - } - - err = gcry_cipher_setkey (ctx, key, key_len); - if (err) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERROR_ENCRYPTION_FAILED, - _("Failed to set symmetric key for encryption: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); - goto out; - } + key_dt.data = (unsigned char *) key; + key_dt.size = key_len; + iv_dt.data = (unsigned char *) iv; + iv_dt.size = iv_len; - /* gcrypt only wants 8 bytes of the IV (same as the DES block length) */ - err = gcry_cipher_setiv (ctx, iv, salt_len); - if (err) { + err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt); + if (err < 0) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_ENCRYPTION_FAILED, - _("Failed to set IV for encryption: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); + _("Failed to initialize the encryption cipher context: %s (%s)"), + gnutls_strerror_name (err), gnutls_strerror (err)); goto out; } - err = gcry_cipher_encrypt (ctx, output, output_len, padded_buf, padded_buf_len); - if (err) { + err = gnutls_cipher_encrypt2 (ctx, padded_buf, padded_buf_len, output, output_len); + if (err < 0) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_ENCRYPTION_FAILED, - _("Failed to encrypt the data: %s / %s."), - gcry_strsource (err), gcry_strerror (err)); + _("Failed to encrypt the data: %s (%s)"), + gnutls_strerror_name (err), gnutls_strerror (err)); goto out; } @@ -284,7 +254,7 @@ out: output = NULL; } } - gcry_cipher_close (ctx); + gnutls_cipher_deinit (ctx); return output; } @@ -449,6 +419,6 @@ crypto_randomize (void *buffer, gsize buffer_len, GError **error) if (!crypto_init (error)) return FALSE; - gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM); + gnutls_rnd (GNUTLS_RND_RANDOM, buffer, buffer_len); return TRUE; } diff --git a/libnm-core/crypto_nss.c b/libnm-core/crypto_nss.c index d0c3506b..7f61ad7c 100644 --- a/libnm-core/crypto_nss.c +++ b/libnm-core/crypto_nss.c @@ -23,9 +23,6 @@ #include "config.h" -#include <glib.h> -#include <glib/gi18n-lib.h> - #include <prinit.h> #include <nss.h> #include <pk11pub.h> @@ -36,6 +33,7 @@ #include <ciferfam.h> #include <p12plcy.h> +#include "nm-default.h" #include "crypto.h" #include "nm-errors.h" diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 8f226582..5a491b40 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -22,15 +22,13 @@ #include "config.h" -#include <glib-object.h> -#include <glib/gi18n-lib.h> #include <string.h> +#include "nm-default.h" #include "nm-connection.h" #include "nm-connection-private.h" #include "nm-utils.h" #include "nm-setting-private.h" #include "nm-core-internal.h" -#include "gsystem-local-alloc.h" /** * SECTION:nm-connection @@ -899,6 +897,34 @@ EXIT: } /** + * nm_connection_verify_secrets: + * @connection: the #NMConnection to verify in + * @error: location to store error, or %NULL + * + * Verifies the secrets in the connection. + * + * Returns: %TRUE if the secrets are valid, %FALSE if they are not + * + * Since: 1.2 + **/ +gboolean +nm_connection_verify_secrets (NMConnection *connection, GError **error) +{ + GHashTableIter iter; + NMSetting *setting; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) { + if (!nm_setting_verify_secrets (setting, connection, error)) + return FALSE; + } + return TRUE; +} + +/** * nm_connection_normalize: * @connection: the #NMConnection to normalize * @parameters: (allow-none) (element-type utf8 gpointer): a #GHashTable with @@ -1520,7 +1546,8 @@ nm_connection_get_id (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); s_con = nm_connection_get_setting_connection (connection); - g_return_val_if_fail (s_con != NULL, NULL); + if (!s_con) + return NULL; return nm_setting_connection_get_id (s_con); } @@ -1541,7 +1568,8 @@ nm_connection_get_connection_type (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); s_con = nm_connection_get_setting_connection (connection); - g_return_val_if_fail (s_con != NULL, NULL); + if (!s_con) + return NULL; return nm_setting_connection_get_connection_type (s_con); } @@ -1566,7 +1594,11 @@ nm_connection_is_virtual (NMConnection *connection) if ( !strcmp (type, NM_SETTING_BOND_SETTING_NAME) || !strcmp (type, NM_SETTING_TEAM_SETTING_NAME) || !strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME) - || !strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) + || !strcmp (type, NM_SETTING_VLAN_SETTING_NAME) + || !strcmp (type, NM_SETTING_TUN_SETTING_NAME) + || !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME) + || !strcmp (type, NM_SETTING_MACVLAN_SETTING_NAME) + || !strcmp (type, NM_SETTING_VXLAN_SETTING_NAME)) return TRUE; if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) { @@ -1837,6 +1869,24 @@ nm_connection_get_setting_ip4_config (NMConnection *connection) } /** + * nm_connection_get_setting_ip_tunnel: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIPTunnel the connection might contain. + * + * Returns: (transfer none): an #NMSettingIPTunnel if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingIPTunnel * +nm_connection_get_setting_ip_tunnel (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingIPTunnel *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP_TUNNEL); +} + +/** * nm_connection_get_setting_ip6_config: * @connection: the #NMConnection * @@ -1858,6 +1908,24 @@ nm_connection_get_setting_ip6_config (NMConnection *connection) } /** + * nm_connection_get_setting_macvlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingMacvlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingMacvlan if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingMacvlan * +nm_connection_get_setting_macvlan (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingMacvlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MACVLAN); +} + +/** * nm_connection_get_setting_olpc_mesh: * @connection: the #NMConnection * @@ -1922,6 +1990,24 @@ nm_connection_get_setting_serial (NMConnection *connection) } /** + * nm_connection_get_setting_tun: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTun the connection might contain. + * + * Returns: (transfer none): an #NMSettingTun if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingTun * +nm_connection_get_setting_tun (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingTun *) nm_connection_get_setting (connection, NM_TYPE_SETTING_TUN); +} + +/** * nm_connection_get_setting_vpn: * @connection: the #NMConnection * @@ -1938,6 +2024,24 @@ nm_connection_get_setting_vpn (NMConnection *connection) } /** + * nm_connection_get_setting_vxlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVxlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingVxlan if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingVxlan * +nm_connection_get_setting_vxlan (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingVxlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VXLAN); +} + +/** * nm_connection_get_setting_wimax: * @connection: the #NMConnection * diff --git a/libnm-core/nm-connection.h b/libnm-core/nm-connection.h index c76ad607..21e30422 100644 --- a/libnm-core/nm-connection.h +++ b/libnm-core/nm-connection.h @@ -145,6 +145,8 @@ gboolean nm_connection_diff (NMConnection *a, GHashTable **out_settings); gboolean nm_connection_verify (NMConnection *connection, GError **error); +NM_AVAILABLE_IN_1_2 +gboolean nm_connection_verify_secrets (NMConnection *connection, GError **error); gboolean nm_connection_normalize (NMConnection *connection, GHashTable *parameters, gboolean *modified, @@ -200,12 +202,17 @@ NMSettingDcb * nm_connection_get_setting_dcb (NMConnec NMSettingGeneric * nm_connection_get_setting_generic (NMConnection *connection); NMSettingGsm * nm_connection_get_setting_gsm (NMConnection *connection); NMSettingInfiniband * nm_connection_get_setting_infiniband (NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingIPTunnel * nm_connection_get_setting_ip_tunnel (NMConnection *connection); NMSettingIPConfig * nm_connection_get_setting_ip4_config (NMConnection *connection); NMSettingIPConfig * nm_connection_get_setting_ip6_config (NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlan * nm_connection_get_setting_macvlan (NMConnection *connection); NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection); NMSettingPpp * nm_connection_get_setting_ppp (NMConnection *connection); NMSettingPppoe * nm_connection_get_setting_pppoe (NMConnection *connection); NMSettingSerial * nm_connection_get_setting_serial (NMConnection *connection); +NMSettingTun * nm_connection_get_setting_tun (NMConnection *connection); NMSettingVpn * nm_connection_get_setting_vpn (NMConnection *connection); NMSettingWimax * nm_connection_get_setting_wimax (NMConnection *connection); NMSettingAdsl * nm_connection_get_setting_adsl (NMConnection *connection); @@ -213,6 +220,8 @@ NMSettingWired * nm_connection_get_setting_wired (NMConnec NMSettingWireless * nm_connection_get_setting_wireless (NMConnection *connection); NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security (NMConnection *connection); NMSettingVlan * nm_connection_get_setting_vlan (NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingVxlan * nm_connection_get_setting_vxlan (NMConnection *connection); G_END_DECLS diff --git a/libnm-core/nm-core-enum-types.c b/libnm-core/nm-core-enum-types.c index d2281653..4c580984 100644 --- a/libnm-core/nm-core-enum-types.c +++ b/libnm-core/nm-core-enum-types.c @@ -3,6 +3,8 @@ /* Generated by glib-mkenums. Do not edit */ +#include "config.h" + #include "nm-core-enum-types.h" #include "nm-version-macros.h" @@ -23,16 +25,20 @@ #include "nm-setting-gsm.h" #include "nm-setting-infiniband.h" #include "nm-setting-ip-config.h" +#include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-macvlan.h" #include "nm-setting-olpc-mesh.h" #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" #include "nm-setting-serial.h" #include "nm-setting-team-port.h" #include "nm-setting-team.h" +#include "nm-setting-tun.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" +#include "nm-setting-vxlan.h" #include "nm-setting-wimax.h" #include "nm-setting-wired.h" #include "nm-setting-wireless-security.h" @@ -41,7 +47,9 @@ #include "nm-simple-connection.h" #include "nm-utils.h" #include "nm-version.h" -#include "nm-vpn-dbus-interface.h" +#include "nm-vpn-dbus-interface.h" +#include "nm-vpn-editor-plugin.h" +#include "nm-vpn-plugin-info.h" GType nm_connection_serialization_flags_get_type (void) @@ -134,6 +142,10 @@ nm_device_type_get_type (void) { NM_DEVICE_TYPE_BRIDGE, "NM_DEVICE_TYPE_BRIDGE", "bridge" }, { NM_DEVICE_TYPE_GENERIC, "NM_DEVICE_TYPE_GENERIC", "generic" }, { NM_DEVICE_TYPE_TEAM, "NM_DEVICE_TYPE_TEAM", "team" }, + { NM_DEVICE_TYPE_TUN, "NM_DEVICE_TYPE_TUN", "tun" }, + { NM_DEVICE_TYPE_IP_TUNNEL, "NM_DEVICE_TYPE_IP_TUNNEL", "ip-tunnel" }, + { NM_DEVICE_TYPE_MACVLAN, "NM_DEVICE_TYPE_MACVLAN", "macvlan" }, + { NM_DEVICE_TYPE_VXLAN, "NM_DEVICE_TYPE_VXLAN", "vxlan" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -501,6 +513,33 @@ nm_secret_agent_capabilities_get_type (void) return g_define_type_id__volatile; } GType +nm_ip_tunnel_mode_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_IP_TUNNEL_MODE_UKNOWN, "NM_IP_TUNNEL_MODE_UKNOWN", "uknown" }, + { NM_IP_TUNNEL_MODE_IPIP, "NM_IP_TUNNEL_MODE_IPIP", "ipip" }, + { NM_IP_TUNNEL_MODE_GRE, "NM_IP_TUNNEL_MODE_GRE", "gre" }, + { NM_IP_TUNNEL_MODE_SIT, "NM_IP_TUNNEL_MODE_SIT", "sit" }, + { NM_IP_TUNNEL_MODE_ISATAP, "NM_IP_TUNNEL_MODE_ISATAP", "isatap" }, + { NM_IP_TUNNEL_MODE_VTI, "NM_IP_TUNNEL_MODE_VTI", "vti" }, + { NM_IP_TUNNEL_MODE_IP6IP6, "NM_IP_TUNNEL_MODE_IP6IP6", "ip6ip6" }, + { NM_IP_TUNNEL_MODE_IPIP6, "NM_IP_TUNNEL_MODE_IPIP6", "ipip6" }, + { NM_IP_TUNNEL_MODE_IP6GRE, "NM_IP_TUNNEL_MODE_IP6GRE", "ip6gre" }, + { NM_IP_TUNNEL_MODE_VTI6, "NM_IP_TUNNEL_MODE_VTI6", "vti6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMIPTunnelMode"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_agent_manager_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -761,6 +800,26 @@ nm_setting_connection_autoconnect_slaves_get_type (void) return g_define_type_id__volatile; } GType +nm_setting_connection_lldp_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_SETTING_CONNECTION_LLDP_DEFAULT, "NM_SETTING_CONNECTION_LLDP_DEFAULT", "default" }, + { NM_SETTING_CONNECTION_LLDP_DISABLE, "NM_SETTING_CONNECTION_LLDP_DISABLE", "disable" }, + { NM_SETTING_CONNECTION_LLDP_ENABLE_RX, "NM_SETTING_CONNECTION_LLDP_ENABLE_RX", "enable-rx" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingConnectionLldp"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_setting_dcb_flags_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -803,6 +862,48 @@ nm_setting_ip6_config_privacy_get_type (void) return g_define_type_id__volatile; } GType +nm_setting_ip6_config_addr_gen_mode_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_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, "NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64", "eui64" }, + { NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, "NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY", "stable-privacy" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingIP6ConfigAddrGenMode"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_macvlan_mode_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_SETTING_MACVLAN_MODE_UNKNOWN, "NM_SETTING_MACVLAN_MODE_UNKNOWN", "unknown" }, + { NM_SETTING_MACVLAN_MODE_VEPA, "NM_SETTING_MACVLAN_MODE_VEPA", "vepa" }, + { NM_SETTING_MACVLAN_MODE_BRIDGE, "NM_SETTING_MACVLAN_MODE_BRIDGE", "bridge" }, + { NM_SETTING_MACVLAN_MODE_PRIVATE, "NM_SETTING_MACVLAN_MODE_PRIVATE", "private" }, + { NM_SETTING_MACVLAN_MODE_PASSTHRU, "NM_SETTING_MACVLAN_MODE_PASSTHRU", "passthru" }, + { NM_SETTING_MACVLAN_MODE_SOURCE, "NM_SETTING_MACVLAN_MODE_SOURCE", "source" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingMacvlanMode"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_setting_serial_parity_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -823,6 +924,26 @@ nm_setting_serial_parity_get_type (void) return g_define_type_id__volatile; } GType +nm_setting_tun_mode_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_SETTING_TUN_MODE_UNKNOWN, "NM_SETTING_TUN_MODE_UNKNOWN", "unknown" }, + { NM_SETTING_TUN_MODE_TUN, "NM_SETTING_TUN_MODE_TUN", "tun" }, + { NM_SETTING_TUN_MODE_TAP, "NM_SETTING_TUN_MODE_TAP", "tap" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingTunMode"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_vlan_priority_map_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -852,6 +973,7 @@ nm_vlan_flags_get_type (void) { NM_VLAN_FLAG_REORDER_HEADERS, "NM_VLAN_FLAG_REORDER_HEADERS", "reorder-headers" }, { NM_VLAN_FLAG_GVRP, "NM_VLAN_FLAG_GVRP", "gvrp" }, { NM_VLAN_FLAG_LOOSE_BINDING, "NM_VLAN_FLAG_LOOSE_BINDING", "loose-binding" }, + { NM_VLAN_FLAG_MVRP, "NM_VLAN_FLAG_MVRP", "mvrp" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -955,6 +1077,26 @@ nm_setting_compare_flags_get_type (void) return g_define_type_id__volatile; } GType +nm_setting_mac_randomization_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_SETTING_MAC_RANDOMIZATION_DEFAULT, "NM_SETTING_MAC_RANDOMIZATION_DEFAULT", "default" }, + { NM_SETTING_MAC_RANDOMIZATION_NEVER, "NM_SETTING_MAC_RANDOMIZATION_NEVER", "never" }, + { NM_SETTING_MAC_RANDOMIZATION_ALWAYS, "NM_SETTING_MAC_RANDOMIZATION_ALWAYS", "always" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingMacRandomization"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_setting_diff_result_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -1100,6 +1242,27 @@ nm_vpn_plugin_failure_get_type (void) return g_define_type_id__volatile; } +GType +nm_vpn_editor_plugin_capability_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_VPN_EDITOR_PLUGIN_CAPABILITY_NONE, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE", "none" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT", "import" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT", "export" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6", "ipv6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMVpnEditorPluginCapability"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} diff --git a/libnm-core/nm-core-enum-types.h b/libnm-core/nm-core-enum-types.h index 7e5c6df0..1c16cb21 100644 --- a/libnm-core/nm-core-enum-types.h +++ b/libnm-core/nm-core-enum-types.h @@ -43,6 +43,8 @@ GType nm_secret_agent_get_secrets_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_SECRET_AGENT_GET_SECRETS_FLAGS (nm_secret_agent_get_secrets_flags_get_type ()) GType nm_secret_agent_capabilities_get_type (void) G_GNUC_CONST; #define NM_TYPE_SECRET_AGENT_CAPABILITIES (nm_secret_agent_capabilities_get_type ()) +GType nm_ip_tunnel_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_IP_TUNNEL_MODE (nm_ip_tunnel_mode_get_type ()) GType nm_agent_manager_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) GType nm_connection_error_get_type (void) G_GNUC_CONST; @@ -65,12 +67,20 @@ GType nm_setting_802_1x_ck_scheme_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_802_1X_CK_SCHEME (nm_setting_802_1x_ck_scheme_get_type ()) GType nm_setting_connection_autoconnect_slaves_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_CONNECTION_AUTOCONNECT_SLAVES (nm_setting_connection_autoconnect_slaves_get_type ()) +GType nm_setting_connection_lldp_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_CONNECTION_LLDP (nm_setting_connection_lldp_get_type ()) GType nm_setting_dcb_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_DCB_FLAGS (nm_setting_dcb_flags_get_type ()) GType nm_setting_ip6_config_privacy_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_IP6_CONFIG_PRIVACY (nm_setting_ip6_config_privacy_get_type ()) +GType nm_setting_ip6_config_addr_gen_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_IP6_CONFIG_ADDR_GEN_MODE (nm_setting_ip6_config_addr_gen_mode_get_type ()) +GType nm_setting_macvlan_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_MACVLAN_MODE (nm_setting_macvlan_mode_get_type ()) GType nm_setting_serial_parity_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_SERIAL_PARITY (nm_setting_serial_parity_get_type ()) +GType nm_setting_tun_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_TUN_MODE (nm_setting_tun_mode_get_type ()) GType nm_vlan_priority_map_get_type (void) G_GNUC_CONST; #define NM_TYPE_VLAN_PRIORITY_MAP (nm_vlan_priority_map_get_type ()) GType nm_vlan_flags_get_type (void) G_GNUC_CONST; @@ -83,6 +93,8 @@ GType nm_setting_secret_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_SECRET_FLAGS (nm_setting_secret_flags_get_type ()) GType nm_setting_compare_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_COMPARE_FLAGS (nm_setting_compare_flags_get_type ()) +GType nm_setting_mac_randomization_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_MAC_RANDOMIZATION (nm_setting_mac_randomization_get_type ()) GType nm_setting_diff_result_get_type (void) G_GNUC_CONST; #define NM_TYPE_SETTING_DIFF_RESULT (nm_setting_diff_result_get_type ()) GType nm_utils_security_type_get_type (void) G_GNUC_CONST; @@ -95,6 +107,8 @@ GType nm_vpn_connection_state_reason_get_type (void) G_GNUC_CONST; #define NM_TYPE_VPN_CONNECTION_STATE_REASON (nm_vpn_connection_state_reason_get_type ()) GType nm_vpn_plugin_failure_get_type (void) G_GNUC_CONST; #define NM_TYPE_VPN_PLUGIN_FAILURE (nm_vpn_plugin_failure_get_type ()) +GType nm_vpn_editor_plugin_capability_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_EDITOR_PLUGIN_CAPABILITY (nm_vpn_editor_plugin_capability_get_type ()) G_END_DECLS #endif /* __NM_CORE_ENUM_TYPES_H__ */ diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 56cb7806..3e1236b9 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -33,6 +33,8 @@ * and some test programs. **/ + +#include "nm-default.h" #include "nm-connection.h" #include "nm-core-enum-types.h" #include "nm-setting-8021x.h" @@ -47,16 +49,20 @@ #include "nm-setting-generic.h" #include "nm-setting-gsm.h" #include "nm-setting-infiniband.h" +#include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-macvlan.h" #include "nm-setting-olpc-mesh.h" #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" #include "nm-setting-serial.h" #include "nm-setting-team-port.h" #include "nm-setting-team.h" +#include "nm-setting-tun.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" +#include "nm-setting-vxlan.h" #include "nm-setting-wimax.h" #include "nm-setting-wired.h" #include "nm-setting-wireless-security.h" @@ -64,22 +70,28 @@ #include "nm-setting.h" #include "nm-simple-connection.h" #include "nm-utils.h" -#include "nm-version.h" #include "nm-vpn-dbus-interface.h" - -#define NM_UTILS_CLEAR_CANCELLABLE(c) \ - if (c) { \ - g_cancellable_cancel (c); \ - g_clear_object (&c); \ - } +#include "nm-core-types-internal.h" /* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated * connection can be replaced by a already-defined connection. This flag only * takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE * flag. */ -#define NM_SETTING_COMPARE_FLAG_INFERRABLE 0x80000000 +#define NM_SETTING_COMPARE_FLAG_INFERRABLE ((NMSettingCompareFlags) 0x80000000) + +/* NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY: this flag is used for properties + * that automatically get re-applied on an active connection when the settings + * connection is modified. For most properties, the applied-connection is distinct + * from the setting-connection and changes don't propagate. Exceptions are the + * firewall-zone and the metered property. + */ +#define NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY ((NMSettingCompareFlags) 0x40000000) +/* NM_SETTING_COMPARE_FLAG_NONE: for convenience, define a special flag NONE -- which + * equals to numeric zero (NM_SETTING_COMPARE_FLAG_EXACT). + */ +#define NM_SETTING_COMPARE_FLAG_NONE ((NMSettingCompareFlags) 0) #define NM_SETTING_SECRET_FLAGS_ALL \ @@ -132,12 +144,27 @@ char ** _nm_utils_slist_to_strv (GSList *slist, gboolean deep_copy); GPtrArray * _nm_utils_strv_to_ptrarray (char **strv); char ** _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray); +gboolean _nm_utils_strv_equal (char **strv1, char **strv2); + +gboolean _nm_utils_check_file (const char *filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat *out_st, + GError **error); + +gboolean _nm_utils_check_module_file (const char *name, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error); #define NM_UTILS_UUID_TYPE_LEGACY 0 #define NM_UTILS_UUID_TYPE_VARIANT3 1 char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); +/* arbitrarily choosen namespace UUID for _nm_utils_uuid_generate_from_strings() */ #define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" char *_nm_utils_uuid_generate_from_strings (const char *string1, ...) G_GNUC_NULL_TERMINATED; @@ -152,12 +179,91 @@ GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data, char **out_password, GError **error); -/* These are public API in NM 1.2, but private on nm-1-0. */ -int nm_utils_bond_mode_string_to_int (const char *mode); -const char *nm_utils_bond_mode_int_to_string (int mode); - gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); +gulong _nm_dbus_signal_connect_data (GDBusProxy *proxy, + const char *signal_name, + const GVariantType *signature, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags); +#define _nm_dbus_signal_connect(proxy, name, signature, handler, data) \ + _nm_dbus_signal_connect_data (proxy, name, signature, handler, data, NULL, (GConnectFlags) 0) + +GVariant *_nm_dbus_proxy_call_finish (GDBusProxy *proxy, + GAsyncResult *res, + const GVariantType *reply_type, + GError **error); + +GVariant *_nm_dbus_proxy_call_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error); + gboolean _nm_dbus_error_has_name (GError *error, const char *dbus_error_name); + +/***********************************************************/ + +gboolean _nm_vpn_plugin_info_check_file (const char *filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error); + +const char *_nm_vpn_plugin_info_get_default_dir_etc (void); +const char *_nm_vpn_plugin_info_get_default_dir_lib (void); +const char *_nm_vpn_plugin_info_get_default_dir_user (void); + +GSList *_nm_vpn_plugin_info_list_load_dir (const char *dirname, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data); + +/***********************************************************/ + +typedef struct { + const char *name; + gboolean numeric; + gboolean ipv6_only; +} NMUtilsDNSOptionDesc; + +extern const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[]; + +gboolean _nm_utils_dns_option_validate (const char *option, char **out_name, + long *out_value, gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs); +int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option); + +/***********************************************************/ + +typedef struct _NMUtilsStrStrDictKey NMUtilsStrStrDictKey; +guint _nm_utils_strstrdictkey_hash (gconstpointer a); +gboolean _nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b); +NMUtilsStrStrDictKey *_nm_utils_strstrdictkey_create (const char *v1, const char *v2); + +#define _nm_utils_strstrdictkey_static(v1, v2) \ + ( (NMUtilsStrStrDictKey *) ("\03" v1 "\0" v2 "") ) + +/***********************************************************/ + +gboolean _nm_setting_vlan_set_priorities (NMSettingVlan *setting, + NMVlanPriorityMap map, + const NMVlanQosMapping *qos_map, + guint n_qos_map); +void _nm_setting_vlan_get_priorities (NMSettingVlan *setting, + NMVlanPriorityMap map, + NMVlanQosMapping **out_qos_map, + guint *out_n_qos_map); + +/***********************************************************/ + #endif diff --git a/libnm-core/nm-core-types-internal.h b/libnm-core/nm-core-types-internal.h new file mode 100644 index 00000000..442a10a3 --- /dev/null +++ b/libnm-core/nm-core-types-internal.h @@ -0,0 +1,30 @@ +/* -*- 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. + * + * (C) Copyright 2015 Red Hat, Inc. + */ + +#ifndef NM_CORE_TYPES_INTERNAL_H +#define NM_CORE_TYPES_INTERNAL_H + +typedef struct { + guint32 from; + guint32 to; +} NMVlanQosMapping; + +#endif /* NM_CORE_TYPES_INTERNAL_H */ diff --git a/libnm-core/nm-core-types.h b/libnm-core/nm-core-types.h index 19388c5b..cd19923b 100644 --- a/libnm-core/nm-core-types.h +++ b/libnm-core/nm-core-types.h @@ -42,16 +42,20 @@ typedef struct _NMSettingGeneric NMSettingGeneric; typedef struct _NMSettingGsm NMSettingGsm; typedef struct _NMSettingInfiniband NMSettingInfiniband; typedef struct _NMSettingIPConfig NMSettingIPConfig; +typedef struct _NMSettingIPTunnel NMSettingIPTunnel; typedef struct _NMSettingIP4Config NMSettingIP4Config; typedef struct _NMSettingIP6Config NMSettingIP6Config; +typedef struct _NMSettingMacvlan NMSettingMacvlan; typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh; typedef struct _NMSettingPpp NMSettingPpp; typedef struct _NMSettingPppoe NMSettingPppoe; typedef struct _NMSettingSerial NMSettingSerial; typedef struct _NMSettingTeam NMSettingTeam; typedef struct _NMSettingTeamPort NMSettingTeamPort; +typedef struct _NMSettingTun NMSettingTun; typedef struct _NMSettingVlan NMSettingVlan; typedef struct _NMSettingVpn NMSettingVpn; +typedef struct _NMSettingVxlan NMSettingVxlan; typedef struct _NMSettingWimax NMSettingWimax; typedef struct _NMSettingWired NMSettingWired; typedef struct _NMSettingWireless NMSettingWireless; diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index ac20fa2e..b32aabc2 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -29,7 +29,7 @@ /* This header must not include glib or libnm. */ #ifndef NM_VERSION_H -#define NM_AVAILABLE_IN_1_0_6 +#define NM_AVAILABLE_IN_1_2 #endif /* @@ -67,7 +67,7 @@ #define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan" #define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan" #define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre" - +#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel" #define NM_DBUS_INTERFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" #define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" @@ -148,6 +148,10 @@ typedef enum { * @NM_DEVICE_TYPE_ADSL: ADSL modem * @NM_DEVICE_TYPE_BRIDGE: a bridge master interface * @NM_DEVICE_TYPE_TEAM: a team master interface + * @NM_DEVICE_TYPE_TUN: a TUN or TAP interface + * @NM_DEVICE_TYPE_IP_TUNNEL: a IP tunnel interface + * @NM_DEVICE_TYPE_MACVLAN: a MACVLAN interface + * @NM_DEVICE_TYPE_VXLAN: a VXLAN interface * * #NMDeviceType values indicate the type of hardware represented by * an #NMDevice. @@ -171,6 +175,10 @@ typedef enum { NM_DEVICE_TYPE_BRIDGE = 13, NM_DEVICE_TYPE_GENERIC = 14, NM_DEVICE_TYPE_TEAM = 15, + NM_DEVICE_TYPE_TUN = 16, + NM_DEVICE_TYPE_IP_TUNNEL = 17, + NM_DEVICE_TYPE_MACVLAN = 18, + NM_DEVICE_TYPE_VXLAN = 19, } NMDeviceType; /** @@ -553,9 +561,9 @@ typedef enum { * * (Corresponds to the NM_METERED type in nm-device.xml.) * - * Since: 1.0.6 + * Since: 1.2 **/ -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 typedef enum { NM_METERED_UNKNOWN = 0, NM_METERED_YES = 1, @@ -644,7 +652,56 @@ typedef enum /*< flags >*/ { } NMSecretAgentCapabilities; #ifndef NM_VERSION_H -#undef NM_AVAILABLE_IN_1_0_6 +#undef NM_AVAILABLE_IN_1_2 #endif +#define NM_LLDP_ATTR_DESTINATION "destination" +#define NM_LLDP_ATTR_CHASSIS_ID_TYPE "chassis-id-type" +#define NM_LLDP_ATTR_CHASSIS_ID "chassis-id" +#define NM_LLDP_ATTR_PORT_ID_TYPE "port-id-type" +#define NM_LLDP_ATTR_PORT_ID "port-id" +#define NM_LLDP_ATTR_PORT_DESCRIPTION "port-description" +#define NM_LLDP_ATTR_SYSTEM_NAME "system-name" +#define NM_LLDP_ATTR_SYSTEM_DESCRIPTION "system-description" +#define NM_LLDP_ATTR_SYSTEM_CAPABILITIES "system-capabilities" +#define NM_LLDP_ATTR_IEEE_802_1_PVID "ieee-802-1-pvid" +#define NM_LLDP_ATTR_IEEE_802_1_PPVID "ieee-802-1-ppvid" +#define NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS "ieee-802-1-ppvid-flags" +#define NM_LLDP_ATTR_IEEE_802_1_VID "ieee-802-1-pvid" +#define NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME "ieee-802-1-vlan-name" + +#define NM_LLDP_DEST_NEAREST_BRIDGE "nearest-bridge" +#define NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE "nearest-non-tpmr-bridge" +#define NM_LLDP_DEST_NEAREST_CUSTOMER_BRIDGE "nearest-customer-bridge" + +/** + * NMIPTunnelMode: + * @NM_IP_TUNNEL_MODE_UNKNOWN: Unknown/unset tunnel mode + * @NM_IP_TUNNEL_MODE_IPIP: IP in IP tunnel + * @NM_IP_TUNNEL_MODE_GRE: GRE tunnel + * @NM_IP_TUNNEL_MODE_SIT: SIT tunnel + * @NM_IP_TUNNEL_MODE_ISATAP: ISATAP tunnel + * @NM_IP_TUNNEL_MODE_VTI: VTI tunnel + * @NM_IP_TUNNEL_MODE_IP6IP6: IPv6 in IPv6 tunnel + * @NM_IP_TUNNEL_MODE_IPIP6: IPv4 in IPv6 tunnel + * @NM_IP_TUNNEL_MODE_IP6GRE: IPv6 GRE tunnel + * @NM_IP_TUNNEL_MODE_VTI6: IPv6 VTI tunnel + * + * The tunneling mode. + * + * Since: 1.2 + */ +typedef enum { + NM_IP_TUNNEL_MODE_UKNOWN = 0, + NM_IP_TUNNEL_MODE_IPIP = 1, + NM_IP_TUNNEL_MODE_GRE = 2, + NM_IP_TUNNEL_MODE_SIT = 3, + NM_IP_TUNNEL_MODE_ISATAP = 4, + NM_IP_TUNNEL_MODE_VTI = 5, + NM_IP_TUNNEL_MODE_IP6IP6 = 6, + NM_IP_TUNNEL_MODE_IPIP6 = 7, + NM_IP_TUNNEL_MODE_IP6GRE = 8, + NM_IP_TUNNEL_MODE_VTI6 = 9, +} NMIPTunnelMode; + #endif /* __NM_DBUS_INTERFACE_H__ */ diff --git a/libnm-core/nm-dbus-utils.c b/libnm-core/nm-dbus-utils.c new file mode 100644 index 00000000..86272786 --- /dev/null +++ b/libnm-core/nm-dbus-utils.c @@ -0,0 +1,294 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> + +#include "nm-default.h" +#include "nm-core-internal.h" + +typedef struct { + char *signal_name; + const GVariantType *signature; +} NMDBusSignalData; + +static void +dbus_signal_data_free (gpointer data, GClosure *closure) +{ + NMDBusSignalData *sd = data; + + g_free (sd->signal_name); + g_slice_free (NMDBusSignalData, sd); +} + +static void +dbus_signal_meta_marshal (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + NMDBusSignalData *sd = marshal_data; + const char *signal_name; + GVariant *parameters, *param; + GValue *closure_params; + gsize n_params, i; + + g_return_if_fail (n_param_values == 4); + + signal_name = g_value_get_string (¶m_values[2]); + parameters = g_value_get_variant (¶m_values[3]); + + if (strcmp (signal_name, sd->signal_name) != 0) + return; + + if (sd->signature) { + if (!g_variant_is_of_type (parameters, sd->signature)) { + g_warning ("%p: got signal '%s' but parameters were of type '%s', not '%s'", + g_value_get_object (¶m_values[0]), + signal_name, g_variant_get_type_string (parameters), + g_variant_type_peek_string (sd->signature)); + return; + } + + n_params = g_variant_n_children (parameters) + 1; + } else + n_params = 1; + + closure_params = g_new0 (GValue, n_params); + g_value_init (&closure_params[0], G_TYPE_OBJECT); + g_value_copy (¶m_values[0], &closure_params[0]); + + for (i = 1; i < n_params; i++) { + param = g_variant_get_child_value (parameters, i - 1); + if ( g_variant_is_of_type (param, G_VARIANT_TYPE ("ay")) + || g_variant_is_of_type (param, G_VARIANT_TYPE ("aay"))) { + /* g_dbus_gvariant_to_gvalue() thinks 'ay' means "non-UTF-8 NUL-terminated string" */ + g_value_init (&closure_params[i], G_TYPE_VARIANT); + g_value_set_variant (&closure_params[i], param); + } else + g_dbus_gvariant_to_gvalue (param, &closure_params[i]); + g_variant_unref (param); + } + + g_cclosure_marshal_generic (closure, + NULL, + n_params, + closure_params, + invocation_hint, + NULL); + + for (i = 0; i < n_params; i++) + g_value_unset (&closure_params[i]); + g_free (closure_params); +} + +/** + * _nm_dbus_signal_connect_data: + * @proxy: a #GDBusProxy + * @signal_name: the D-Bus signal to connect to + * @signature: (allow-none): the signal's type signature (must be a tuple) + * @c_handler: the signal handler function + * @data: (allow-none): data to pass to @c_handler + * @destroy_data: (allow-none): closure destroy notify for @data + * @connect_flags: connection flags + * + * Connects to the D-Bus signal @signal_name on @proxy. @c_handler must be a + * void function whose first argument is a #GDBusProxy, followed by arguments + * for each element of @signature, ending with a #gpointer argument for @data. + * + * The argument types in @c_handler correspond to the types output by + * g_dbus_gvariant_to_gvalue(), except for 'ay' and 'aay'. In particular: + * - both 16-bit and 32-bit integers are passed as #gint/#guint + * - 'as' values are passed as #GStrv (char **) + * - all other array, tuple, and dict types are passed as #GVariant + * + * If @signature is %NULL, then the signal's parameters will be ignored, and + * @c_handler should take only the #GDBusProxy and #gpointer arguments. + * + * Returns: the signal handler ID, which can be used with + * g_signal_handler_remove(). Beware that because of the way the signal is + * connected, you will not be able to remove it with + * g_signal_handlers_disconnect_by_func(), although + * g_signal_handlers_disconnect_by_data() will work correctly. + */ +gulong +_nm_dbus_signal_connect_data (GDBusProxy *proxy, + const char *signal_name, + const GVariantType *signature, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags) +{ + NMDBusSignalData *sd; + GClosure *closure; + gboolean swapped = !!(connect_flags & G_CONNECT_SWAPPED); + gboolean after = !!(connect_flags & G_CONNECT_AFTER); + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), 0); + g_return_val_if_fail (signal_name != NULL, 0); + g_return_val_if_fail (signature == NULL || g_variant_type_is_tuple (signature), 0); + g_return_val_if_fail (c_handler != NULL, 0); + + sd = g_slice_new (NMDBusSignalData); + sd->signal_name = g_strdup (signal_name); + sd->signature = signature; + + closure = (swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data); + g_closure_set_marshal (closure, g_cclosure_marshal_generic); + g_closure_set_meta_marshal (closure, sd, dbus_signal_meta_marshal); + g_closure_add_finalize_notifier (closure, sd, dbus_signal_data_free); + + return g_signal_connect_closure (proxy, "g-signal", closure, after); +} + +/** + * _nm_dbus_signal_connect: + * @proxy: a #GDBusProxy + * @signal_name: the D-Bus signal to connect to + * @signature: the signal's type signature (must be a tuple) + * @c_handler: the signal handler function + * @data: (allow-none): data to pass to @c_handler + * + * Simplified version of _nm_dbus_signal_connect_data() with fewer arguments. + * + * Returns: the signal handler ID, as with _nm_signal_connect_data(). + */ + + +static void +typecheck_response (GVariant **response, + const GVariantType *reply_type, + GError **error) +{ + if (*response && reply_type && !g_variant_is_of_type (*response, reply_type)) { + /* This is the same error code that g_dbus_connection_call() returns if + * @reply_type doesn't match. + */ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Method returned type '%s', but expected '%s'"), + g_variant_get_type_string (*response), + g_variant_type_peek_string (reply_type)); + g_clear_pointer (response, g_variant_unref); + } +} + +/** + * _nm_dbus_proxy_call_finish: + * @proxy: A #GDBusProxy. + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to + * g_dbus_proxy_call(). + * @reply_type: (allow-none): the expected type of the reply, or %NULL + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_proxy_call(), as with + * g_dbus_proxy_call_finish(), except thatif @reply_type is non-%NULL, then it + * will also check that the response matches that type signature, and return + * an error if not. + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + */ +GVariant * +_nm_dbus_proxy_call_finish (GDBusProxy *proxy, + GAsyncResult *res, + const GVariantType *reply_type, + GError **error) +{ + GVariant *ret; + + ret = g_dbus_proxy_call_finish (proxy, res, error); + typecheck_response (&ret, reply_type, error); + return ret; +} + +/** + * _nm_dbus_proxy_call_sync: + * @proxy: A #GDBusProxy. + * @method_name: Name of method to invoke. + * @parameters: (allow-none): A #GVariant tuple with parameters for the signal + * or %NULL if not passing parameters. + * @reply_type: (allow-none): the expected type of the reply, or %NULL + * @flags: Flags from the #GDBusCallFlags enumeration. + * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning + * "infinite") or -1 to use the proxy default timeout. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously invokes the @method_name method on @proxy, as with + * g_dbus_proxy_call_sync(), except that if @reply_type is non-%NULL, then the + * reply to the call will be checked against it, and an error returned if it + * does not match. + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + */ +GVariant * +_nm_dbus_proxy_call_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error) +{ + GVariant *ret; + + ret = g_dbus_proxy_call_sync (proxy, method_name, parameters, + flags, timeout_msec, + cancellable, error); + typecheck_response (&ret, reply_type, error); + return ret; +} + +/** + * _nm_dbus_error_has_name: + * @error: (allow-none): a #GError, or %NULL + * @dbus_error_name: a D-Bus error name + * + * Checks if @error is set and corresponds to the D-Bus error @dbus_error_name. + * + * This should only be used for "foreign" D-Bus errors (eg, errors + * from BlueZ or wpa_supplicant). All NetworkManager D-Bus errors + * should be properly mapped by gdbus to one of the domains/codes in + * nm-errors.h. + * + * Returns: %TRUE or %FALSE + */ +gboolean +_nm_dbus_error_has_name (GError *error, + const char *dbus_error_name) +{ + gboolean has_name = FALSE; + + if (error && g_dbus_error_is_remote_error (error)) { + char *error_name; + + error_name = g_dbus_error_get_remote_error (error); + has_name = !g_strcmp0 (error_name, dbus_error_name); + g_free (error_name); + } + + return has_name; +} diff --git a/libnm-core/nm-errors.c b/libnm-core/nm-errors.c index 222f2de6..4c950f69 100644 --- a/libnm-core/nm-errors.c +++ b/libnm-core/nm-errors.c @@ -21,10 +21,9 @@ #include "config.h" #include <string.h> -#include <gio/gio.h> +#include "nm-default.h" #include "nm-errors.h" -#include "nm-glib-compat.h" #include "nm-vpn-dbus-interface.h" #include "nm-core-internal.h" diff --git a/libnm-core/nm-keyfile-internal.h b/libnm-core/nm-keyfile-internal.h index f4bb0796..7873aa7c 100644 --- a/libnm-core/nm-keyfile-internal.h +++ b/libnm-core/nm-keyfile-internal.h @@ -22,13 +22,12 @@ #ifndef __NM_KEYFILE_INTERNAL_H__ #define __NM_KEYFILE_INTERNAL_H__ -#include <glib.h> #include <sys/types.h> +#include "nm-default.h" #include "nm-connection.h" #include "nm-setting-8021x.h" - /*********************************************************/ #define NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB "data:;base64," diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c index 9d8c8734..6a0584a5 100644 --- a/libnm-core/nm-keyfile-reader.c +++ b/libnm-core/nm-keyfile-reader.c @@ -28,16 +28,12 @@ #include <sys/types.h> #include <arpa/inet.h> #include <string.h> -#include <glib/gi18n-lib.h> +#include "nm-default.h" #include "nm-core-internal.h" #include "nm-macros-internal.h" -#include "gsystem-local-alloc.h" -#include "nm-glib-compat.h" #include "nm-keyfile-internal.h" #include "nm-keyfile-utils.h" -#include "nm-setting-private.h" - typedef struct { NMConnection *connection; @@ -564,6 +560,28 @@ ip6_dns_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) } static void +ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + const char *setting_name = nm_setting_get_name (setting); + gs_free char *s = NULL; + + s = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL); + if (s) { + if (!nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), s, + (int *) &addr_gen_mode, NULL)) { + handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid option '%s', use one of [%s]"), + s, "eui64,stable-privacy"); + return; + } + } else + addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; + + g_object_set (G_OBJECT (setting), key, (gint) addr_gen_mode, NULL); +} + +static void mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize enforce_length) { const char *setting_name = nm_setting_get_name (setting); @@ -1181,6 +1199,10 @@ static KeyParser key_parsers[] = { NM_SETTING_IP_CONFIG_DNS, FALSE, ip6_dns_parser }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + FALSE, + ip6_addr_gen_mode_parser }, { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS, TRUE, @@ -1257,8 +1279,13 @@ set_default_for_missing_key (NMSetting *setting, const char *property) { /* Set a value different from the default value of the property's spec */ - if (NM_IS_SETTING_VLAN (setting) && !strcmp (property, NM_SETTING_VLAN_FLAGS)) - g_object_set (setting, property, 0, NULL); + if (NM_IS_SETTING_VLAN (setting)) { + if (!strcmp (property, NM_SETTING_VLAN_FLAGS)) + g_object_set (setting, property, (NMVlanFlags) 0, NULL); + } else if (NM_IS_SETTING_WIRELESS (setting)) { + if (!strcmp (property, NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION)) + g_object_set (setting, property, (NMSettingMacRandomization) NM_SETTING_MAC_RANDOMIZATION_NEVER, NULL); + } } static void diff --git a/libnm-core/nm-keyfile-utils.c b/libnm-core/nm-keyfile-utils.c index d04a3d1b..15b14a3e 100644 --- a/libnm-core/nm-keyfile-utils.c +++ b/libnm-core/nm-keyfile-utils.c @@ -20,18 +20,16 @@ #include "config.h" -#include <glib.h> #include <stdlib.h> #include <string.h> -#include "gsystem-local-alloc.h" +#include "nm-default.h" #include "nm-keyfile-utils.h" #include "nm-keyfile-internal.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" - typedef struct { const char *setting; const char *alias; diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c index 1dac5c32..ba1736b9 100644 --- a/libnm-core/nm-keyfile-writer.c +++ b/libnm-core/nm-keyfile-writer.c @@ -28,11 +28,8 @@ #include <errno.h> #include <arpa/inet.h> #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-core-internal.h" -#include "gsystem-local-alloc.h" -#include "nm-glib-compat.h" #include "nm-keyfile-internal.h" #include "nm-keyfile-utils.h" @@ -106,6 +103,24 @@ dns_writer (KeyfileWriterInfo *info, } static void +ip6_addr_gen_mode_writer (KeyfileWriterInfo *info, + NMSetting *setting, + const char *key, + const GValue *value) +{ + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + gs_free char *str = NULL; + + addr_gen_mode = (NMSettingIP6ConfigAddrGenMode) g_value_get_int (value); + str = nm_utils_enum_to_str (nm_setting_ip6_config_addr_gen_mode_get_type (), + addr_gen_mode); + nm_keyfile_plugin_kf_set_string (info->keyfile, + nm_setting_get_name (setting), + key, + str); +} + +static void write_ip_values (GKeyFile *file, const char *setting_name, GPtrArray *array, @@ -560,6 +575,9 @@ static KeyWriter key_writers[] = { { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS, dns_writer }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + ip6_addr_gen_mode_writer }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, ssid_writer }, @@ -590,8 +608,16 @@ static KeyWriter key_writers[] = { static gboolean can_omit_default_value (NMSetting *setting, const char *property) { - if (NM_IS_SETTING_VLAN (setting) && !strcmp (property, NM_SETTING_VLAN_FLAGS)) - return FALSE; + if (NM_IS_SETTING_VLAN (setting)) { + if (!strcmp (property, NM_SETTING_VLAN_FLAGS)) + return FALSE; + } else if (NM_IS_SETTING_IP6_CONFIG (setting)) { + if (!strcmp (property, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE)) + return FALSE; + } else if (NM_IS_SETTING_WIRELESS (setting)) { + if (!strcmp (property, NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION)) + return FALSE; + } return TRUE; } diff --git a/libnm-core/nm-property-compare.c b/libnm-core/nm-property-compare.c index 5d270706..d244f745 100644 --- a/libnm-core/nm-property-compare.c +++ b/libnm-core/nm-property-compare.c @@ -22,13 +22,12 @@ #include "config.h" -#include "nm-property-compare.h" -#include "nm-glib-compat.h" - #include <string.h> #include <math.h> #include <netinet/in.h> -#include <gio/gio.h> + +#include "nm-property-compare.h" +#include "nm-default.h" static gint _nm_property_compare_collection (GVariant *value1, GVariant *value2) diff --git a/libnm-core/nm-property-compare.h b/libnm-core/nm-property-compare.h index 33016787..3f105818 100644 --- a/libnm-core/nm-property-compare.h +++ b/libnm-core/nm-property-compare.h @@ -23,7 +23,7 @@ #ifndef __NM_PROPERTY_COMPARE_H__ #define __NM_PROPERTY_COMPARE_H__ -#include <glib.h> +#include "nm-default.h" int nm_property_compare (GVariant *value1, GVariant *value2); diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index d53ae43b..cd0d4e66 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -23,8 +23,8 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> +#include "nm-default.h" #include "nm-setting-8021x.h" #include "nm-utils.h" #include "crypto.h" @@ -32,7 +32,6 @@ #include "nm-setting-private.h" #include "nm-core-enum-types.h" #include "nm-macros-internal.h" -#include "gsystem-local-alloc.h" /** * SECTION:nm-setting-8021x @@ -429,6 +428,8 @@ get_cert_scheme (GBytes *bytes, GError **error) * * Returns: the scheme of the blob or %NM_SETTING_802_1X_CK_SCHEME_UNKNOWN. * For NULL it also returns NM_SETTING_802_1X_CK_SCHEME_UNKNOWN. + * + * Since: 1.2 **/ NMSetting8021xCKScheme nm_setting_802_1x_check_cert_scheme (gconstpointer pdata, gsize length, GError **error) diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h index 3099fbd1..da86071a 100644 --- a/libnm-core/nm-setting-8021x.h +++ b/libnm-core/nm-setting-8021x.h @@ -149,6 +149,9 @@ GType nm_setting_802_1x_get_type (void); NMSetting *nm_setting_802_1x_new (void); +NM_AVAILABLE_IN_1_2 +NMSetting8021xCKScheme nm_setting_802_1x_check_cert_scheme (gconstpointer pdata, gsize length, GError **error); + guint32 nm_setting_802_1x_get_num_eap_methods (NMSetting8021x *setting); const char * nm_setting_802_1x_get_eap_method (NMSetting8021x *setting, guint32 i); gboolean nm_setting_802_1x_add_eap_method (NMSetting8021x *setting, const char *eap); diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c index 7d78f060..0cf386d8 100644 --- a/libnm-core/nm-setting-adsl.c +++ b/libnm-core/nm-setting-adsl.c @@ -22,7 +22,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-adsl.h" #include "nm-setting-ppp.h" @@ -227,6 +226,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return TRUE; } +static gboolean +verify_secrets (NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string (NM_SETTING_ADSL_GET_PRIVATE (setting)->password, + NM_SETTING_ADSL_SETTING_NAME, + NM_SETTING_ADSL_PASSWORD, + error); +} + static GPtrArray * need_secrets (NMSetting *setting) { @@ -350,6 +358,7 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) object_class->get_property = get_property; object_class->finalize = finalize; parent_class->verify = verify; + parent_class->verify_secrets = verify_secrets; parent_class->need_secrets = need_secrets; /* Properties */ diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 41a0b4c2..864a91cc 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -24,7 +24,6 @@ #include <string.h> #include <net/ethernet.h> -#include <glib/gi18n-lib.h> #include "nm-setting-bluetooth.h" #include "nm-setting-cdma.h" diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 5441a090..1c377584 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -26,7 +26,6 @@ #include <errno.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <glib/gi18n-lib.h> #include "nm-setting-bond.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index 763af37b..a02b8de1 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -24,7 +24,6 @@ #include <string.h> #include <ctype.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-bridge-port.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index d00271b7..7915e730 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -24,7 +24,6 @@ #include <string.h> #include <ctype.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-bridge.h" #include "nm-connection-private.h" @@ -53,6 +52,7 @@ typedef struct { guint16 hello_time; guint16 max_age; guint32 ageing_time; + gboolean multicast_snooping; } NMSettingBridgePrivate; enum { @@ -64,6 +64,7 @@ enum { PROP_HELLO_TIME, PROP_MAX_AGE, PROP_AGEING_TIME, + PROP_MULTICAST_SNOOPING, LAST_PROP }; @@ -178,6 +179,22 @@ nm_setting_bridge_get_ageing_time (NMSettingBridge *setting) return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->ageing_time; } +/** + * nm_setting_bridge_get_multicast_snooping: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-snooping property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_bridge_get_multicast_snooping (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_snooping; +} + /* IEEE 802.1D-1998 timer values */ #define BR_MIN_HELLO_TIME 1 #define BR_MAX_HELLO_TIME 10 @@ -309,6 +326,9 @@ set_property (GObject *object, guint prop_id, case PROP_AGEING_TIME: priv->ageing_time = g_value_get_uint (value); break; + case PROP_MULTICAST_SNOOPING: + priv->multicast_snooping = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -344,6 +364,9 @@ get_property (GObject *object, guint prop_id, case PROP_AGEING_TIME: g_value_set_uint (value, priv->ageing_time); break; + case PROP_MULTICAST_SNOOPING: + g_value_set_boolean (value, priv->multicast_snooping); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -533,6 +556,33 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingBridge:multicast-snooping: + * + * Controls whether IGMP snooping is enabled for this bridge. + * Note that if snooping was automatically disabled due to hash collisions, + * the system may refuse to enable the feature until the collisions are + * resolved. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: multicast-snooping + * variable: BRIDGING_OPTS: multicast_snooping= + * values: 0 or 1 + * default: 1 + * description: IGMP snooping support. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MULTICAST_SNOOPING, + g_param_spec_boolean (NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + /* ---dbus--- * property: interface-name * format: string diff --git a/libnm-core/nm-setting-bridge.h b/libnm-core/nm-setting-bridge.h index b4fe7477..020d6db6 100644 --- a/libnm-core/nm-setting-bridge.h +++ b/libnm-core/nm-setting-bridge.h @@ -16,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2011 - 2015 Red Hat, Inc. */ #ifndef __NM_SETTING_BRIDGE_H__ @@ -46,6 +46,7 @@ G_BEGIN_DECLS #define NM_SETTING_BRIDGE_HELLO_TIME "hello-time" #define NM_SETTING_BRIDGE_MAX_AGE "max-age" #define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time" +#define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping" struct _NMSettingBridge { NMSetting parent; @@ -76,6 +77,8 @@ guint16 nm_setting_bridge_get_max_age (NMSettingBridge *setting); guint32 nm_setting_bridge_get_ageing_time (NMSettingBridge *setting); +gboolean nm_setting_bridge_get_multicast_snooping (NMSettingBridge *setting); + G_END_DECLS #endif /* __NM_SETTING_BRIDGE_H__ */ diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c index 6fd2ad8b..3c01b43f 100644 --- a/libnm-core/nm-setting-cdma.c +++ b/libnm-core/nm-setting-cdma.c @@ -22,7 +22,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-cdma.h" #include "nm-utils.h" @@ -163,6 +162,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return TRUE; } +static gboolean +verify_secrets (NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string (NM_SETTING_CDMA_GET_PRIVATE (setting)->password, + NM_SETTING_CDMA_SETTING_NAME, + NM_SETTING_CDMA_PASSWORD, + error); +} + static GPtrArray * need_secrets (NMSetting *setting) { @@ -265,6 +273,7 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) object_class->get_property = get_property; object_class->finalize = finalize; parent_class->verify = verify; + parent_class->verify_secrets = verify_secrets; parent_class->need_secrets = need_secrets; /* Properties */ diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 28e590df..f341a398 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -23,7 +23,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-utils.h" #include "nm-utils-private.h" @@ -34,6 +33,7 @@ #include "nm-setting-bridge.h" #include "nm-setting-team.h" #include "nm-setting-vlan.h" +#include "nm-macros-internal.h" /** * SECTION:nm-setting-connection @@ -77,6 +77,7 @@ typedef struct { GSList *secondaries; /* secondary connections to activate with the base connection */ guint gateway_ping_timeout; NMMetered metered; + NMSettingConnectionLldp lldp; } NMSettingConnectionPrivate; enum { @@ -97,6 +98,7 @@ enum { PROP_SECONDARIES, PROP_GATEWAY_PING_TIMEOUT, PROP_METERED, + PROP_LLDP, LAST_PROP }; @@ -616,7 +618,7 @@ nm_setting_connection_is_slave_type (NMSettingConnection *setting, * Returns: whether slaves of the connection should be activated together * with the connection. * - * Since: 1.0.4 + * Since: 1.2 **/ NMSettingConnectionAutoconnectSlaves nm_setting_connection_get_autoconnect_slaves (NMSettingConnection *setting) @@ -625,6 +627,9 @@ nm_setting_connection_get_autoconnect_slaves (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_slaves; } +NM_BACKPORT_SYMBOL (libnm_1_0_4, NMSettingConnectionAutoconnectSlaves, nm_setting_connection_get_autoconnect_slaves, (NMSettingConnection *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_4, GType, nm_setting_connection_autoconnect_slaves_get_type, (void), ()); /** * nm_setting_connection_get_num_secondaries: @@ -768,7 +773,7 @@ nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting) * * Returns: the #NMSettingConnection:metered property of the setting. * - * Since: 1.0.6 + * Since: 1.2 **/ NMMetered nm_setting_connection_get_metered (NMSettingConnection *setting) @@ -779,6 +784,29 @@ nm_setting_connection_get_metered (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->metered; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_setting_connection_get_metered, (NMSettingConnection *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, GType, nm_metered_get_type, (void), ()); + +/** + * nm_setting_connection_get_lldp: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:lldp property of the connection. + * + * Returns: a %NMSettingConnectionLldp which indicates whether LLDP must be + * enabled for the connection. + * + * Since: 1.2 + **/ +NMSettingConnectionLldp +nm_setting_connection_get_lldp (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NM_SETTING_CONNECTION_LLDP_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->lldp; +} + static void _set_error_missing_base_setting (GError **error, const char *type) { @@ -1188,6 +1216,9 @@ set_property (GObject *object, guint prop_id, case PROP_METERED: priv->metered = g_value_get_enum (value); break; + case PROP_LLDP: + priv->lldp = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1264,6 +1295,9 @@ get_property (GObject *object, guint prop_id, case PROP_METERED: g_value_set_enum (value, priv->metered); break; + case PROP_LLDP: + g_value_set_int (value, priv->lldp); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1525,6 +1559,9 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * (for example "Home", "Work", "Public"). %NULL or unspecified zone means * the connection will be placed in the default zone as defined by the * firewall. + * + * When updating this property on a currently activated connection, + * the change takes effect immediately. **/ /* ---ifcfg-rh--- * property: zone @@ -1541,6 +1578,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE | + NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | G_PARAM_STATIC_STRINGS)); /** @@ -1599,7 +1637,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * If -1 (default) is set, global connection.autoconnect-slaves is read to * determine the real value. If it is default as well, this fallbacks to 0. * - * Since: 1.0.4 + * Since: 1.2 **/ /* ---ifcfg-rh--- * property: autoconnect-slaves @@ -1669,7 +1707,10 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * * Whether the connection is metered. * - * Since: 1.0.6 + * When updating this property on a currently activated connection, + * the change takes effect immediately. + * + * Since: 1.2 **/ /* ---ifcfg-rh--- * property: metered @@ -1685,5 +1726,31 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NM_TYPE_METERED, NM_METERED_UNKNOWN, G_PARAM_READWRITE | + NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:lldp: + * + * Whether LLDP is enabled for the connection. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: lldp + * variable: LLDP + * values: boolean value or 'rx' + * default: missing variable means global default + * description: whether LLDP is enabled for the connection + * example: LLDP=no + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_LLDP, + g_param_spec_int (NM_SETTING_CONNECTION_LLDP, "", "", + G_MININT32, G_MAXINT32, NM_SETTING_CONNECTION_LLDP_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-core/nm-setting-connection.h b/libnm-core/nm-setting-connection.h index 24b5f6ac..0d4966f0 100644 --- a/libnm-core/nm-setting-connection.h +++ b/libnm-core/nm-setting-connection.h @@ -60,6 +60,7 @@ G_BEGIN_DECLS #define NM_SETTING_CONNECTION_SECONDARIES "secondaries" #define NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT "gateway-ping-timeout" #define NM_SETTING_CONNECTION_METERED "metered" +#define NM_SETTING_CONNECTION_LLDP "lldp" /* Types for property values */ /** @@ -73,13 +74,25 @@ G_BEGIN_DECLS * #NMSettingConnectionAutoconnectSlaves values indicate whether slave connections * should be activated when master is activated. */ -NM_AVAILABLE_IN_1_0_4 typedef enum { NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT = -1, NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO = 0, NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES = 1, } NMSettingConnectionAutoconnectSlaves; +/** + * NMSettingConnectionLldp: + * @NM_SETTING_CONNECTION_LLDP_DEFAULT: default value + * @NM_SETTING_CONNECTION_LLDP_DISABLE: disable LLDP + * @NM_SETTING_CONNECTION_LLDP_ENABLE_RX: enable reception of LLDP frames + * + * #NMSettingConnectionLldp values indicate whether LLDP should be enabled. + */ +typedef enum { + NM_SETTING_CONNECTION_LLDP_DEFAULT = -1, + NM_SETTING_CONNECTION_LLDP_DISABLE = 0, + NM_SETTING_CONNECTION_LLDP_ENABLE_RX = 1, +} NMSettingConnectionLldp; /** * NMSettingConnection: @@ -133,7 +146,7 @@ const char *nm_setting_connection_get_master (NMSettingConnection *set gboolean nm_setting_connection_is_slave_type (NMSettingConnection *setting, const char *type); const char *nm_setting_connection_get_slave_type (NMSettingConnection *setting); -NM_AVAILABLE_IN_1_0_4 +NM_AVAILABLE_IN_1_2 NMSettingConnectionAutoconnectSlaves nm_setting_connection_get_autoconnect_slaves (NMSettingConnection *setting); guint32 nm_setting_connection_get_num_secondaries (NMSettingConnection *setting); @@ -143,8 +156,10 @@ void nm_setting_connection_remove_secondary (NMSettingConnection *set gboolean nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting, const char *sec_uuid); guint32 nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 NMMetered nm_setting_connection_get_metered (NMSettingConnection *setting); +NM_AVAILABLE_IN_1_2 +NMSettingConnectionLldp nm_setting_connection_get_lldp (NMSettingConnection *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index 915cc41f..89675810 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -22,7 +22,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-dcb.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c index 36557a25..4bb5ba9f 100644 --- a/libnm-core/nm-setting-gsm.c +++ b/libnm-core/nm-setting-gsm.c @@ -23,7 +23,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-gsm.h" #include "nm-utils.h" @@ -51,6 +50,11 @@ typedef struct { char *password; NMSettingSecretFlags password_flags; + /* Restrict connection to certain devices or SIMs */ + char *device_id; + char *sim_id; + char *sim_operator_id; + char *apn; /* NULL for dynamic */ char *network_id; /* for manual registration or NULL for automatic */ @@ -71,6 +75,9 @@ enum { PROP_PIN, PROP_PIN_FLAGS, PROP_HOME_ONLY, + PROP_DEVICE_ID, + PROP_SIM_ID, + PROP_SIM_OPERATOR_ID, LAST_PROP }; @@ -214,6 +221,54 @@ nm_setting_gsm_get_home_only (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->home_only; } +/** + * nm_setting_gsm_get_device_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:device-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_device_id (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->device_id; +} + +/** + * nm_setting_gsm_get_sim_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:sim-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_sim_id (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->sim_id; +} + +/** + * nm_setting_gsm_get_sim_operator_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:sim-operator-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_sim_operator_id (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->sim_operator_id; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -313,9 +368,61 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } + if (priv->device_id && !priv->device_id[0]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_DEVICE_ID); + return FALSE; + } + + if (priv->sim_id && !priv->sim_id[0]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_ID); + return FALSE; + } + + if (priv->sim_operator_id) { + size_t len = strlen (priv->sim_operator_id); + const char *p = priv->sim_operator_id; + + if (len == 0 || (len != 5 && len != 6)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty or wrong size")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_OPERATOR_ID); + return FALSE; + } + + while (p && *p) { + if (!g_ascii_isdigit (*p++)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property must contain only digits")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_OPERATOR_ID); + return FALSE; + } + } + } + return TRUE; } +static gboolean +verify_secrets (NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string (NM_SETTING_GSM_GET_PRIVATE (setting)->password, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD, + error); +} + static GPtrArray * need_secrets (NMSetting *setting) { @@ -351,6 +458,9 @@ finalize (GObject *object) g_free (priv->apn); g_free (priv->network_id); g_free (priv->pin); + g_free (priv->device_id); + g_free (priv->sim_id); + g_free (priv->sim_operator_id); G_OBJECT_CLASS (nm_setting_gsm_parent_class)->finalize (object); } @@ -402,6 +512,18 @@ set_property (GObject *object, guint prop_id, case PROP_HOME_ONLY: priv->home_only = g_value_get_boolean (value); break; + case PROP_DEVICE_ID: + g_free (priv->device_id); + priv->device_id = g_value_dup_string (value); + break; + case PROP_SIM_ID: + g_free (priv->sim_id); + priv->sim_id = g_value_dup_string (value); + break; + case PROP_SIM_OPERATOR_ID: + g_free (priv->sim_operator_id); + priv->sim_operator_id = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -442,6 +564,15 @@ get_property (GObject *object, guint prop_id, case PROP_HOME_ONLY: g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting)); break; + case PROP_DEVICE_ID: + g_value_set_string (value, nm_setting_gsm_get_device_id (setting)); + break; + case PROP_SIM_ID: + g_value_set_string (value, nm_setting_gsm_get_sim_id (setting)); + break; + case PROP_SIM_OPERATOR_ID: + g_value_set_string (value, nm_setting_gsm_get_sim_operator_id (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -461,6 +592,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) object_class->get_property = get_property; object_class->finalize = finalize; parent_class->verify = verify; + parent_class->verify_secrets = verify_secrets; parent_class->need_secrets = need_secrets; /* Properties */ @@ -597,6 +729,57 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingGsm:device-id: + * + * The device unique identifier (as given by the WWAN management service) + * which this connection applies to. If given, the connection will only + * apply to the specified device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_DEVICE_ID, + g_param_spec_string (NM_SETTING_GSM_DEVICE_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:sim-id: + * + * The SIM card unique identifier (as given by the WWAN management service) + * which this connection applies to. If given, the connection will apply + * to any device also allowed by #NMSettingGsm:device-id which contains a + * SIM card matching the given identifier. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_SIM_ID, + g_param_spec_string (NM_SETTING_GSM_SIM_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:sim-operator-id: + * + * A MCC/MNC string like "310260" or "21601" identifying the specific + * mobile network operator which this connection applies to. If given, + * the connection will apply to any device also allowed by + * #NMSettingGsm:device-id and #NMSettingGsm:sim-id which contains a SIM + * card provisioined by the given operator. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_SIM_OPERATOR_ID, + g_param_spec_string (NM_SETTING_GSM_SIM_OPERATOR_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* Ignore incoming deprecated properties */ _nm_setting_class_add_dbus_only_property (parent_class, "allowed-bands", G_VARIANT_TYPE_UINT32, diff --git a/libnm-core/nm-setting-gsm.h b/libnm-core/nm-setting-gsm.h index 90756738..2dfe73fa 100644 --- a/libnm-core/nm-setting-gsm.h +++ b/libnm-core/nm-setting-gsm.h @@ -40,15 +40,18 @@ G_BEGIN_DECLS #define NM_SETTING_GSM_SETTING_NAME "gsm" -#define NM_SETTING_GSM_NUMBER "number" -#define NM_SETTING_GSM_USERNAME "username" -#define NM_SETTING_GSM_PASSWORD "password" -#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" -#define NM_SETTING_GSM_APN "apn" -#define NM_SETTING_GSM_NETWORK_ID "network-id" -#define NM_SETTING_GSM_PIN "pin" -#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" -#define NM_SETTING_GSM_HOME_ONLY "home-only" +#define NM_SETTING_GSM_NUMBER "number" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" +#define NM_SETTING_GSM_DEVICE_ID "device-id" +#define NM_SETTING_GSM_SIM_ID "sim-id" +#define NM_SETTING_GSM_SIM_OPERATOR_ID "sim-operator-id" struct _NMSettingGsm { NMSetting parent; @@ -63,14 +66,21 @@ typedef struct { GType nm_setting_gsm_get_type (void); -NMSetting *nm_setting_gsm_new (void); -const char *nm_setting_gsm_get_number (NMSettingGsm *setting); -const char *nm_setting_gsm_get_username (NMSettingGsm *setting); -const char *nm_setting_gsm_get_password (NMSettingGsm *setting); -const char *nm_setting_gsm_get_apn (NMSettingGsm *setting); -const char *nm_setting_gsm_get_network_id (NMSettingGsm *setting); -const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); -gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); +NMSetting *nm_setting_gsm_new (void); +const char *nm_setting_gsm_get_number (NMSettingGsm *setting); +const char *nm_setting_gsm_get_username (NMSettingGsm *setting); +const char *nm_setting_gsm_get_password (NMSettingGsm *setting); +const char *nm_setting_gsm_get_apn (NMSettingGsm *setting); +const char *nm_setting_gsm_get_network_id (NMSettingGsm *setting); +const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); +gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_device_id (NMSettingGsm *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_sim_id (NMSettingGsm *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_sim_operator_id (NMSettingGsm *setting); NMSettingSecretFlags nm_setting_gsm_get_pin_flags (NMSettingGsm *setting); NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting); diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index b0afe04f..1cffdd79 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -22,7 +22,6 @@ #include "config.h" #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-infiniband.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 3a67ca32..7e719aae 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -24,13 +24,12 @@ #include <string.h> #include <arpa/inet.h> -#include <glib/gi18n-lib.h> +#include "nm-default.h" #include "nm-setting-ip-config.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-utils.h" -#include "nm-glib-compat.h" #include "nm-setting-private.h" #include "nm-utils-private.h" @@ -46,6 +45,24 @@ * related to IP addressing, routing, and Domain Name Service. **/ +const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[] = { + { NM_SETTING_DNS_OPTION_DEBUG, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_NDOTS, TRUE, FALSE }, + { NM_SETTING_DNS_OPTION_TIMEOUT, TRUE, FALSE }, + { NM_SETTING_DNS_OPTION_ATTEMPTS, TRUE, FALSE }, + { NM_SETTING_DNS_OPTION_ROTATE, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_NO_CHECK_NAMES, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_INET6, FALSE, TRUE }, + { NM_SETTING_DNS_OPTION_IP6_BYTESTRING, FALSE, TRUE }, + { NM_SETTING_DNS_OPTION_IP6_DOTINT, FALSE, TRUE }, + { NM_SETTING_DNS_OPTION_NO_IP6_DOTINT, FALSE, TRUE }, + { NM_SETTING_DNS_OPTION_EDNS0, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_SINGLE_REQUEST, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_SINGLE_REQUEST_REOPEN, FALSE, FALSE }, + { NM_SETTING_DNS_OPTION_NO_TLD_QUERY, FALSE, FALSE }, + { NULL, FALSE, FALSE } +}; + static char * canonicalize_ip (int family, const char *ip, gboolean null_any) { @@ -79,7 +96,7 @@ valid_ip (int family, const char *ip, GError **error) } if (!nm_utils_ipaddr_valid (family, ip)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - family == AF_INET ? _("Invalid IPv4 address '%s'") : _("Invalid IPv6 address '%s"), + family == AF_INET ? _("Invalid IPv4 address '%s'") : _("Invalid IPv6 address '%s'"), ip); return FALSE; } else @@ -93,7 +110,7 @@ valid_prefix (int family, guint prefix, GError **error, gboolean allow_zero_pref || (family == AF_INET6 && prefix > 128) || (!allow_zero_prefix && prefix == 0)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - family == AF_INET ? _("Invalid IPv4 address prefix '%u'") : _("Invalid IPv6 address prefix '%u"), + family == AF_INET ? _("Invalid IPv4 address prefix '%u'") : _("Invalid IPv6 address prefix '%u'"), prefix); return FALSE; } @@ -1065,6 +1082,7 @@ typedef struct { char *method; GPtrArray *dns; /* array of IP address strings */ GPtrArray *dns_search; /* array of domain name strings */ + GPtrArray *dns_options;/* array of DNS options */ GPtrArray *addresses; /* array of NMIPAddress */ GPtrArray *routes; /* array of NMIPRoute */ gint64 route_metric; @@ -1082,6 +1100,7 @@ enum { PROP_METHOD, PROP_DNS, PROP_DNS_SEARCH, + PROP_DNS_OPTIONS, PROP_ADDRESSES, PROP_GATEWAY, PROP_ROUTES, @@ -1131,21 +1150,21 @@ nm_setting_ip_config_get_num_dns (NMSettingIPConfig *setting) /** * nm_setting_ip_config_get_dns: * @setting: the #NMSettingIPConfig - * @i: index number of the DNS server to return + * @idx: index number of the DNS server to return * - * Returns: the IP address of the DNS server at index @i + * Returns: the IP address of the DNS server at index @idx **/ const char * -nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (i < priv->dns->len, NULL); + g_return_val_if_fail (idx < priv->dns->len, NULL); - return priv->dns->pdata[i]; + return priv->dns->pdata[idx]; } /** @@ -1187,21 +1206,21 @@ nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, const char *dns) /** * nm_setting_ip_config_remove_dns: * @setting: the #NMSettingIPConfig - * @i: index number of the DNS server to remove + * @idx: index number of the DNS server to remove * - * Removes the DNS server at index @i. + * Removes the DNS server at index @idx. **/ void -nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (i < priv->dns->len); + g_return_if_fail (idx < priv->dns->len); - g_ptr_array_remove_index (priv->dns, i); + g_ptr_array_remove_index (priv->dns, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); } @@ -1275,21 +1294,21 @@ nm_setting_ip_config_get_num_dns_searches (NMSettingIPConfig *setting) /** * nm_setting_ip_config_get_dns_search: * @setting: the #NMSettingIPConfig - * @i: index number of the DNS search domain to return + * @idx: index number of the DNS search domain to return * - * Returns: the DNS search domain at index @i + * Returns: the DNS search domain at index @idx **/ const char * -nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (i < priv->dns_search->len, NULL); + g_return_val_if_fail (idx < priv->dns_search->len, NULL); - return priv->dns_search->pdata[i]; + return priv->dns_search->pdata[idx]; } /** @@ -1327,21 +1346,21 @@ nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting, /** * nm_setting_ip_config_remove_dns_search: * @setting: the #NMSettingIPConfig - * @i: index number of the DNS search domain + * @idx: index number of the DNS search domain * - * Removes the DNS search domain at index @i. + * Removes the DNS search domain at index @idx. **/ void -nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (i < priv->dns_search->len); + g_return_if_fail (idx < priv->dns_search->len); - g_ptr_array_remove_index (priv->dns_search, i); + g_ptr_array_remove_index (priv->dns_search, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); } @@ -1397,6 +1416,233 @@ nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting) } /** + * nm_setting_ip_config_get_num_dns_options: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS options + * + * Since: 1.2 + **/ +guint +nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + return priv->dns_options ? priv->dns_options->len : 0; +} + +/** + * nm_setting_ip_config_has_dns_options: + * @setting: the #NMSettingIPConfig + * + * NMSettingIPConfig can have a list of dns-options. If the list + * is empty, there are two similar (but differentiated) states. + * Either the options are explicitly set to have no values, + * or the options are left undefined. The latter means to use + * a default configuration, while the former explicitly means "no-options". + * + * Returns: whether DNS options are initalized or left unset (the default). + **/ +gboolean +nm_setting_ip_config_has_dns_options (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return !!NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_options; +} + +/** + * nm_setting_ip_config_get_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS option + * + * Returns: the DNS option at index @idx + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (priv->dns_options, NULL); + g_return_val_if_fail (idx < priv->dns_options->len, NULL); + + return priv->dns_options->pdata[idx]; +} + +/** + * nm_setting_ip_config_next_valid_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index to start the search from + * + * Returns: the index, greater or equal than @idx, of the first valid + * DNS option, or -1 if no valid option is found + * + * Since: 1.2 + **/ +gint +nm_setting_ip_config_next_valid_dns_option (NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), -1); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + if (!priv->dns_options) + return -1; + + for (; idx < priv->dns_options->len; idx++) { + if (_nm_utils_dns_option_validate (priv->dns_options->pdata[idx], NULL, NULL, + NM_IS_SETTING_IP6_CONFIG (setting), + _nm_utils_dns_option_descs)) + return idx; + } + + return -1; +} + +/** + * nm_setting_ip_config_add_dns_option: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to add + * + * Adds a new DNS option to the setting. + * + * Returns: %TRUE if the DNS option was added; %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting, + const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_option != NULL, FALSE); + g_return_val_if_fail (dns_option[0] != '\0', FALSE); + + if (!_nm_utils_dns_option_validate (dns_option, NULL, NULL, FALSE, NULL)) + return FALSE; + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + if (!priv->dns_options) + priv->dns_options = g_ptr_array_new_with_free_func (g_free); + else { + if (_nm_utils_dns_option_find_idx (priv->dns_options, dns_option) >= 0) + return FALSE; + } + + g_ptr_array_add (priv->dns_options, g_strdup (dns_option)); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS option + * + * Removes the DNS option at index @idx. + * + * Since: 1.2 + **/ +void +nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (priv->dns_options); + g_return_if_fail (idx < priv->dns_options->len); + + g_ptr_array_remove_index (priv->dns_options, idx); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); +} + +/** + * nm_setting_ip_config_remove_dns_option_by_value: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to remove + * + * Removes the DNS option @dns_option. + * + * Returns: %TRUE if the DNS option was found and removed; %FALSE if it was not. + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting, + const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_option != NULL, FALSE); + g_return_val_if_fail (dns_option[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + if (!priv->dns_options) + return FALSE; + + i = _nm_utils_dns_option_find_idx (priv->dns_options, dns_option); + if (i >= 0) { + g_ptr_array_remove_index (priv->dns_options, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns_options: + * @setting: the #NMSettingIPConfig + * @is_set: the dns-options can be either empty or unset (default). + * Specify how to clear the options. + * + * Removes all configured DNS options. + * + * Since: 1.2 + **/ +void +nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_set) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + if (!priv->dns_options) { + if (!is_set) + return; + priv->dns_options = g_ptr_array_new_with_free_func (g_free); + } else { + if (!is_set) { + g_ptr_array_unref (priv->dns_options); + priv->dns_options = NULL; + } else { + if (priv->dns_options->len == 0) + return; + g_ptr_array_set_size (priv->dns_options, 0); + } + } + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); +} + +/** * nm_setting_ip_config_get_num_addresses: * @setting: the #NMSettingIPConfig * @@ -1413,21 +1659,21 @@ nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting) /** * nm_setting_ip_config_get_address: * @setting: the #NMSettingIPConfig - * @i: index number of the address to return + * @idx: index number of the address to return * - * Returns: (transfer none): the address at index @i + * Returns: (transfer none): the address at index @idx **/ NMIPAddress * -nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (i < priv->addresses->len, NULL); + g_return_val_if_fail (idx < priv->addresses->len, NULL); - return priv->addresses->pdata[i]; + return priv->addresses->pdata[idx]; } /** @@ -1467,21 +1713,21 @@ nm_setting_ip_config_add_address (NMSettingIPConfig *setting, /** * nm_setting_ip_config_remove_address: * @setting: the #NMSettingIPConfig - * @i: index number of the address to remove + * @idx: index number of the address to remove * - * Removes the address at index @i. + * Removes the address at index @idx. **/ void -nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (i < priv->addresses->len); + g_return_if_fail (idx < priv->addresses->len); - g_ptr_array_remove_index (priv->addresses, i); + g_ptr_array_remove_index (priv->addresses, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES); } @@ -1565,21 +1811,21 @@ nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting) /** * nm_setting_ip_config_get_route: * @setting: the #NMSettingIPConfig - * @i: index number of the route to return + * @idx: index number of the route to return * - * Returns: (transfer none): the route at index @i + * Returns: (transfer none): the route at index @idx **/ NMIPRoute * -nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (i < priv->routes->len, NULL); + g_return_val_if_fail (idx < priv->routes->len, NULL); - return priv->routes->pdata[i]; + return priv->routes->pdata[idx]; } /** @@ -1617,21 +1863,21 @@ nm_setting_ip_config_add_route (NMSettingIPConfig *setting, /** * nm_setting_ip_config_remove_route: * @setting: the #NMSettingIPConfig - * @i: index number of the route + * @idx: index number of the route * - * Removes the route at index @i. + * Removes the route at index @idx. **/ void -nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int i) +nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int idx) { NMSettingIPConfigPrivate *priv; g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (i < priv->routes->len); + g_return_if_fail (idx < priv->routes->len); - g_ptr_array_remove_index (priv->routes, i); + g_ptr_array_remove_index (priv->routes, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); } @@ -1962,6 +2208,7 @@ nm_setting_ip_config_init (NMSettingIPConfig *setting) priv->dns = g_ptr_array_new_with_free_func (g_free); priv->dns_search = g_ptr_array_new_with_free_func (g_free); + priv->dns_options = NULL; priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); } @@ -1978,6 +2225,8 @@ finalize (GObject *object) g_ptr_array_unref (priv->dns); g_ptr_array_unref (priv->dns_search); + if (priv->dns_options) + g_ptr_array_unref (priv->dns_options); g_ptr_array_unref (priv->addresses); g_ptr_array_unref (priv->routes); @@ -1991,6 +2240,8 @@ set_property (GObject *object, guint prop_id, NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object); NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); const char *gateway; + char **strv; + int i; switch (prop_id) { case PROP_METHOD: @@ -2005,6 +2256,25 @@ set_property (GObject *object, guint prop_id, g_ptr_array_unref (priv->dns_search); priv->dns_search = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); break; + case PROP_DNS_OPTIONS: + strv = g_value_get_boxed (value); + if (!strv) { + if (priv->dns_options) { + g_ptr_array_unref (priv->dns_options); + priv->dns_options = NULL; + } + } else { + if (priv->dns_options) + g_ptr_array_set_size (priv->dns_options, 0); + else + priv->dns_options = g_ptr_array_new_with_free_func (g_free); + for (i = 0; strv[i]; i++) { + if ( _nm_utils_dns_option_validate (strv[i], NULL, NULL, FALSE, NULL) + && _nm_utils_dns_option_find_idx (priv->dns_options, strv[i]) < 0) + g_ptr_array_add (priv->dns_options, g_strdup (strv[i])); + } + } + break; case PROP_ADDRESSES: g_ptr_array_unref (priv->addresses); priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value), @@ -2068,6 +2338,9 @@ get_property (GObject *object, guint prop_id, case PROP_DNS_SEARCH: g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_search)); break; + case PROP_DNS_OPTIONS: + g_value_take_boxed (value, priv->dns_options ? _nm_utils_ptrarray_to_strv (priv->dns_options) : NULL); + break; case PROP_ADDRESSES: g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses, (NMUtilsCopyFunc) nm_ip_address_dup, @@ -2188,6 +2461,24 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) G_PARAM_STATIC_STRINGS)); /** + * NMSettingIPConfig:dns-options: + * + * Array of DNS options. + * + * %NULL means that the options are unset and left at the default. + * In this case NetworkManager will use default options. This is + * distinct from an empty list of properties. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_DNS_OPTIONS, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_OPTIONS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** * NMSettingIPConfig:addresses: * * Array of IP addresses. @@ -2304,6 +2595,8 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) * * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the * specified name will be sent to the DHCP server when acquiring a lease. + * This property and #NMSettingIP4Config:dhcp-fqdn are mutually exclusive and + * cannot be set at the same time. **/ g_object_class_install_property (object_class, PROP_DHCP_HOSTNAME, diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h index 12763fa8..6e8c0202 100644 --- a/libnm-core/nm-setting-ip-config.h +++ b/libnm-core/nm-setting-ip-config.h @@ -133,6 +133,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route, #define NM_SETTING_IP_CONFIG_METHOD "method" #define NM_SETTING_IP_CONFIG_DNS "dns" #define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options" #define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" #define NM_SETTING_IP_CONFIG_GATEWAY "gateway" #define NM_SETTING_IP_CONFIG_ROUTES "routes" @@ -144,6 +145,21 @@ void nm_ip_route_set_attribute (NMIPRoute *route, #define NM_SETTING_IP_CONFIG_NEVER_DEFAULT "never-default" #define NM_SETTING_IP_CONFIG_MAY_FAIL "may-fail" +#define NM_SETTING_DNS_OPTION_DEBUG "debug" +#define NM_SETTING_DNS_OPTION_NDOTS "ndots" +#define NM_SETTING_DNS_OPTION_TIMEOUT "timeout" +#define NM_SETTING_DNS_OPTION_ATTEMPTS "attempts" +#define NM_SETTING_DNS_OPTION_ROTATE "rotate" +#define NM_SETTING_DNS_OPTION_NO_CHECK_NAMES "no-check-names" +#define NM_SETTING_DNS_OPTION_INET6 "inet6" +#define NM_SETTING_DNS_OPTION_IP6_BYTESTRING "ip6-bytestring" +#define NM_SETTING_DNS_OPTION_IP6_DOTINT "ip6-dotint" +#define NM_SETTING_DNS_OPTION_NO_IP6_DOTINT "no-ip6-dotint" +#define NM_SETTING_DNS_OPTION_EDNS0 "edns0" +#define NM_SETTING_DNS_OPTION_SINGLE_REQUEST "single-request" +#define NM_SETTING_DNS_OPTION_SINGLE_REQUEST_REOPEN "single-request-reopen" +#define NM_SETTING_DNS_OPTION_NO_TLD_QUERY "no-tld-query" + struct _NMSettingIPConfig { NMSetting parent; }; @@ -161,33 +177,47 @@ const char *nm_setting_ip_config_get_method (NMSettingIPConfig guint nm_setting_ip_config_get_num_dns (NMSettingIPConfig *setting); const char *nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, const char *dns); void nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_remove_dns_by_value (NMSettingIPConfig *setting, const char *dns); void nm_setting_ip_config_clear_dns (NMSettingIPConfig *setting); guint nm_setting_ip_config_get_num_dns_searches (NMSettingIPConfig *setting); const char *nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting, const char *dns_search); void nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting, const char *dns_search); void nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting); +guint nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_has_dns_options (NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, + guint idx); +gint nm_setting_ip_config_next_valid_dns_option (NMSettingIPConfig *setting, + guint idx); +gboolean nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting, + const char *dns_option); +void nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, + int idx); +gboolean nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting, + const char *dns_option); +void nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_set); + guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting); NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_add_address (NMSettingIPConfig *setting, NMIPAddress *address); void nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig *setting, NMIPAddress *address); void nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting); @@ -196,11 +226,11 @@ const char *nm_setting_ip_config_get_gateway (NMSettingIPConfig guint nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting); NMIPRoute *nm_setting_ip_config_get_route (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_add_route (NMSettingIPConfig *setting, NMIPRoute *route); void nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, - int i); + int idx); gboolean nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, NMIPRoute *route); void nm_setting_ip_config_clear_routes (NMSettingIPConfig *setting); diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c new file mode 100644 index 00000000..cd63aa11 --- /dev/null +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -0,0 +1,767 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "nm-setting-ip-tunnel.h" + +#include "config.h" + +#include "nm-setting-private.h" +#include "nm-macros-internal.h" +#include "nm-utils.h" + +/** + * SECTION:nm-setting-ip-tunnel + * @short_description: Describes connection properties for IP tunnel devices + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING, + _nm_register_setting (IP_TUNNEL, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP_TUNNEL) + +#define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate)) + +typedef struct { + char *parent; + NMIPTunnelMode mode; + char *local; + char *remote; + guint ttl; + guint tos; + gboolean path_mtu_discovery; + char *input_key; + char *output_key; + guint encapsulation_limit; + guint flow_label; + guint mtu; +} NMSettingIPTunnelPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_MODE, + PROP_LOCAL, + PROP_REMOTE, + PROP_TTL, + PROP_TOS, + PROP_PATH_MTU_DISCOVERY, + PROP_INPUT_KEY, + PROP_OUTPUT_KEY, + PROP_ENCAPSULATION_LIMIT, + PROP_FLOW_LABEL, + PROP_MTU, + + LAST_PROP +}; + +/** + * nm_setting_ip_tunnel_get_parent: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:parent property of the setting + * + * Returns: the parent device + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_parent (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL); + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_ip_tunnel_get_mode: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:mode property of the setting. + * + * Returns: the tunnel mode + * + * Since: 1.2 + **/ +NMIPTunnelMode +nm_setting_ip_tunnel_get_mode (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mode; +} + +/** + * nm_setting_ip_tunnel_get_local: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:local property of the setting. + * + * Returns: the local endpoint + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_local (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->local; +} + +/** + * nm_setting_ip_tunnel_get_remote: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:remote property of the setting. + * + * Returns: the remote endpoint + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_remote (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->remote; +} + +/** + * nm_setting_ip_tunnel_get_ttl: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:ttl property of the setting. + * + * Returns: the Time-to-live value + * + * Since: 1.2 + **/ + +guint +nm_setting_ip_tunnel_get_ttl (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->ttl; +} + +/** + * nm_setting_ip_tunnel_get_tos: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:tos property of the setting. + * + * Returns: the TOS value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_tos (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->tos; +} + +/** + * nm_setting_ip_tunnel_get_path_mtu_discovery: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:path-mtu-discovery property of the setting. + * + * Returns: whether path MTU discovery is enabled + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_tunnel_get_path_mtu_discovery (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), TRUE); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->path_mtu_discovery; +} + +/** + * nm_setting_ip_tunnel_get_input_key: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:input-key property of the setting. + * + * Returns: the input key + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_input_key (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->input_key; +} + +/** + * nm_setting_ip_tunnel_get_output_key: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:output-key property of the setting. + * + * Returns: the output key + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_output_key (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->output_key; +} + +/** + * nm_setting_ip_tunnel_get_encapsulation_limit: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:encapsulation-limit property of the setting. + * + * Returns: the encapsulation limit value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_encapsulation_limit (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->encapsulation_limit; +} + +/** + * nm_setting_ip_tunnel_get_flow_label: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:flow-label property of the setting. + * + * Returns: the flow label value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->flow_label; +} + +/** + * nm_setting_ip_tunnel_get_mtu: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:mtu property of the setting. + * + * Returns: the MTU + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mtu; +} + +/*********************************************************************/ + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting); + int family; + + switch (priv->mode) { + case NM_IP_TUNNEL_MODE_IPIP: + case NM_IP_TUNNEL_MODE_SIT: + case NM_IP_TUNNEL_MODE_ISATAP: + case NM_IP_TUNNEL_MODE_GRE: + case NM_IP_TUNNEL_MODE_VTI: + family = AF_INET; + break; + case NM_IP_TUNNEL_MODE_IP6IP6: + case NM_IP_TUNNEL_MODE_IPIP6: + case NM_IP_TUNNEL_MODE_IP6GRE: + case NM_IP_TUNNEL_MODE_VTI6: + family = AF_INET6; + break; + default: + family = AF_UNSPEC; + } + + if (family == AF_UNSPEC) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid tunnel mode"), + (int) priv->mode); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE); + return FALSE; + } + + if ( priv->parent + && !nm_utils_iface_valid_name (priv->parent) + && !nm_utils_is_uuid (priv->parent)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_PARENT); + return FALSE; + } + + if (priv->local && !nm_utils_ipaddr_valid (family, priv->local)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv%c address"), + priv->local, + family == AF_INET ? '4' : '6'); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL); + return FALSE; + } + + if (priv->remote && !nm_utils_ipaddr_valid (family, priv->remote)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv%c address"), + priv->remote, + family == AF_INET ? '4' : '6'); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE); + return FALSE; + } + + if ( (priv->input_key && priv->input_key[0]) + || (priv->output_key && priv->output_key[0])) { + if ( priv->mode != NM_IP_TUNNEL_MODE_GRE + && priv->mode != NM_IP_TUNNEL_MODE_IP6GRE) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("tunnel keys can only be specified for GRE tunnels")); + return FALSE; + } + } + + if (priv->input_key && priv->input_key[0]) { + gint64 val; + + val = _nm_utils_ascii_str_to_int64 (priv->input_key, 10, 0, G_MAXUINT32, -1); + if (val == -1) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid tunnel key"), + priv->input_key); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_INPUT_KEY); + return FALSE; + } + } + + if (priv->output_key && priv->output_key[0]) { + gint64 val; + + val = _nm_utils_ascii_str_to_int64 (priv->output_key, 10, 0, G_MAXUINT32, -1); + if (val == -1) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid tunnel key"), + priv->output_key); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_OUTPUT_KEY); + return FALSE; + } + } + + if (!priv->path_mtu_discovery && priv->ttl != 0) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a fixed TTL is allowed only when path MTU discovery is enabled")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_TTL); + return FALSE; + } + + return TRUE; +} + +/** + * nm_setting_ip_tunnel_new: + * + * Creates a new #NMSettingIPTunnel object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIPTunnel object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_ip_tunnel_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP_TUNNEL, NULL); +} + +static void +nm_setting_ip_tunnel_init (NMSettingIPTunnel *setting) +{ +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + break; + case PROP_MODE: + priv->mode = g_value_get_uint (value); + break; + case PROP_LOCAL: + g_free (priv->local); + priv->local = g_value_dup_string (value); + break; + case PROP_REMOTE: + g_free (priv->remote); + priv->remote = g_value_dup_string (value); + break; + case PROP_TTL: + priv->ttl = g_value_get_uint (value); + break; + case PROP_TOS: + priv->tos = g_value_get_uint (value); + break; + case PROP_PATH_MTU_DISCOVERY: + priv->path_mtu_discovery = g_value_get_boolean (value); + break; + case PROP_INPUT_KEY: + g_free (priv->input_key); + priv->input_key = g_value_dup_string (value); + break; + case PROP_OUTPUT_KEY: + g_free (priv->output_key); + priv->output_key = g_value_dup_string (value); + break; + case PROP_ENCAPSULATION_LIMIT: + priv->encapsulation_limit = g_value_get_uint (value); + break; + case PROP_FLOW_LABEL: + priv->flow_label = g_value_get_uint (value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string (value, priv->parent); + break; + case PROP_MODE: + g_value_set_uint (value, priv->mode); + break; + case PROP_LOCAL: + g_value_set_string (value, priv->local); + break; + case PROP_REMOTE: + g_value_set_string (value, priv->remote); + break; + case PROP_TTL: + g_value_set_uint (value, priv->ttl); + break; + case PROP_TOS: + g_value_set_uint (value, priv->tos); + break; + case PROP_PATH_MTU_DISCOVERY: + g_value_set_boolean (value, priv->path_mtu_discovery); + break; + case PROP_INPUT_KEY: + g_value_set_string (value, priv->input_key); + break; + case PROP_OUTPUT_KEY: + g_value_set_string (value, priv->output_key); + break; + case PROP_ENCAPSULATION_LIMIT: + g_value_set_uint (value, priv->encapsulation_limit); + break; + case PROP_FLOW_LABEL: + g_value_set_uint (value, priv->flow_label); + break; + case PROP_MTU: + g_value_set_uint (value, priv->mtu); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting); + + g_free (priv->local); + g_free (priv->remote); + g_free (priv->input_key); + g_free (priv->output_key); + + G_OBJECT_CLASS (nm_setting_ip_tunnel_parent_class)->finalize (object); +} + +static void +nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingIPTunnelPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /** + * NMSettingIPTunnel:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * the new device will be bound to so that tunneled packets will only be + * routed via that interface. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_IP_TUNNEL_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:mode: + * + * The tunneling mode, for example %NM_IP_TUNNEL_MODE_IPIP or + * %NM_IP_TUNNEL_MODE_GRE. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_MODE, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:local: + * + * The local endpoint of the tunnel; the value can be empty, otherwise it + * must contain an IPv4 or IPv6 address. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_LOCAL, + g_param_spec_string (NM_SETTING_IP_TUNNEL_LOCAL, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:remote: + * + * The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 + * address. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_REMOTE, + g_param_spec_string (NM_SETTING_IP_TUNNEL_REMOTE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:ttl + * + * The TTL to assign to tunneled packets. 0 is a special value meaning that + * packets inherit the TTL value. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TTL, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_TTL, "", "", + 0, 255, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:tos + * + * The type of service (IPv4) or traffic class (IPv6) field to be set on + * tunneled packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TOS, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_TOS, "", "", + 0, 255, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:path-mtu-discovery + * + * Whether to enable Path MTU Discovery on this tunnel. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PATH_MTU_DISCOVERY, + g_param_spec_boolean (NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:input-key: + * + * The key used for tunnel input packets; the property is valid only for + * certain tunnel modes (GRE, IP6GRE). If empty, no key is used. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_INPUT_KEY, + g_param_spec_string (NM_SETTING_IP_TUNNEL_INPUT_KEY, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:output-key: + * + * The key used for tunnel output packets; the property is valid only for + * certain tunnel modes (GRE, IP6GRE). If empty, no key is used. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_OUTPUT_KEY, + g_param_spec_string (NM_SETTING_IP_TUNNEL_OUTPUT_KEY, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:encapsulation-limit: + * + * How many additional levels of encapsulation are permitted to be prepended + * to packets. This property applies only to IPv6 tunnels. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_ENCAPSULATION_LIMIT, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, "", "", + 0, 255, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunnel:flow-label: + * + * The flow label to assign to tunnel packets. This property applies only to + * IPv6 tunnels. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_FLOW_LABEL, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_FLOW_LABEL, "", "", + 0, (1 << 20) - 1, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunel:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple fragments. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_MTU, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-ip-tunnel.h b/libnm-core/nm-setting-ip-tunnel.h new file mode 100644 index 00000000..09814f35 --- /dev/null +++ b/libnm-core/nm-setting-ip-tunnel.h @@ -0,0 +1,98 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_IP_TUNNEL_H__ +#define __NM_SETTING_IP_TUNNEL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP_TUNNEL (nm_setting_ip_tunnel_get_type ()) +#define NM_SETTING_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnel)) +#define NM_SETTING_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelClass)) +#define NM_IS_SETTING_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP_TUNNEL)) +#define NM_IS_SETTING_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_IP_TUNNEL)) +#define NM_SETTING_IP_TUNNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelClass)) + +#define NM_SETTING_IP_TUNNEL_SETTING_NAME "ip-tunnel" + +#define NM_SETTING_IP_TUNNEL_PARENT "parent" +#define NM_SETTING_IP_TUNNEL_MODE "mode" +#define NM_SETTING_IP_TUNNEL_LOCAL "local" +#define NM_SETTING_IP_TUNNEL_REMOTE "remote" +#define NM_SETTING_IP_TUNNEL_TTL "ttl" +#define NM_SETTING_IP_TUNNEL_TOS "tos" +#define NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY "path-mtu-discovery" +#define NM_SETTING_IP_TUNNEL_INPUT_KEY "input-key" +#define NM_SETTING_IP_TUNNEL_OUTPUT_KEY "output-key" +#define NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit" +#define NM_SETTING_IP_TUNNEL_FLOW_LABEL "flow-label" +#define NM_SETTING_IP_TUNNEL_MTU "mtu" + +struct _NMSettingIPTunnel { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIPTunnelClass; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_ip_tunnel_get_type (void); + +NM_AVAILABLE_IN_1_2 +NMSetting * nm_setting_ip_tunnel_new (void); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_parent (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +NMIPTunnelMode nm_setting_ip_tunnel_get_mode (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_local (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_remote (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_ttl (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_tos (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_ip_tunnel_get_path_mtu_discovery (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_input_key (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_output_key (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_encapsulation_limit (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP_TUNNEL_H__ */ diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 81cc1f88..7708b6c5 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -22,7 +22,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-ip4-config.h" #include "nm-setting-private.h" @@ -59,11 +58,15 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP4_CONFIG) typedef struct { char *dhcp_client_id; + int dhcp_timeout; + char *dhcp_fqdn; } NMSettingIP4ConfigPrivate; enum { PROP_0, PROP_DHCP_CLIENT_ID, + PROP_DHCP_TIMEOUT, + PROP_DHCP_FQDN, LAST_PROP }; @@ -99,6 +102,45 @@ nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting) return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_client_id; } +/** + * nm_setting_ip4_config_get_dhcp_timeout: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp-timeout + * property. + * + * Returns: the configured DHCP timeout in seconds. 0 = default for + * the particular kind of device. + * + * Since: 1.2 + **/ +int +nm_setting_ip4_config_get_dhcp_timeout (NMSettingIP4Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), 0); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_timeout; +} + +/** + * nm_setting_ip4_config_get_dhcp_fqdn: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp-fqdn + * property. + * + * Returns: the configured FQDN to send to the DHCP server + * + * Since: 1.2 + **/ +const char * +nm_setting_ip4_config_get_dhcp_fqdn (NMSettingIP4Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_fqdn; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -180,6 +222,31 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (priv->dhcp_fqdn && !*priv->dhcp_fqdn) { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + + if (priv->dhcp_fqdn && !strchr (priv->dhcp_fqdn, '.')) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid FQDN"), priv->dhcp_fqdn); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + + if (priv->dhcp_fqdn && nm_setting_ip_config_get_dhcp_hostname (s_ip)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be set when dhcp-hostname is also set")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + return TRUE; } @@ -194,6 +261,7 @@ finalize (GObject *object) NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (object); g_free (priv->dhcp_client_id); + g_free (priv->dhcp_fqdn); G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object); } @@ -209,6 +277,13 @@ set_property (GObject *object, guint prop_id, g_free (priv->dhcp_client_id); priv->dhcp_client_id = g_value_dup_string (value); break; + case PROP_DHCP_TIMEOUT: + priv->dhcp_timeout = g_value_get_uint (value); + break; + case PROP_DHCP_FQDN: + g_free (priv->dhcp_fqdn); + priv->dhcp_fqdn = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -225,6 +300,12 @@ get_property (GObject *object, guint prop_id, case PROP_DHCP_CLIENT_ID: g_value_set_string (value, nm_setting_ip4_config_get_dhcp_client_id (s_ip4)); break; + case PROP_DHCP_TIMEOUT: + g_value_set_uint (value, nm_setting_ip4_config_get_dhcp_timeout (s_ip4)); + break; + case PROP_DHCP_FQDN: + g_value_set_string (value, nm_setting_ip4_config_get_dhcp_fqdn (s_ip4)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -549,7 +630,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) /* ---ifcfg-rh--- * property: dhcp-hostname * variable: DHCP_HOSTNAME - * description: Hostname to send to the DHCP server. + * description: Hostname to send to the DHCP server. When both DHCP_HOSTNAME and + * DHCP_FQDN are specified only the latter is used. * ---end--- */ @@ -600,6 +682,51 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingIP4Config:dhcp-timeout: + * + * A timeout for a DHCP transaction in seconds. + **/ + /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: DHCP_TIMEOUT(+) + * description: A timeout after which the DHCP transaction fails in case of no response. + * example: DHCP_TIMEOUT=10 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_DHCP_TIMEOUT, + g_param_spec_uint (NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIP4Config:dhcp-fqdn: + * + * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the + * specified FQDN will be sent to the DHCP server when acquiring a lease. This + * property and #NMSettingIPConfig:dhcp-hostname are mutually exclusive and + * cannot be set at the same time. + * + * Since: 1.2 + */ + /* ---ifcfg-rh--- + * property: dhcp-fqdn + * variable: DHCP_FQDN + * description: FQDN to send to the DHCP server. When both DHCP_HOSTNAME and + * DHCP_FQDN are specified only the latter is used. + * example: DHCP_FQDN=foo.bar.com + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_DHCP_FQDN, + g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_FQDN, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* IP4-specific property overrides */ /* ---dbus--- diff --git a/libnm-core/nm-setting-ip4-config.h b/libnm-core/nm-setting-ip4-config.h index e944dfe3..a78df703 100644 --- a/libnm-core/nm-setting-ip4-config.h +++ b/libnm-core/nm-setting-ip4-config.h @@ -41,6 +41,8 @@ G_BEGIN_DECLS #define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4" #define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id" +#define NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT "dhcp-timeout" +#define NM_SETTING_IP4_CONFIG_DHCP_FQDN "dhcp-fqdn" /** * NM_SETTING_IP4_CONFIG_METHOD_AUTO: @@ -102,6 +104,10 @@ GType nm_setting_ip4_config_get_type (void); NMSetting *nm_setting_ip4_config_new (void); const char *nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting); +NM_AVAILABLE_IN_1_2 +int nm_setting_ip4_config_get_dhcp_timeout (NMSettingIP4Config *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip4_config_get_dhcp_fqdn (NMSettingIP4Config *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 619e002c..bc516d6e 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -22,11 +22,11 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-ip6-config.h" #include "nm-setting-private.h" #include "nm-core-enum-types.h" +#include "nm-macros-internal.h" /** * SECTION:nm-setting-ip6-config @@ -58,12 +58,14 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG) typedef struct { NMSettingIP6ConfigPrivacy ip6_privacy; + NMSettingIP6ConfigAddrGenMode addr_gen_mode; } NMSettingIP6ConfigPrivate; enum { PROP_0, PROP_IP6_PRIVACY, + PROP_ADDR_GEN_MODE, LAST_PROP }; @@ -98,9 +100,30 @@ nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting) return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ip6_privacy; } +/** + * nm_setting_ip6_config_get_addr_gen_mode: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:addr-gen-mode + * property. + * + * Returns: IPv6 Address Generation Mode. + * + * Since: 1.2 + **/ +NMSettingIP6ConfigAddrGenMode +nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting); NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); NMSettingVerifyResult ret; const char *method; @@ -167,6 +190,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (!NM_IN_SET (priv->addr_gen_mode, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + return TRUE; } @@ -331,6 +365,9 @@ set_property (GObject *object, guint prop_id, case PROP_IP6_PRIVACY: priv->ip6_privacy = g_value_get_enum (value); break; + case PROP_ADDR_GEN_MODE: + priv->addr_gen_mode = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -347,6 +384,9 @@ get_property (GObject *object, guint prop_id, case PROP_IP6_PRIVACY: g_value_set_enum (value, priv->ip6_privacy); break; + case PROP_ADDR_GEN_MODE: + g_value_set_int (value, priv->addr_gen_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -512,6 +552,10 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) * * If also global configuration is unspecified or set to "-1", fallback to read * "/proc/sys/net/ipv6/conf/default/use_tempaddr". + * + * Note that this setting is distinct from the Stable Privacy addresses + * that can be enabled with the "addr-gen-mode" property's "stable-privacy" + * setting as another way of avoiding host tracking with IPv6 addresses. **/ /* ---ifcfg-rh--- * property: ip6-privacy @@ -532,6 +576,53 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingIP6Config:addr-gen-mode: + * + * Configure method for creating the address for use with RFC4862 IPv6 + * Stateless Address Autoconfiguration. The permitted values are: "eui64", + * "stable-privacy" or unset. + * + * If the property is set to "eui64", the addresses will be generated + * using the interface tokens derived from hardware address. This makes + * the host part of the address to stay constant, making it possible + * to track host's presence when it changes networks. The address changes + * when the interface hardware is replaced. + * + * The value of "stable-privacy" enables use of cryptographically + * secure hash of a secret host-specific key along with the connection + * identification and the network address as specified by RFC7217. + * This makes it impossible to use the address track host's presence, + * and makes the address stable when the network interface hardware is + * replaced. + * + * Leaving this unset causes a default that could be subject to change + * in future versions to be used. + * + * Note that this setting is distinct from the Privacy Extensions as + * configured by "ip6-privacy" property and it does not affect the + * temporary addresses configured with this option. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: addr-gen-mode + * variable: IPV6_ADDR_GEN_MODE + * values: IPV6_ADDR_GEN_MODE: eui64, stable-privacy + * default: eui64 + * description: Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217). + * example: IPV6_ADDR_GEN_MODE=stable-privacy + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ADDR_GEN_MODE, + g_param_spec_int (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, "", "", + G_MININT, G_MAXINT, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /* IP6-specific property overrides */ /* ---dbus--- diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h index b791e937..f8923d19 100644 --- a/libnm-core/nm-setting-ip6-config.h +++ b/libnm-core/nm-setting-ip6-config.h @@ -41,6 +41,8 @@ G_BEGIN_DECLS #define NM_SETTING_IP6_CONFIG_IP6_PRIVACY "ip6-privacy" +#define NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE "addr-gen-mode" + /** * NM_SETTING_IP6_CONFIG_METHOD_IGNORE: * @@ -114,6 +116,25 @@ typedef enum { NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR = 2 } NMSettingIP6ConfigPrivacy; +/** + * NMSettingIP6ConfigAddrGenMode: + * @NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64: The Interface Identifier is derived + * from the interface hardware address. + * @NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY: The Interface Identifier + * is created by using a cryptographically secure hash of a secret host-specific + * key along with the connection identification and the network address as + * specified by RFC7217. + * + * #NMSettingIP6ConfigAddrGenMode controls how the the Interface Identifier for + * RFC4862 Stateless Address Autoconfiguration is created. + * + * Since: 1.2 + */ +typedef enum { + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 = 0, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY = 1, +} NMSettingIP6ConfigAddrGenMode; + struct _NMSettingIP6Config { NMSettingIPConfig parent; }; @@ -130,6 +151,8 @@ GType nm_setting_ip6_config_get_type (void); NMSetting *nm_setting_ip6_config_new (void); NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_2 +NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c new file mode 100644 index 00000000..7bedf514 --- /dev/null +++ b/libnm-core/nm-setting-macvlan.c @@ -0,0 +1,350 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include "nm-setting-macvlan.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-macvlan + * @short_description: Describes connection properties for macvlan interfaces + * + * The #NMSettingMacvlan object is a #NMSetting subclass that describes properties + * necessary for connection to macvlan interfaces. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING, + _nm_register_setting (MACVLAN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_MACVLAN) + +#define NM_SETTING_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate)) + +typedef struct { + char *parent; + NMSettingMacvlanMode mode; + gboolean promiscuous; + gboolean tap; +} NMSettingMacvlanPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_MODE, + PROP_PROMISCUOUS, + PROP_TAP, + LAST_PROP +}; + +/** + * nm_setting_macvlan_new: + * + * Creates a new #NMSettingMacvlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingMacvlan object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_macvlan_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_MACVLAN, NULL); +} + +/** + * nm_setting_macvlan_get_parent: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:parent property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_macvlan_get_parent (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NULL); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_macvlan_get_mode: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:mode property of the setting + * + * Since: 1.2 + **/ +NMSettingMacvlanMode +nm_setting_macvlan_get_mode (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NM_SETTING_MACVLAN_MODE_UNKNOWN); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->mode; +} + +/** + * nm_setting_macvlan_get_promiscuous: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:promiscuous property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->promiscuous; +} + +/** + * nm_setting_macvlan_get_tap: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:tap property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_tap (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->tap; +} + +/*********************************************************************/ + +static void +nm_setting_macvlan_init (NMSettingMacvlan *setting) +{ +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + NMSettingConnection *s_con; + NMSettingWired *s_wired; + + if (connection) { + s_con = nm_connection_get_setting_connection (connection); + s_wired = nm_connection_get_setting_wired (connection); + } else { + s_con = NULL; + s_wired = NULL; + } + + if (priv->parent) { + if ( !nm_utils_is_uuid (priv->parent) + && !nm_utils_iface_valid_name (priv->parent)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if ( connection + && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } + + if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("non promiscuous operation is allowed only in passthru mode'")); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_MACVLAN_PROMISCUOUS); + return FALSE; + + } + + return TRUE; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + break; + case PROP_MODE: + priv->mode = g_value_get_uint (value); + break; + case PROP_PROMISCUOUS: + priv->promiscuous = g_value_get_boolean (value); + break; + case PROP_TAP: + priv->tap = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string (value, priv->parent); + break; + case PROP_MODE: + g_value_set_uint (value, priv->mode); + break; + case PROP_PROMISCUOUS: + g_value_set_boolean (value, priv->promiscuous); + break; + case PROP_TAP: + g_value_set_boolean (value, priv->tap); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + g_free (priv->parent); + + G_OBJECT_CLASS (nm_setting_macvlan_parent_class)->finalize (object); +} + +static void +nm_setting_macvlan_class_init (NMSettingMacvlanClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingMacvlanPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingMacvlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this MAC-VLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_MACVLAN_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:mode: + * + * The macvlan mode, which specifies the communication mechanism between multiple + * macvlans on the same lower device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_SETTING_MACVLAN_MODE, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:promiscuous: + * + * Whether the interface should be put in promiscuous mode. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PROMISCUOUS, + g_param_spec_boolean (NM_SETTING_MACVLAN_PROMISCUOUS, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:tap: + * + * Whether the interface should be a MACVTAP. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TAP, + g_param_spec_boolean (NM_SETTING_MACVLAN_TAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-macvlan.h b/libnm-core/nm-setting-macvlan.h new file mode 100644 index 00000000..3922cd93 --- /dev/null +++ b/libnm-core/nm-setting-macvlan.h @@ -0,0 +1,94 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_MACVLAN_H__ +#define __NM_SETTING_MACVLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_MACVLAN (nm_setting_macvlan_get_type ()) +#define NM_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlan)) +#define NM_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_MACVLANCONFIG, NMSettingMacvlanClass)) +#define NM_IS_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_MACVLAN)) +#define NM_IS_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_MACVLAN)) +#define NM_SETTING_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanClass)) + +#define NM_SETTING_MACVLAN_SETTING_NAME "macvlan" + +#define NM_SETTING_MACVLAN_PARENT "parent" +#define NM_SETTING_MACVLAN_MODE "mode" +#define NM_SETTING_MACVLAN_PROMISCUOUS "promiscuous" +#define NM_SETTING_MACVLAN_TAP "tap" + +struct _NMSettingMacvlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingMacvlanClass; + +/** + * NMSettingMacvlanMode: + * @NM_SETTING_MACVLAN_MODE_UNKNOWN: unknown/unset mode + * @NM_SETTING_MACVLAN_MODE_VEPA: Virtual Ethernet Port Aggregator mode + * @NM_SETTING_MACVLAN_MODE_BRIDGE: bridge mode + * @NM_SETTING_MACVLAN_MODE_PRIVATE: private mode + * @NM_SETTING_MACVLAN_MODE_PASSTHRU: passthru mode + * @NM_SETTING_MACVLAN_MODE_SOURCE: source mode + **/ +typedef enum { + NM_SETTING_MACVLAN_MODE_UNKNOWN = 0, + NM_SETTING_MACVLAN_MODE_VEPA = 1, + NM_SETTING_MACVLAN_MODE_BRIDGE = 2, + NM_SETTING_MACVLAN_MODE_PRIVATE = 3, + NM_SETTING_MACVLAN_MODE_PASSTHRU = 4, + NM_SETTING_MACVLAN_MODE_SOURCE = 5, + _NM_SETTING_MACVLAN_MODE_NUM, /*< skip >*/ + NM_SETTING_MACVLAN_MODE_LAST = _NM_SETTING_MACVLAN_MODE_NUM - 1, /*< skip >*/ +} NMSettingMacvlanMode; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_macvlan_get_type (void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_macvlan_new (void); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_macvlan_get_parent (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlanMode nm_setting_macvlan_get_mode (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_tap (NMSettingMacvlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_MACVLAN_H__ */ diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c index a3a5d881..4b42c365 100644 --- a/libnm-core/nm-setting-olpc-mesh.c +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -23,13 +23,20 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-olpc-mesh.h" #include "nm-utils.h" #include "nm-utils-private.h" #include "nm-setting-private.h" +/** + * SECTION:nm-setting-olpc-mesh + * @short_description: Describes connection properties for OLPC-Mesh devices + * + * The #NMSettingOlpcMesh object is a #NMSetting subclass that describes properties + * necessary for connection to OLPC-Mesh devices. + **/ + static void nm_setting_olpc_mesh_init (NMSettingOlpcMesh *setting); G_DEFINE_TYPE_WITH_CODE (NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING, diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c index 01f798ea..2cc5a209 100644 --- a/libnm-core/nm-setting-ppp.c +++ b/libnm-core/nm-setting-ppp.c @@ -22,8 +22,6 @@ #include "config.h" -#include <glib/gi18n-lib.h> - #include "nm-setting-ppp.h" #include "nm-setting-private.h" diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index ac6764d0..e2466eb3 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -23,7 +23,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 955608fa..cb7ca52e 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -21,10 +21,10 @@ #ifndef __NM_SETTING_PRIVATE_H__ #define __NM_SETTING_PRIVATE_H__ +#include "nm-default.h" #include "nm-setting.h" #include "nm-connection.h" #include "nm-core-enum-types.h" -#include "nm-glib-compat.h" #include "nm-core-internal.h" @@ -89,10 +89,20 @@ gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting, /* This is a legacy property, which clients should not send to the daemon. */ #define NM_SETTING_PARAM_LEGACY (1 << (5 + G_PARAM_USER_SHIFT)) +/* When a connection is active and gets modified, usually the change + * to the settings-connection does not propagate automatically to the + * applied-connection of the device. For certain properties like the + * firewall zone and the metered property, this is different. + * + * Such fields can be ignored during nm_connection_compare() with the + * NMSettingCompareFlag NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY. + */ +#define NM_SETTING_PARAM_REAPPLY_IMMEDIATELY (1 << (6 + G_PARAM_USER_SHIFT)) + /* Ensure the setting's GType is registered at library load time */ #define NM_SETTING_REGISTER_TYPE(x) \ static void __attribute__((constructor)) register_setting (void) \ -{ g_type_init (); g_type_ensure (x); } +{ nm_g_type_init (); g_type_ensure (x); } GVariant *_nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, NMConnection *connection, @@ -102,6 +112,11 @@ NMSettingVerifyResult _nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error); +gboolean _nm_setting_verify_secret_string (const char *str, + const char *setting_name, + const char *property, + GError **error); + gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type); GVariant *_nm_setting_to_dbus (NMSetting *setting, @@ -155,6 +170,4 @@ gboolean _nm_setting_use_legacy_property (NMSetting *setting, GPtrArray *_nm_setting_need_secrets (NMSetting *setting); -NMSetting8021xCKScheme nm_setting_802_1x_check_cert_scheme (gconstpointer pdata, gsize length, GError **error); - #endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c index 3fd780c8..b8589cd2 100644 --- a/libnm-core/nm-setting-serial.c +++ b/libnm-core/nm-setting-serial.c @@ -24,8 +24,8 @@ #include <string.h> +#include "nm-default.h" #include "nm-setting-serial.h" -#include "nm-glib-compat.h" #include "nm-setting-private.h" /** diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index 7fbf8620..78cb3cb7 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -23,7 +23,6 @@ #include <string.h> #include <ctype.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-team-port.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 04b98243..2dfffaac 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -22,7 +22,6 @@ #include <string.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-team.h" #include "nm-utils.h" diff --git a/libnm-core/nm-setting-tun.c b/libnm-core/nm-setting-tun.c new file mode 100644 index 00000000..b3c11860 --- /dev/null +++ b/libnm-core/nm-setting-tun.c @@ -0,0 +1,409 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include "nm-setting-tun.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-tun + * @short_description: Describes connection properties for TUN/TAP interfaces + * + * The #NMSettingTun object is a #NMSetting subclass that describes properties + * necessary for connection to TUN/TAP interfaces. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingTun, nm_setting_tun, NM_TYPE_SETTING, + _nm_register_setting (TUN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TUN) + +#define NM_SETTING_TUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TUN, NMSettingTunPrivate)) + +typedef struct { + NMSettingTunMode mode; + char *owner; + char *group; + gboolean pi; + gboolean vnet_hdr; + gboolean multi_queue; +} NMSettingTunPrivate; + +enum { + PROP_0, + PROP_MODE, + PROP_OWNER, + PROP_GROUP, + PROP_PI, + PROP_VNET_HDR, + PROP_MULTI_QUEUE, + LAST_PROP +}; + +/** + * nm_setting_tun_new: + * + * Creates a new #NMSettingTun object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTun object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_tun_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_TUN, NULL); +} + +/** + * nm_setting_tun_get_mode: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:mode property of the setting + * + * Since: 1.2 + **/ +NMSettingTunMode +nm_setting_tun_get_mode (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), NM_SETTING_TUN_MODE_TUN); + return NM_SETTING_TUN_GET_PRIVATE (setting)->mode; +} + +/** + * nm_setting_tun_get_owner: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:owner property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_tun_get_owner (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), NULL); + return NM_SETTING_TUN_GET_PRIVATE (setting)->owner; +} + +/** + * nm_setting_tun_get_group: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:group property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_tun_get_group (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), NULL); + return NM_SETTING_TUN_GET_PRIVATE (setting)->group; +} + +/** + * nm_setting_tun_get_pi: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:pi property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_pi (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE (setting)->pi; +} + +/** + * nm_setting_tun_get_vnet_hdr: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:vnet_hdr property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_vnet_hdr (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE (setting)->vnet_hdr; +} + +/** + * nm_setting_tun_get_multi_queue: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:multi-queue property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_multi_queue (NMSettingTun *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TUN (setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE (setting)->multi_queue; +} + +static void +nm_setting_tun_init (NMSettingTun *setting) +{ +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE (setting); + + if ( priv->mode != NM_SETTING_TUN_MODE_TUN + && priv->mode != NM_SETTING_TUN_MODE_TAP) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%u': invalid mode"), (unsigned int) priv->mode); + g_prefix_error (error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MODE); + return FALSE; + } + + if (priv->owner) { + if (_nm_utils_ascii_str_to_int64 (priv->owner, 10, 0, G_MAXINT32, -1) == -1) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s': invalid user ID"), priv->owner); + g_prefix_error (error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_OWNER); + return FALSE; + } + } + + if (priv->group) { + if (_nm_utils_ascii_str_to_int64 (priv->group, 10, 0, G_MAXINT32, -1) == -1) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s': invalid group ID"), priv->group); + g_prefix_error (error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_GROUP); + return FALSE; + } + } + + return TRUE; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingTun *setting = NM_SETTING_TUN (object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_MODE: + priv->mode = g_value_get_uint (value); + break; + case PROP_OWNER: + g_free (priv->owner); + priv->owner = g_value_dup_string (value); + break; + case PROP_GROUP: + g_free (priv->group); + priv->group = g_value_dup_string (value); + break; + case PROP_PI: + priv->pi = g_value_get_boolean (value); + break; + case PROP_VNET_HDR: + priv->vnet_hdr = g_value_get_boolean (value); + break; + case PROP_MULTI_QUEUE: + priv->multi_queue = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingTun *setting = NM_SETTING_TUN (object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_MODE: + g_value_set_uint (value, priv->mode); + break; + case PROP_OWNER: + g_value_set_string (value, priv->owner); + break; + case PROP_GROUP: + g_value_set_string (value, priv->group); + break; + case PROP_PI: + g_value_set_boolean (value, priv->pi); + break; + case PROP_VNET_HDR: + g_value_set_boolean (value, priv->vnet_hdr); + break; + case PROP_MULTI_QUEUE: + g_value_set_boolean (value, priv->multi_queue); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingTun *setting = NM_SETTING_TUN (object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE (setting); + + g_free (priv->owner); + g_free (priv->group); + + G_OBJECT_CLASS (nm_setting_tun_parent_class)->finalize (object); +} + +static void +nm_setting_tun_class_init (NMSettingTunClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingTunPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingTun:mode: + * + * The operating mode of the virtual device. Allowed values are + * %NM_SETTING_TUN_MODE_TUN to create a layer 3 device and + * %NM_SETTING_TUN_MODE_TAP to create an Ethernet-like layer 2 + * one. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_SETTING_TUN_MODE, "", "", + 0, G_MAXUINT, NM_SETTING_TUN_MODE_TUN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTun:owner: + * + * The user ID which will own the device. If set to %NULL everyone + * will be able to use the device. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_OWNER, + g_param_spec_string (NM_SETTING_TUN_OWNER, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTun:group: + * + * The group ID which will own the device. If set to %NULL everyone + * will be able to use the device. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_GROUP, + g_param_spec_string (NM_SETTING_TUN_GROUP, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTun:pi: + * + * If %TRUE the interface will prepend a 4 byte header describing the + * physical interface to the packets. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_PI, + g_param_spec_boolean (NM_SETTING_TUN_PI, "", "", + FALSE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTun:vnet-hdr: + * + * If %TRUE the IFF_VNET_HDR the tunnel packets will include a virtio + * network header. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_VNET_HDR, + g_param_spec_boolean (NM_SETTING_TUN_VNET_HDR, "", "", + FALSE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTun:multi-queue: + * + * If the property is set to %TRUE, the interface will support + * multiple file descriptors (queues) to parallelize packet + * sending or receiving. Otherwise, the interface will only + * support a single queue. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_MULTI_QUEUE, + g_param_spec_boolean (NM_SETTING_TUN_MULTI_QUEUE, "", "", + FALSE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-tun.h b/libnm-core/nm-setting-tun.h new file mode 100644 index 00000000..2b368a69 --- /dev/null +++ b/libnm-core/nm-setting-tun.h @@ -0,0 +1,94 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_TUN_H__ +#define __NM_SETTING_TUN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TUN (nm_setting_tun_get_type ()) +#define NM_SETTING_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TUN, NMSettingTun)) +#define NM_SETTING_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_TUNCONFIG, NMSettingTunClass)) +#define NM_IS_SETTING_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_TUN)) +#define NM_IS_SETTING_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_TUN)) +#define NM_SETTING_TUN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_TUN, NMSettingTunClass)) + +#define NM_SETTING_TUN_SETTING_NAME "tun" + +#define NM_SETTING_TUN_MODE "mode" +#define NM_SETTING_TUN_OWNER "owner" +#define NM_SETTING_TUN_GROUP "group" +#define NM_SETTING_TUN_PI "pi" +#define NM_SETTING_TUN_VNET_HDR "vnet-hdr" +#define NM_SETTING_TUN_MULTI_QUEUE "multi-queue" + +/** + * NMSettingTunMode: + * @NM_SETTING_TUN_MODE_UNKNOWN: an unknown device type + * @NM_SETTING_TUN_MODE_TUN: a TUN device + * @NM_SETTING_TUN_MODE_TAP: a TAP device + * + * #NMSettingTunMode values indicate the device type (TUN/TAP) + */ +typedef enum { + NM_SETTING_TUN_MODE_UNKNOWN = 0, + NM_SETTING_TUN_MODE_TUN = 1, + NM_SETTING_TUN_MODE_TAP = 2, +} NMSettingTunMode; + +struct _NMSettingTun { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTunClass; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_tun_get_type (void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_tun_new (void); + +NM_AVAILABLE_IN_1_2 +NMSettingTunMode nm_setting_tun_get_mode (NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_tun_get_owner (NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_tun_get_group (NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_pi (NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_vnet_hdr (NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_multi_queue (NMSettingTun *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_TUN_H__ */ diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 0547141c..8428a369 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -23,10 +23,12 @@ #include <stdlib.h> #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-vlan.h" +#include "nm-default.h" +#include "nm-macros-internal.h" #include "nm-utils.h" +#include "nm-core-types-internal.h" #include "nm-setting-connection.h" #include "nm-setting-private.h" #include "nm-setting-wired.h" @@ -67,11 +69,6 @@ enum { #define MAX_SKB_PRIO G_MAXUINT32 #define MAX_8021P_PRIO 7 /* Max 802.1p priority */ -typedef struct { - guint32 from; - guint32 to; -} PriorityMap; - /** * nm_setting_vlan_new: * @@ -134,10 +131,10 @@ get_max_prio (NMVlanPriorityMap map, gboolean from) g_assert_not_reached (); } -static PriorityMap * +static NMVlanQosMapping * priority_map_new_from_str (NMVlanPriorityMap map, const char *str) { - PriorityMap *p = NULL; + NMVlanQosMapping *p = NULL; gchar **t = NULL; guint32 len; guint64 from, to; @@ -151,7 +148,7 @@ priority_map_new_from_str (NMVlanPriorityMap map, const char *str) to = g_ascii_strtoull (t[1], NULL, 10); if ((from <= get_max_prio (map, TRUE)) && (to <= get_max_prio (map, FALSE))) { - p = g_malloc0 (sizeof (PriorityMap)); + p = g_malloc0 (sizeof (NMVlanQosMapping)); p->from = from; p->to = to; } @@ -165,7 +162,7 @@ priority_map_new_from_str (NMVlanPriorityMap map, const char *str) } static void -priority_map_free (PriorityMap *map) +priority_map_free (NMVlanQosMapping *map) { g_return_if_fail (map != NULL); g_free (map); @@ -182,9 +179,44 @@ get_map (NMSettingVlan *self, NMVlanPriorityMap map) return NULL; } +static gint +prio_map_compare (gconstpointer p_a, gconstpointer p_b) +{ + const NMVlanQosMapping *a = p_a; + const NMVlanQosMapping *b = p_b; + + return a->from < b->from + ? -1 + : (a->from > b->from + ? 1 + : (a->to < b->to ? -1 : (a->to > b->to ? 1 : 0))); +} + static void set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) { + /* Assert that the list is sorted */ +#if NM_MORE_ASSERTS >= 2 + { + GSList *iter, *last; + + last = list; + iter = list ? list->next : NULL; + while (iter) { + const NMVlanQosMapping *l = last->data; + const NMVlanQosMapping *m = iter->data; + + nm_assert (prio_map_compare (last->data, iter->data) < 0); + + /* Also reject duplicates (based on "from") */ + nm_assert (l->from < m->from); + + last = iter; + iter = iter->next; + } + } +#endif + if (map == NM_VLAN_INGRESS_MAP) { NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map = list; g_object_notify (G_OBJECT (self), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); @@ -195,6 +227,22 @@ set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) g_assert_not_reached (); } +static gboolean +check_replace_duplicate_priority (GSList *list, guint32 from, guint32 to) +{ + GSList *iter; + NMVlanQosMapping *p; + + for (iter = list; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (p->from == from) { + p->to = to; + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_vlan_add_priority_str: * @setting: the #NMSettingVlan @@ -213,8 +261,8 @@ nm_setting_vlan_add_priority_str (NMSettingVlan *setting, NMVlanPriorityMap map, const char *str) { - GSList *list = NULL, *iter = NULL; - PriorityMap *item = NULL; + GSList *list = NULL; + NMVlanQosMapping *item = NULL; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); @@ -227,21 +275,16 @@ nm_setting_vlan_add_priority_str (NMSettingVlan *setting, g_return_val_if_reached (FALSE); /* Duplicates get replaced */ - for (iter = list; iter; iter = g_slist_next (iter)) { - PriorityMap *p = iter->data; - - if (p->from == item->from) { - p->to = item->to; - g_free (item); - if (map == NM_VLAN_INGRESS_MAP) - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); - else - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); - return TRUE; - } + if (check_replace_duplicate_priority (list, item->from, item->to)) { + g_free (item); + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; } - set_map (setting, map, g_slist_append (list, item)); + set_map (setting, map, g_slist_insert_sorted (list, item, prio_map_compare)); return TRUE; } @@ -286,7 +329,7 @@ nm_setting_vlan_get_priority (NMSettingVlan *setting, guint32 *out_to) { GSList *list = NULL; - PriorityMap *item = NULL; + NMVlanQosMapping *item = NULL; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); @@ -330,33 +373,111 @@ nm_setting_vlan_add_priority (NMSettingVlan *setting, guint32 from, guint32 to) { - GSList *list = NULL, *iter = NULL; - PriorityMap *item; + GSList *list = NULL; + NMVlanQosMapping *item; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); list = get_map (setting, map); - for (iter = list; iter; iter = g_slist_next (iter)) { - item = iter->data; - if (item->from == from) { - item->to = to; - if (map == NM_VLAN_INGRESS_MAP) - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); - else - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); - return TRUE; - } + if (check_replace_duplicate_priority (list, from, to)) { + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; } - item = g_malloc0 (sizeof (PriorityMap)); + item = g_malloc0 (sizeof (NMVlanQosMapping)); item->from = from; item->to = to; - set_map (setting, map, g_slist_append (list, item)); + set_map (setting, map, g_slist_insert_sorted (list, item, prio_map_compare)); return TRUE; } +gboolean +_nm_setting_vlan_set_priorities (NMSettingVlan *setting, + NMVlanPriorityMap map, + const NMVlanQosMapping *qos_map, + guint n_qos_map) +{ + gboolean has_changes = FALSE; + GSList *map_prev, *map_new; + guint i; + gint64 from_last; + + map_prev = get_map (setting, map); + + if (n_qos_map != g_slist_length (map_prev)) + has_changes = TRUE; + else { + const GSList *iter; + + iter = map_prev; + for (i = 0; i < n_qos_map; i++, iter = iter->next) { + const NMVlanQosMapping *m = iter->data; + + if ( m->from != qos_map[i].from + || m->to != qos_map[i].to) { + has_changes = TRUE; + break; + } + } + } + + if (!has_changes) + return FALSE; + + map_new = NULL; + from_last = G_MAXINT64; + for (i = n_qos_map; i > 0;) { + const NMVlanQosMapping *m = &qos_map[--i]; + NMVlanQosMapping *item; + + /* We require the array to be presorted. */ + if (m->from >= from_last) + g_return_val_if_reached (FALSE); + from_last = m->from; + + item = g_malloc0 (sizeof (NMVlanQosMapping)); + item->from = m->from; + item->to = m->to; + map_new = g_slist_prepend (map_new, item); + } + + g_slist_free_full (map_prev, g_free); + set_map (setting, map, map_new); + + return TRUE; +} + +void +_nm_setting_vlan_get_priorities (NMSettingVlan *setting, + NMVlanPriorityMap map, + NMVlanQosMapping **out_qos_map, + guint *out_n_qos_map) +{ + GSList *list; + NMVlanQosMapping *qos_map = NULL; + guint n_qos_map, i; + + list = get_map (setting, map); + + n_qos_map = g_slist_length (list); + + if (n_qos_map > 0) { + qos_map = g_new (NMVlanQosMapping, n_qos_map); + + for (i = 0; list; i++, list = list->next) { + nm_assert (i < n_qos_map); + qos_map[i] = *((const NMVlanQosMapping *) list->data); + } + } + *out_qos_map = qos_map; + *out_n_qos_map = n_qos_map; +} + /** * nm_setting_vlan_remove_priority: * @setting: the #NMSettingVlan @@ -381,7 +502,7 @@ nm_setting_vlan_remove_priority (NMSettingVlan *setting, g_return_if_fail (idx < g_slist_length (list)); item = g_slist_nth (list, idx); - priority_map_free ((PriorityMap *) (item->data)); + priority_map_free ((NMVlanQosMapping *) (item->data)); set_map (setting, map, g_slist_delete_link (list, item)); } @@ -405,7 +526,7 @@ nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, guint32 to) { GSList *list = NULL, *iter = NULL; - PriorityMap *item; + NMVlanQosMapping *item; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); @@ -414,7 +535,7 @@ nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, for (iter = list; iter; iter = g_slist_next (iter)) { item = iter->data; if (item->from == from && item->to == to) { - priority_map_free ((PriorityMap *) (iter->data)); + priority_map_free ((NMVlanQosMapping *) (iter->data)); set_map (setting, map, g_slist_delete_link (list, iter)); return TRUE; } @@ -439,7 +560,7 @@ nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting, NMVlanPriorityMap map, const char *str) { - PriorityMap *item; + NMVlanQosMapping *item; gboolean found; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); @@ -545,9 +666,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS | - NM_VLAN_FLAG_GVRP | - NM_VLAN_FLAG_LOOSE_BINDING)) { + if (priv->flags & ~NM_VLAN_FLAGS_ALL) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -559,6 +678,24 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return TRUE; } +static GVariant * +_override_flags_get (NMSetting *setting, const char *property) +{ + return g_variant_new_uint32 (nm_setting_vlan_get_flags ((NMSettingVlan *) setting)); +} + +static void +_override_flags_not_set (NMSetting *setting, + GVariant *connection_dict, + const char *property) +{ + /* we changed the default value for FLAGS. When an older client + * doesn't serialize the property, we assume it is the old default. */ + g_object_set (G_OBJECT (setting), + NM_SETTING_VLAN_FLAGS, (NMVlanFlags) 0, + NULL); +} + static GSList * priority_strv_to_maplist (NMVlanPriorityMap map, char **strv) { @@ -566,13 +703,15 @@ priority_strv_to_maplist (NMVlanPriorityMap map, char **strv) int i; for (i = 0; strv && strv[i]; i++) { - PriorityMap *item; + NMVlanQosMapping *item; item = priority_map_new_from_str (map, strv[i]); - if (item) - list = g_slist_prepend (list, item); + if (item) { + if (!check_replace_duplicate_priority (list, item->from, item->to)) + list = g_slist_prepend (list, item); + } } - return g_slist_reverse (list); + return g_slist_sort (list, prio_map_compare); } static void @@ -618,7 +757,7 @@ priority_maplist_to_strv (GSList *list) strv = g_ptr_array_new (); for (iter = list; iter; iter = g_slist_next (iter)) { - PriorityMap *item = iter->data; + NMVlanQosMapping *item = iter->data; g_ptr_array_add (strv, g_strdup_printf ("%d:%d", item->from, item->to)); } @@ -736,12 +875,18 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) * interface. Flags include %NM_VLAN_FLAG_REORDER_HEADERS (reordering of * output packet headers), %NM_VLAN_FLAG_GVRP (use of the GVRP protocol), * and %NM_VLAN_FLAG_LOOSE_BINDING (loose binding of the interface to its - * master device's operating state). + * master device's operating state). %NM_VLAN_FLAG_MVRP (use of the MVRP + * protocol). + * + * The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, + * but it used to be 0. To preserve backward compatibility, the default-value + * in the D-Bus API continues to be 0 and a missing property on D-Bus + * is still considered as 0. **/ /* ---ifcfg-rh--- * property: flags - * variable: VLAN_FLAGS, REORDER_HDR - * values: "GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDR + * variable: REORDER_HDR, GVRP, MVRP, VLAN_FLAGS + * values: "yes or "no" for REORDER_HDR, GVRP and MVRP; "LOOSE_BINDING" for VLAN_FLAGS * description: VLAN flags. * ---end--- */ @@ -754,6 +899,11 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + _nm_setting_class_override_property (parent_class, NM_SETTING_VLAN_FLAGS, + NULL, + _override_flags_get, + NULL, + _override_flags_not_set); /** * NMSettingVlan:ingress-priority-map: diff --git a/libnm-core/nm-setting-vlan.h b/libnm-core/nm-setting-vlan.h index 30305d32..cf41ba17 100644 --- a/libnm-core/nm-setting-vlan.h +++ b/libnm-core/nm-setting-vlan.h @@ -79,6 +79,8 @@ typedef enum { * @NM_VLAN_FLAG_LOOSE_BINDING: indicates that this interface's operating * state is tied to the underlying network interface but other details * (like routing) are not. + * @NM_VLAN_FLAG_MVRP: indicates that this interface should use MVRP to register + * itself with it's switch * * #NMVlanFlags values control the behavior of the VLAN interface. **/ @@ -86,10 +88,19 @@ typedef enum { /*< flags >*/ NM_VLAN_FLAG_REORDER_HEADERS = 0x1, NM_VLAN_FLAG_GVRP = 0x2, NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + NM_VLAN_FLAG_MVRP = 0x8, /* NOTE: if adding flags update nm-setting-vlan.c::verify() */ + + /* NOTE: these flags must correspond to the value from the kernel + * header files. */ } NMVlanFlags; +#define NM_VLAN_FLAGS_ALL (NM_VLAN_FLAG_REORDER_HEADERS | \ + NM_VLAN_FLAG_GVRP | \ + NM_VLAN_FLAG_LOOSE_BINDING | \ + NM_VLAN_FLAG_MVRP) + GType nm_setting_vlan_get_type (void); NMSetting *nm_setting_vlan_new (void); diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index e6fffa87..aae8ae13 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -24,7 +24,6 @@ #include <string.h> #include <errno.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> #include "nm-setting-vpn.h" #include "nm-utils.h" @@ -81,6 +80,9 @@ typedef struct { * freed with g_free(). Should contain secrets only. */ GHashTable *secrets; + + /* Timeout for the VPN service to establish the connection */ + guint32 timeout; } NMSettingVpnPrivate; enum { @@ -90,6 +92,7 @@ enum { PROP_PERSISTENT, PROP_DATA, PROP_SECRETS, + PROP_TIMEOUT, LAST_PROP }; @@ -388,6 +391,22 @@ nm_setting_vpn_foreach_secret (NMSettingVpn *setting, foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, func, user_data); } +/** + * nm_setting_vpn_get_timeout: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:timeout property of the setting + * + * Since: 1.2 + **/ +guint32 +nm_setting_vpn_get_timeout (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); + + return NM_SETTING_VPN_GET_PRIVATE (setting)->timeout; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -754,6 +773,9 @@ set_property (GObject *object, guint prop_id, g_hash_table_unref (priv->secrets); priv->secrets = _nm_utils_copy_strdict (g_value_get_boxed (value)); break; + case PROP_TIMEOUT: + priv->timeout = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -783,6 +805,9 @@ get_property (GObject *object, guint prop_id, case PROP_SECRETS: g_value_take_boxed (value, _nm_utils_copy_strdict (priv->secrets)); break; + case PROP_TIMEOUT: + g_value_set_uint (value, nm_setting_vpn_get_timeout (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -910,4 +935,22 @@ nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); + + /** + * NMSettingVpn:timeout: + * + * Timeout for the VPN service to establish the connection. Some services + * may take quite a long time to connect. + * Value of 0 means a default timeout, which is 60 seconds (unless overriden + * by vpn.timeout in configuration file). Values greater than zero mean + * timeout in seconds. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TIMEOUT, + g_param_spec_uint (NM_SETTING_VPN_TIMEOUT, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-core/nm-setting-vpn.h b/libnm-core/nm-setting-vpn.h index 487549af..31f3c7b8 100644 --- a/libnm-core/nm-setting-vpn.h +++ b/libnm-core/nm-setting-vpn.h @@ -45,6 +45,7 @@ G_BEGIN_DECLS #define NM_SETTING_VPN_PERSISTENT "persistent" #define NM_SETTING_VPN_DATA "data" #define NM_SETTING_VPN_SECRETS "secrets" +#define NM_SETTING_VPN_TIMEOUT "timeout" struct _NMSettingVpn { NMSetting parent; @@ -96,6 +97,8 @@ gboolean nm_setting_vpn_remove_secret (NMSettingVpn *setting, void nm_setting_vpn_foreach_secret (NMSettingVpn *setting, NMVpnIterFunc func, gpointer user_data); +NM_AVAILABLE_IN_1_2 +guint32 nm_setting_vpn_get_timeout (NMSettingVpn *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c new file mode 100644 index 00000000..814623b7 --- /dev/null +++ b/libnm-core/nm-setting-vxlan.c @@ -0,0 +1,843 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include "nm-setting-vxlan.h" +#include "nm-utils.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-vxlan + * @short_description: Describes connection properties for VXLAN interfaces + * + * The #NMSettingVxlan object is a #NMSetting subclass that describes properties + * necessary for connection to VXLAN interfaces. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING, + _nm_register_setting (VXLAN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VXLAN) + +#define NM_SETTING_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VXLAN, NMSettingVxlanPrivate)) + +typedef struct { + char *parent; + guint id; + char *local; + char *remote; + guint source_port_min; + guint source_port_max; + guint destination_port; + guint tos; + guint ttl; + guint ageing; + guint limit; + gboolean learning; + gboolean proxy; + gboolean rsc; + gboolean l2_miss; + gboolean l3_miss; +} NMSettingVxlanPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_ID, + PROP_LOCAL, + PROP_REMOTE, + PROP_SOURCE_PORT_MIN, + PROP_SOURCE_PORT_MAX, + PROP_DESTINATION_PORT, + PROP_TOS, + PROP_TTL, + PROP_AGEING, + PROP_LIMIT, + PROP_LEARNING, + PROP_PROXY, + PROP_RSC, + PROP_L2_MISS, + PROP_L3_MISS, + + LAST_PROP +}; + +#define DST_PORT_DEFAULT 8472 + +/** + * nm_setting_vxlan_new: + * + * Creates a new #NMSettingVxlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVxlan object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_vxlan_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_VXLAN, NULL); +} + +/** + * nm_setting_vxlan_get_parent: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:parent property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_parent (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_vxlan_get_id: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:id property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_id (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->id; +} + +/** + * nm_setting_vxlan_get_local: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:local property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_local (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->local; +} + +/** + * nm_setting_vxlan_get_remote: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:remote property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_remote (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->remote; +} + +/** + * nm_setting_vxlan_get_source_port_min: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:source-port-min property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_source_port_min (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->source_port_min; +} + +/** + * nm_setting_vxlan_get_source_port_max: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:source-port-max property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_source_port_max (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->source_port_max; +} + +/** + * nm_setting_vxlan_get_destination_port: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:destination-port property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_destination_port (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), DST_PORT_DEFAULT); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->destination_port; +} + +/** + * nm_setting_vxlan_get_proxy: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:proxy property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_proxy (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->proxy; +} + +/** + * nm_setting_vxlan_get_ageing: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:ageing property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_ageing (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->ageing; +} + +/** + * nm_setting_vxlan_get_limit: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:limit property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_limit (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->limit; +} + +/** + * nm_setting_vxlan_get_tos: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:tos property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_tos (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->tos; +} + +/** + * nm_setting_vxlan_get_ttl: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:ttl property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_ttl (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->ttl; +} + +/** + * nm_setting_vxlan_get_learning: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:learning property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_learning (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->learning; +} + +/** + * nm_setting_vxlan_get_rsc: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:rsc property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_rsc (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->rsc; +} + +/** + * nm_setting_vxlan_get_l2_miss: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:l2_miss property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_l2_miss (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->l2_miss; +} + +/** + * nm_setting_vxlan_get_l3_miss: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:l3_miss property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_l3_miss (NMSettingVxlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE (setting)->l3_miss; +} + +/*********************************************************************/ + +static void +nm_setting_vxlan_init (NMSettingVxlan *setting) +{ +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting); + int family = AF_UNSPEC; + + if (!priv->remote) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_REMOTE); + return FALSE; + } + + if (nm_utils_ipaddr_valid (AF_INET, priv->remote)) + family = AF_INET; + else if (nm_utils_ipaddr_valid (AF_INET6, priv->remote)) + family = AF_INET6; + else { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IP address"), + priv->remote); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_REMOTE); + return FALSE; + } + + if (priv->local) { + if (!nm_utils_ipaddr_valid (family, priv->local)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IP%c address"), + priv->local, family == AF_INET ? '4' : '6'); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_LOCAL); + return FALSE; + } + } + + if ( priv->parent + && !nm_utils_iface_valid_name (priv->parent) + && !nm_utils_is_uuid (priv->parent)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_PARENT); + return FALSE; + } + + if ( (priv->source_port_min || priv->source_port_max) + && (priv->source_port_min > priv->source_port_max)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d is greater than local port max %d"), + priv->source_port_min, + priv->source_port_max); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_SOURCE_PORT_MIN); + return FALSE; + } + + return TRUE; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingVxlan *setting = NM_SETTING_VXLAN (object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + break; + case PROP_ID: + priv->id = g_value_get_uint (value); + break; + case PROP_LOCAL: + g_free (priv->local); + priv->local = g_value_dup_string (value); + break; + case PROP_REMOTE: + g_free (priv->remote); + priv->remote = g_value_dup_string (value); + break; + case PROP_SOURCE_PORT_MIN: + priv->source_port_min = g_value_get_uint (value); + break; + case PROP_SOURCE_PORT_MAX: + priv->source_port_max = g_value_get_uint (value); + break; + case PROP_DESTINATION_PORT: + priv->destination_port = g_value_get_uint (value); + break; + case PROP_TOS: + priv->tos = g_value_get_uint (value); + break; + case PROP_AGEING: + priv->ageing = g_value_get_uint (value); + break; + case PROP_LIMIT: + priv->limit = g_value_get_uint (value); + break; + case PROP_PROXY: + priv->proxy = g_value_get_boolean (value); + break; + case PROP_TTL: + priv->ttl = g_value_get_uint (value); + break; + case PROP_LEARNING: + priv->learning = g_value_get_boolean (value); + break; + case PROP_RSC: + priv->rsc = g_value_get_boolean (value); + break; + case PROP_L2_MISS: + priv->l2_miss = g_value_get_boolean (value); + break; + case PROP_L3_MISS: + priv->l3_miss = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingVxlan *setting = NM_SETTING_VXLAN (object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string (value, priv->parent); + break; + case PROP_ID: + g_value_set_uint (value, priv->id); + break; + case PROP_LOCAL: + g_value_set_string (value, priv->local); + break; + case PROP_REMOTE: + g_value_set_string (value, priv->remote); + break; + case PROP_SOURCE_PORT_MIN: + g_value_set_uint (value, priv->source_port_min); + break; + case PROP_SOURCE_PORT_MAX: + g_value_set_uint (value, priv->source_port_max); + break; + case PROP_DESTINATION_PORT: + g_value_set_uint (value, priv->destination_port); + break; + case PROP_TOS: + g_value_set_uint (value, priv->tos); + break; + case PROP_AGEING: + g_value_set_uint (value, priv->ageing); + break; + case PROP_LIMIT: + g_value_set_uint (value, priv->limit); + break; + case PROP_PROXY: + g_value_set_boolean (value, priv->proxy); + break; + case PROP_TTL: + g_value_set_uint (value, priv->ttl); + break; + case PROP_LEARNING: + g_value_set_boolean (value, priv->learning); + break; + case PROP_RSC: + g_value_set_boolean (value, priv->rsc); + break; + case PROP_L2_MISS: + g_value_set_boolean (value, priv->l2_miss); + break; + case PROP_L3_MISS: + g_value_set_boolean (value, priv->l3_miss); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingVxlan *setting = NM_SETTING_VXLAN (object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting); + + g_free (priv->parent); + g_free (priv->local); + g_free (priv->remote); + + G_OBJECT_CLASS (nm_setting_vxlan_parent_class)->finalize (object); +} + +static void +nm_setting_vxlan_class_init (NMSettingVxlanClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingVxlanPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingVxlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_VXLAN_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + /** + * NMSettingVxlan:id: + * + * Specifies the VXLAN Network Identifer (or VXLAN Segment Identifier) to + * use. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_uint (NM_SETTING_VXLAN_ID, "", "", + 0, (1 << 24) - 1, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:local: + * + * If given, specifies the source IP address to use in outgoing packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_LOCAL, + g_param_spec_string (NM_SETTING_VXLAN_LOCAL, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:remote: + * + * Specifies the unicast destination IP address to use in outgoing packets + * when the destination link layer address is not known in the VXLAN device + * forwarding database, or the multicast IP address to join. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_REMOTE, + g_param_spec_string (NM_SETTING_VXLAN_REMOTE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:source-port-min: + * + * Specifies the minimum UDP source port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_SOURCE_PORT_MIN, + g_param_spec_uint (NM_SETTING_VXLAN_SOURCE_PORT_MIN, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:source-port-max: + * + * Specifies the maximum UDP source port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_SOURCE_PORT_MAX, + g_param_spec_uint (NM_SETTING_VXLAN_SOURCE_PORT_MAX, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:destination-port: + * + * Specifies the UDP destination port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_DESTINATION_PORT, + g_param_spec_uint (NM_SETTING_VXLAN_DESTINATION_PORT, "", "", + 0, G_MAXUINT16, DST_PORT_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:ageing: + * + * Specifies the lifetime in seconds of FDB entries learnt by the kernel. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_AGEING, + g_param_spec_uint (NM_SETTING_VXLAN_AGEING, "", "", + 0, G_MAXINT32, 300, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:limit: + * + * Specifies the maximum number of FDB entries. A value of zero means that + * the kernel will store unlimited entries. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_AGEING, + g_param_spec_uint (NM_SETTING_VXLAN_LIMIT, "", "", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:tos: + * + * Specifies the TOS value to use in outgoing packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TOS, + g_param_spec_uint (NM_SETTING_VXLAN_TOS, "", "", + 0, 255, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:ttl: + * + * Specifies the time-to-live value to use in outgoing packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TTL, + g_param_spec_uint (NM_SETTING_VXLAN_TTL, "", "", + 0, 255, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:proxy: + * + * Specifies whether ARP proxy is turned on. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PROXY, + g_param_spec_boolean (NM_SETTING_VXLAN_PROXY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:learning: + * + * Specifies whether unknown source link layer addresses and IP addresses + * are entered into the VXLAN device forwarding database. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_LEARNING, + g_param_spec_boolean (NM_SETTING_VXLAN_LEARNING, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + /** + * NMSettingVxlan:rsc: + * + * Specifies whether route short circuit is turned on. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_RSC, + g_param_spec_boolean (NM_SETTING_VXLAN_RSC, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + /** + * NMSettingVxlan:l2-miss: + * + * Specifies whether netlink LL ADDR miss notifications are generated. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_L2_MISS, + g_param_spec_boolean (NM_SETTING_VXLAN_L2_MISS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVxlan:l3-miss: + * + * Specifies whether netlink IP ADDR miss notifications are generated. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_L3_MISS, + g_param_spec_boolean (NM_SETTING_VXLAN_L3_MISS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-vxlan.h b/libnm-core/nm-setting-vxlan.h new file mode 100644 index 00000000..c410338e --- /dev/null +++ b/libnm-core/nm-setting-vxlan.h @@ -0,0 +1,109 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VXLAN_H__ +#define __NM_SETTING_VXLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VXLAN (nm_setting_vxlan_get_type ()) +#define NM_SETTING_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlan)) +#define NM_SETTING_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VXLANCONFIG, NMSettingVxlanClass)) +#define NM_IS_SETTING_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VXLAN)) +#define NM_IS_SETTING_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_VXLAN)) +#define NM_SETTING_VXLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlanClass)) + +#define NM_SETTING_VXLAN_SETTING_NAME "vxlan" + +#define NM_SETTING_VXLAN_PARENT "parent" +#define NM_SETTING_VXLAN_ID "id" +#define NM_SETTING_VXLAN_LOCAL "local" +#define NM_SETTING_VXLAN_REMOTE "remote" +#define NM_SETTING_VXLAN_SOURCE_PORT_MIN "source-port-min" +#define NM_SETTING_VXLAN_SOURCE_PORT_MAX "source-port-max" +#define NM_SETTING_VXLAN_DESTINATION_PORT "destination-port" +#define NM_SETTING_VXLAN_TOS "tos" +#define NM_SETTING_VXLAN_TTL "ttl" +#define NM_SETTING_VXLAN_AGEING "ageing" +#define NM_SETTING_VXLAN_LIMIT "limit" +#define NM_SETTING_VXLAN_PROXY "proxy" +#define NM_SETTING_VXLAN_LEARNING "learning" +#define NM_SETTING_VXLAN_RSC "rsc" +#define NM_SETTING_VXLAN_L2_MISS "l2-miss" +#define NM_SETTING_VXLAN_L3_MISS "l3-miss" + +struct _NMSettingVxlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVxlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_vxlan_get_type (void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_vxlan_new (void); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_parent (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_id (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_local (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_remote (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_source_port_min (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_source_port_max (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_destination_port (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_tos (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_ttl (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_ageing (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_limit (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_proxy (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_learning (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_rsc (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_l2_miss (NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_l3_miss (NMSettingVxlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VXLAN_H__ */ diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c index 541c0bbf..95a09952 100644 --- a/libnm-core/nm-setting-wimax.c +++ b/libnm-core/nm-setting-wimax.c @@ -24,7 +24,6 @@ #include <string.h> #include <net/ethernet.h> -#include <glib/gi18n-lib.h> #include "nm-setting-wimax.h" #include "nm-setting-private.h" @@ -37,6 +36,10 @@ * * The #NMSettingWimax object is a #NMSetting subclass that describes properties * necessary for connection to 802.16e Mobile WiMAX networks. + * + * NetworkManager no longer supports WiMAX; while this API remains available for + * backward-compatibility reasons, it serves no real purpose, since WiMAX + * connections cannot be activated. **/ G_DEFINE_TYPE_WITH_CODE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING, @@ -64,6 +67,8 @@ enum { * Creates a new #NMSettingWimax object with default values. * * Returns: the new empty #NMSettingWimax object + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ NMSetting * nm_setting_wimax_new (void) @@ -79,6 +84,8 @@ nm_setting_wimax_new (void) * specific WiMAX network this setting describes a connection to. * * Returns: the WiMAX NSP name + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ const char * nm_setting_wimax_get_network_name (NMSettingWimax *setting) @@ -96,6 +103,8 @@ nm_setting_wimax_get_network_name (NMSettingWimax *setting) * to. * * Returns: the MAC address + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ const char * nm_setting_wimax_get_mac_address (NMSettingWimax *setting) @@ -217,6 +226,8 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) * * Network Service Provider (NSP) name of the WiMAX network this connection * should use. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_NETWORK_NAME, @@ -231,6 +242,8 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) * If specified, this connection will only apply to the WiMAX device whose * MAC address matches. This property does not change the MAC address of the * device (known as MAC spoofing). + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS, diff --git a/libnm-core/nm-setting-wimax.h b/libnm-core/nm-setting-wimax.h index 0a585046..0a98fbb5 100644 --- a/libnm-core/nm-setting-wimax.h +++ b/libnm-core/nm-setting-wimax.h @@ -53,10 +53,14 @@ typedef struct { gpointer padding[4]; } NMSettingWimaxClass; +NM_DEPRECATED_IN_1_2 GType nm_setting_wimax_get_type (void); +NM_DEPRECATED_IN_1_2 NMSetting *nm_setting_wimax_new (void); +NM_DEPRECATED_IN_1_2 const char *nm_setting_wimax_get_network_name (NMSettingWimax *setting); +NM_DEPRECATED_IN_1_2 const char *nm_setting_wimax_get_mac_address (NMSettingWimax *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index c38b1874..64b66971 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -24,7 +24,6 @@ #include <string.h> #include <net/ethernet.h> -#include <glib/gi18n-lib.h> #include "nm-setting-wired.h" #include "nm-utils.h" @@ -567,7 +566,7 @@ nm_setting_wired_get_valid_s390_options (NMSettingWired *setting) * * Returns: the Wake-on-LAN options * - * Since: 1.0.6 + * Since: 1.2 */ NMSettingWiredWakeOnLan nm_setting_wired_get_wake_on_lan (NMSettingWired *setting) @@ -576,6 +575,8 @@ nm_setting_wired_get_wake_on_lan (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->wol; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, NMSettingWiredWakeOnLan, nm_setting_wired_get_wake_on_lan, + (NMSettingWired *setting), (setting)); /** * nm_setting_wired_get_wake_on_lan_password: @@ -586,7 +587,7 @@ nm_setting_wired_get_wake_on_lan (NMSettingWired *setting) * * Returns: the Wake-on-LAN setting password, or %NULL if there is no password. * - * Since: 1.0.6 + * Since: 1.2 */ const char * nm_setting_wired_get_wake_on_lan_password (NMSettingWired *setting) @@ -595,6 +596,10 @@ nm_setting_wired_get_wake_on_lan_password (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->wol_password; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, const char *, nm_setting_wired_get_wake_on_lan_password, + (NMSettingWired *setting), (setting)); + +NM_BACKPORT_SYMBOL (libnm_1_0_6, GType, nm_setting_wired_wake_on_lan_get_type, (void), ()); static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) @@ -1195,7 +1200,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) * %NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (to disable management of Wake-on-LAN in * NetworkManager). * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_WAKE_ON_LAN, @@ -1212,7 +1217,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) * Wake-on-LAN, represented as an Ethernet MAC address. If %NULL, * no password will be required. * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_WAKE_ON_LAN_PASSWORD, diff --git a/libnm-core/nm-setting-wired.h b/libnm-core/nm-setting-wired.h index e1fd6f67..7eb53d30 100644 --- a/libnm-core/nm-setting-wired.h +++ b/libnm-core/nm-setting-wired.h @@ -60,7 +60,7 @@ G_BEGIN_DECLS * Options for #NMSettingWired:wake-on-lan. Note that not all options * are supported by all devices. * - * Since: 1.0.6 + * Since: 1.2 */ typedef enum { /*< flags >*/ NM_SETTING_WIRED_WAKE_ON_LAN_NONE = 0, /*< skip >*/ @@ -145,9 +145,7 @@ gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting const char *key); const char ** nm_setting_wired_get_valid_s390_options (NMSettingWired *setting); -NM_AVAILABLE_IN_1_0_6 NMSettingWiredWakeOnLan nm_setting_wired_get_wake_on_lan (NMSettingWired *setting); -NM_AVAILABLE_IN_1_0_6 const char * nm_setting_wired_get_wake_on_lan_password (NMSettingWired *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 6df5b461..7c5e3932 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -23,7 +23,6 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" @@ -1018,6 +1017,63 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } static gboolean +_verify_wep_key (const char *wep_key, + NMWepKeyType wep_key_type, + const char *property, + GError **error) +{ + if (wep_key && !nm_utils_wep_key_valid (wep_key, wep_key_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, property); + return FALSE; + } + return TRUE; +} + +static gboolean +verify_secrets (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self); + + /* LEAP */ + if ( priv->auth_alg + && !strcmp (priv->auth_alg, "leap") + && !strcmp (priv->key_mgmt, "ieee8021x")) { + if (!_nm_setting_verify_secret_string (priv->leap_password, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + error)) + return FALSE; + } + + /* WEP */ + if (!_verify_wep_key (priv->wep_key0, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, error)) + return FALSE; + if (!_verify_wep_key (priv->wep_key1, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, error)) + return FALSE; + if (!_verify_wep_key (priv->wep_key2, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, error)) + return FALSE; + if (!_verify_wep_key (priv->wep_key3, priv->wep_key_type, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, error)) + return FALSE; + + /* WPA-PSK */ + if (priv->psk && !nm_utils_wpa_psk_valid (priv->psk)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PSK); + return FALSE; + } + + return TRUE; +} + +static gboolean get_secret_flags (NMSetting *setting, const char *secret_name, gboolean verify_secret, @@ -1267,6 +1323,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting object_class->finalize = finalize; parent_class->verify = verify; + parent_class->verify_secrets = verify_secrets; parent_class->need_secrets = need_secrets; parent_class->get_secret_flags = get_secret_flags; parent_class->set_secret_flags = set_secret_flags; diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 34c97fe8..2a148293 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -24,7 +24,6 @@ #include <string.h> #include <net/ethernet.h> -#include <glib/gi18n-lib.h> #include "nm-setting-wireless.h" #include "nm-utils.h" @@ -59,6 +58,8 @@ typedef struct { guint32 mtu; GSList *seen_bssids; gboolean hidden; + guint32 powersave; + NMSettingMacRandomization mac_address_randomization; } NMSettingWirelessPrivate; enum { @@ -76,6 +77,8 @@ enum { PROP_MTU, PROP_SEEN_BSSIDS, PROP_HIDDEN, + PROP_POWERSAVE, + PROP_MAC_ADDRESS_RANDOMIZATION, LAST_PROP }; @@ -601,6 +604,39 @@ nm_setting_wireless_get_hidden (NMSettingWireless *setting) } /** + * nm_setting_wireless_get_powersave: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:powersave property of the setting + * + * Since: 1.2 + **/ +guint32 +nm_setting_wireless_get_powersave (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->powersave; +} + +/** + * nm_setting_wireless_get_mac_address_randomization: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address-randomization property of the + * setting + * + * Since: 1.2 + **/ +NMSettingMacRandomization +nm_setting_wireless_get_mac_address_randomization (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_randomization; +} + +/** * nm_setting_wireless_add_seen_bssid: * @setting: the #NMSettingWireless * @bssid: the new BSSID to add to the list @@ -915,6 +951,12 @@ set_property (GObject *object, guint prop_id, case PROP_HIDDEN: priv->hidden = g_value_get_boolean (value); break; + case PROP_POWERSAVE: + priv->powersave = g_value_get_uint (value); + break; + case PROP_MAC_ADDRESS_RANDOMIZATION: + priv->mac_address_randomization = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -968,6 +1010,12 @@ get_property (GObject *object, guint prop_id, case PROP_HIDDEN: g_value_set_boolean (value, nm_setting_wireless_get_hidden (setting)); break; + case PROP_POWERSAVE: + g_value_set_uint (value, nm_setting_wireless_get_powersave (setting)); + break; + case PROP_MAC_ADDRESS_RANDOMIZATION: + g_value_set_uint (value, nm_setting_wireless_get_mac_address_randomization (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1314,6 +1362,58 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingWireless:powersave: + * + * If set to %FALSE, Wi-Fi power saving behavior is disabled. If set to + * %TRUE, Wi-Fi power saving behavior is enabled. All other values are + * reserved. Note that even though only boolean values are allowed, the + * property type is an unsigned integer to allow for future expansion. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: powersave + * variable: POWERSAVE(+) + * default: no + * description: Enables or disables Wi-Fi power saving. + * example: POWERSAVE=yes + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_POWERSAVE, + g_param_spec_uint (NM_SETTING_WIRELESS_POWERSAVE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:mac-address-randomization: + * + * One of %NM_SETTING_MAC_RANDOMIZATION_DEFAULT (never randomize unless + * the user has set a global default to randomize and the supplicant + * supports randomization), %NM_SETTING_MAC_RANDOMIZATION_NEVER (never + * randomize the MAC address), or %NM_SETTING_MAC_RANDOMIZATION_ALWAYS + * (always randomize the MAC address). + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: mac-address-randomization + * variable: MAC_ADDRESS_RANDOMIZATION(+) + * values: 0 (default), (1) never, (2) always + * default: 1 + * description: Enables or disables Wi-Fi MAC address randomization. + * example: MAC_ADDRESS_RANDOMIZATION=2 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS_RANDOMIZATION, + g_param_spec_uint (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, "", "", + 0, G_MAXUINT32, NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* Compatibility for deprecated property */ /* ---ifcfg-rh--- * property: security diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h index ef27ded2..a4c0147f 100644 --- a/libnm-core/nm-setting-wireless.h +++ b/libnm-core/nm-setting-wireless.h @@ -54,6 +54,8 @@ G_BEGIN_DECLS #define NM_SETTING_WIRELESS_MTU "mtu" #define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" #define NM_SETTING_WIRELESS_HIDDEN "hidden" +#define NM_SETTING_WIRELESS_POWERSAVE "powersave" +#define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization" /** * NM_SETTING_WIRELESS_MODE_ADHOC: @@ -117,6 +119,11 @@ void nm_setting_wireless_clear_mac_blacklist_items (NMSettingWire guint32 nm_setting_wireless_get_mtu (NMSettingWireless *setting); gboolean nm_setting_wireless_get_hidden (NMSettingWireless *setting); +NM_AVAILABLE_IN_1_2 +guint32 nm_setting_wireless_get_powersave (NMSettingWireless *setting); + +NM_AVAILABLE_IN_1_2 +NMSettingMacRandomization nm_setting_wireless_get_mac_address_randomization (NMSettingWireless *setting); gboolean nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, const char *bssid); diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index e1e81b5d..b08eea10 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -23,15 +23,15 @@ #include "config.h" #include <string.h> -#include <glib/gi18n-lib.h> -#include <gio/gio.h> +#include "nm-default.h" #include "nm-setting.h" #include "nm-setting-private.h" #include "nm-utils.h" #include "nm-core-internal.h" #include "nm-utils-private.h" #include "nm-property-compare.h" +#include "nm-macros-internal.h" #include "nm-setting-connection.h" #include "nm-setting-bond.h" @@ -95,9 +95,7 @@ static void _ensure_registered (void) { if (G_UNLIKELY (registered_settings == NULL)) { -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + nm_g_type_init (); registered_settings = g_hash_table_new (g_str_hash, g_str_equal); registered_settings_by_type = g_hash_table_new (_nm_gtype_hash, _nm_gtype_equal); } @@ -1012,6 +1010,53 @@ _nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error return NM_SETTING_VERIFY_SUCCESS; } +/** + * nm_setting_verify_secrets: + * @setting: the #NMSetting to verify secrets in + * @connection: (allow-none): the #NMConnection that @setting came from, or + * %NULL if @setting is being verified in isolation. + * @error: location to store error, or %NULL + * + * Verifies the secrets in the setting. + * The returned #GError contains information about which secret of the setting + * failed validation, and in what way that secret failed validation. + * The secret validation is done separately from main setting validation, because + * in some cases connection failure is not desired just for the secrets. + * + * Returns: %TRUE if the setting secrets are valid, %FALSE if they are not + * + * Since: 1.2 + **/ +gboolean +nm_setting_verify_secrets (NMSetting *setting, NMConnection *connection, GError **error) +{ + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!error || *error == NULL, NM_SETTING_VERIFY_ERROR); + + if (NM_SETTING_GET_CLASS (setting)->verify_secrets) + return NM_SETTING_GET_CLASS (setting)->verify_secrets (setting, connection, error); + + return NM_SETTING_VERIFY_SUCCESS; +} + +gboolean +_nm_setting_verify_secret_string (const char *str, + const char *setting_name, + const char *property, + GError **error) +{ + if (str && !*str) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", setting_name, property); + return FALSE; + } + return TRUE; +} + static gboolean compare_property (NMSetting *setting, NMSetting *other, @@ -1101,15 +1146,20 @@ nm_setting_compare (NMSetting *a, GParamSpec *prop_spec = property_specs[i]; /* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */ - if ( (flags & NM_SETTING_COMPARE_FLAG_FUZZY) - && (prop_spec->flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))) + if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_FUZZY) + && !NM_FLAGS_ANY (prop_spec->flags, NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)) continue; - if ((flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_spec->flags & NM_SETTING_PARAM_INFERRABLE)) + if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) + && !NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_INFERRABLE)) continue; - if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) - && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) + if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY) + && NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_REAPPLY_IMMEDIATELY)) + continue; + + if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) + && NM_FLAGS_HAS (prop_spec->flags, NM_SETTING_PARAM_SECRET)) continue; same = NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); @@ -1133,6 +1183,9 @@ should_compare_prop (NMSetting *setting, if ((comp_flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_flags & NM_SETTING_PARAM_INFERRABLE)) return FALSE; + if ((comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY) && !(prop_flags & NM_SETTING_PARAM_REAPPLY_IMMEDIATELY)) + return FALSE; + if (prop_flags & NM_SETTING_PARAM_SECRET) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h index 3601fce3..3083ef60 100644 --- a/libnm-core/nm-setting.h +++ b/libnm-core/nm-setting.h @@ -127,11 +127,27 @@ typedef enum { NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP = 0x00000080, - /* 0x80000000 is used for a private flag */ + /* Higher flags like 0x80000000 and 0x40000000 are used internally as private flags */ } NMSettingCompareFlags; /** + * NMSettingMacRandomization: + * @NM_SETTING_MAC_RANDOMIZATION_DEFAULT: the default value, which unless + * overridden by user-controlled defaults configuration, is "never". + * @NM_SETTING_MAC_RANDOMIZATION_NEVER: the device's MAC address is always used. + * @NM_SETTING_MAC_RANDOMIZATION_ALWAYS: a random MAC address is used. + * + * Controls if and how the MAC address of a device is randomzied. + **/ +typedef enum { + NM_SETTING_MAC_RANDOMIZATION_DEFAULT = 0, + NM_SETTING_MAC_RANDOMIZATION_NEVER, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS, +} NMSettingMacRandomization; + + +/** * NMSetting: * * The NMSetting struct contains only private data. @@ -164,6 +180,10 @@ typedef struct { NMConnection *connection, GError **error); + gboolean (*verify_secrets) (NMSetting *setting, + NMConnection *connection, + GError **error); + GPtrArray *(*need_secrets) (NMSetting *setting); int (*update_one_secret) (NMSetting *setting, @@ -195,7 +215,7 @@ typedef struct { NMSettingCompareFlags flags); /*< private >*/ - gpointer padding[8]; + gpointer padding[7]; } NMSettingClass; /** @@ -226,6 +246,11 @@ gboolean nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_verify_secrets (NMSetting *setting, + NMConnection *connection, + GError **error); + gboolean nm_setting_compare (NMSetting *a, NMSetting *b, NMSettingCompareFlags flags); diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index ffdc6315..68aaaa1c 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -21,7 +21,12 @@ #ifndef __NM_UTILS_PRIVATE_H__ #define __NM_UTILS_PRIVATE_H__ +#ifdef __NETWORKMANAGER_TYPES_H__ +#error "nm-utils-private.h" must not be used outside of libnm-core/. Do you want "nm-core-internal.h"? +#endif + #include "nm-setting-private.h" +#include "nm-setting-ip-config.h" gboolean _nm_utils_string_slist_validate (GSList *list, const char **valid_values); diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 987cf731..930f528e 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -29,14 +29,13 @@ #include <uuid/uuid.h> #include <libintl.h> #include <gmodule.h> -#include <glib/gi18n-lib.h> +#include <sys/stat.h> +#include "nm-default.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-glib-compat.h" #include "nm-setting-private.h" #include "crypto.h" -#include "gsystem-local-alloc.h" #include "nm-macros-internal.h" #include "nm-setting-bond.h" @@ -240,7 +239,7 @@ _nm_utils_init (void) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - g_type_init (); + nm_g_type_init (); _nm_dbus_errors_init (); } @@ -845,6 +844,30 @@ _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray) } /** + * _nm_utils_strv_equal: + * @strv1: a string array + * @strv2: a string array + * + * Compare NULL-terminated string arrays for equality. + * + * Returns: %TRUE if the arrays are equal, %FALSE otherwise. + **/ +gboolean +_nm_utils_strv_equal (char **strv1, char **strv2) +{ + if (strv1 == strv2) + return TRUE; + + if (!strv1 || !strv2) + return FALSE; + + for ( ; *strv1 && *strv2 && !strcmp (*strv1, *strv2); strv1++, strv2++) + ; + + return !*strv1 && !*strv2; +} + +/** * _nm_utils_strsplit_set: * @str: string to split * @delimiters: string of delimiter characters @@ -1730,7 +1753,7 @@ nm_utils_ip6_addresses_from_variant (GVariant *value, char **out_gateway) *out_gateway = g_strdup (nm_utils_inet6_ntop (gateway_bytes, NULL)); } } else { - g_warning ("Ignoring invalid IP4 address: %s", error->message); + g_warning ("Ignoring invalid IP6 address: %s", error->message); g_clear_error (&error); } @@ -2409,6 +2432,132 @@ nm_utils_file_is_pkcs12 (const char *filename) /**********************************************************************************************/ +gboolean +_nm_utils_check_file (const char *filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat *out_st, + GError **error) +{ + struct stat st_backup; + + if (!out_st) + out_st = &st_backup; + + if (stat (filename, out_st) != 0) { + int errsv = errno; + + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("failed stat file %s: %s"), filename, strerror (errsv)); + return FALSE; + } + + /* ignore non-files. */ + if (!S_ISREG (out_st->st_mode)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("not a file (%s)"), filename); + return FALSE; + } + + /* with check_owner enabled, check that the file belongs to the + * owner or root. */ + if ( check_owner >= 0 + && (out_st->st_uid != 0 && (gint64) out_st->st_uid != check_owner)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("invalid file owner %d for %s"), out_st->st_uid, filename); + return FALSE; + } + + /* with check_owner enabled, check that the file cannot be modified + * by other users (except root). */ + if ( check_owner >= 0 + && NM_FLAGS_ANY (out_st->st_mode, S_IWGRP | S_IWOTH | S_ISUID)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("file permissions for %s"), filename); + return FALSE; + } + + if ( check_file + && !check_file (filename, out_st, user_data, error)) { + if (error && !*error) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("reject %s"), filename); + } + return FALSE; + } + + return TRUE; +} + + +gboolean +_nm_utils_check_module_file (const char *name, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error) +{ + if (!g_path_is_absolute (name)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("path is not absolute (%s)"), name); + return FALSE; + } + + /* Set special error code if the file doesn't exist. + * The VPN package might be split into separate packages, + * so it could be correct that the plugin file is missing. + * + * Note that nm-applet checks for this error code to fail + * gracefully. */ + if (!g_file_test (name, G_FILE_TEST_EXISTS)) { + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_NOENT, + _("Plugin file does not exist (%s)"), name); + return FALSE; + } + + if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("Plugin is not a valid file (%s)"), name); + return FALSE; + } + + if (g_str_has_suffix (name, ".la")) { + /* g_module_open() treats files that end with .la special. + * We don't want to parse the libtool archive. Just error out. */ + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("libtool archives are not supported (%s)"), name); + return FALSE; + } + + return _nm_utils_check_file (name, + check_owner, + check_file, + user_data, + NULL, + error); +} + +/**********************************************************************************************/ + /** * nm_utils_file_search_in_paths: * @progname: the helper program name, like "iptables" @@ -2724,13 +2873,14 @@ _wifi_freqs (gboolean bg_band) * * Returns: zero-terminated array of frequencies numbers (in MHz) * - * Since: 1.0.6 + * Since: 1.2 **/ const guint * nm_utils_wifi_2ghz_freqs (void) { return _wifi_freqs (TRUE); } +NM_BACKPORT_SYMBOL (libnm_1_0_6, const guint *, nm_utils_wifi_2ghz_freqs, (void), ()); /** * nm_utils_wifi_5ghz_freqs: @@ -2739,13 +2889,14 @@ nm_utils_wifi_2ghz_freqs (void) * * Returns: zero-terminated array of frequencies numbers (in MHz) * - * Since: 1.0.6 + * Since: 1.2 **/ const guint * nm_utils_wifi_5ghz_freqs (void) { return _wifi_freqs (FALSE); } +NM_BACKPORT_SYMBOL (libnm_1_0_6, const guint *, nm_utils_wifi_5ghz_freqs, (void), ()); /** * nm_utils_wifi_strength_bars: @@ -3501,8 +3652,9 @@ static BondMode bond_mode_table[] = { * available modes. * * Returns: bonding mode string, or NULL on error -*/ - + * + * Since: 1.2 + */ const char * nm_utils_bond_mode_int_to_string (int mode) { @@ -3521,7 +3673,9 @@ nm_utils_bond_mode_int_to_string (int mode) * The @mode string can be either a descriptive name or a number (as string). * * Returns: numeric bond mode, or -1 on error -*/ + * + * Since: 1.2 + */ int nm_utils_bond_mode_string_to_int (const char *mode) { @@ -3540,6 +3694,105 @@ nm_utils_bond_mode_string_to_int (const char *mode) /**********************************************************************************************/ +#define STRSTRDICTKEY_V1_SET 0x01 +#define STRSTRDICTKEY_V2_SET 0x02 +#define STRSTRDICTKEY_ALL_SET 0x03 + +struct _NMUtilsStrStrDictKey { + char type; + char data[1]; +}; + +guint +_nm_utils_strstrdictkey_hash (gconstpointer a) +{ + const NMUtilsStrStrDictKey *k = a; + const signed char *p; + guint32 h = 5381; + + if (k) { + if (((int) k->type) & ~STRSTRDICTKEY_ALL_SET) + g_return_val_if_reached (0); + + h = (h << 5) + h + k->type; + if (k->type & STRSTRDICTKEY_ALL_SET) { + p = (void *) k->data; + for (; *p != '\0'; p++) + h = (h << 5) + h + *p; + if (k->type == STRSTRDICTKEY_ALL_SET) { + /* the key contains two strings. Continue... */ + h = (h << 5) + h + '\0'; + for (p++; *p != '\0'; p++) + h = (h << 5) + h + *p; + } + } + } + + return h; +} + +gboolean +_nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b) +{ + const NMUtilsStrStrDictKey *k1 = a; + const NMUtilsStrStrDictKey *k2 = b; + + if (k1 == k2) + return TRUE; + if (!k1 || !k2) + return FALSE; + + if (k1->type != k2->type) + return FALSE; + + if (k1->type & STRSTRDICTKEY_ALL_SET) { + if (strcmp (k1->data, k2->data) != 0) + return FALSE; + + if (k1->type == STRSTRDICTKEY_ALL_SET) { + gsize l = strlen (k1->data) + 1; + + return strcmp (&k1->data[l], &k2->data[l]) == 0; + } + } + + return TRUE; +} + +NMUtilsStrStrDictKey * +_nm_utils_strstrdictkey_create (const char *v1, const char *v2) +{ + char type = 0; + gsize l1 = 0, l2 = 0; + NMUtilsStrStrDictKey *k; + + if (!v1 && !v2) + return g_malloc0 (1); + + /* we need to distinguish between ("",NULL) and (NULL,""). + * Thus, in @type we encode which strings we have present + * as not-NULL. */ + if (v1) { + type |= STRSTRDICTKEY_V1_SET; + l1 = strlen (v1) + 1; + } + if (v2) { + type |= STRSTRDICTKEY_V2_SET; + l2 = strlen (v2) + 1; + } + + k = g_malloc (G_STRUCT_OFFSET (NMUtilsStrStrDictKey, data) + l1 + l2); + k->type = type; + if (v1) + memcpy (&k->data[0], v1, l1); + if (v2) + memcpy (&k->data[l1], v2, l2); + + return k; +} + +/**********************************************************************************************/ + /* _nm_utils_ascii_str_to_int64: * * A wrapper for g_ascii_strtoll, that checks whether the whole string @@ -3613,30 +3866,131 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma return v; } +static gboolean +validate_dns_option (const char *name, gboolean numeric, gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs) +{ + const NMUtilsDNSOptionDesc *desc; + + if (!option_descs) + return !!*name; + + for (desc = option_descs; desc->name; desc++) { + if (!strcmp (name, desc->name) && + numeric == desc->numeric && + (!desc->ipv6_only || ipv6)) + return TRUE; + } + + return FALSE; +} + /** - * _nm_dbus_error_has_name: - * @error: (allow-none): a #GError, or %NULL - * @dbus_error_name: a D-Bus error name + * _nm_utils_dns_option_validate: + * @option: option string + * @out_name: (out) (allow-none): the option name + * @out_value: (out) (allow-none): the option value + * @ipv6: whether the option refers to a IPv6 configuration + * @option_descs: (allow-none): an array of NMUtilsDNSOptionDesc which describes the + * valid options + * + * Parses a DNS option in the form "name" or "name:number" and, if + * @option_descs is not NULL, checks that the option conforms to one + * of the provided descriptors. If @option_descs is NULL @ipv6 is + * not considered. + * + * Returns: %TRUE when the parsing was successful and the option is valid, + * %FALSE otherwise + */ +gboolean +_nm_utils_dns_option_validate (const char *option, char **out_name, + long *out_value, gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs) +{ + char **tokens, *ptr; + gboolean ret = FALSE; + + g_return_val_if_fail (option != NULL, FALSE); + + if (out_name) + *out_name = NULL; + if (out_value) + *out_value = -1; + + if (!option[0]) + return FALSE; + + tokens = g_strsplit (option, ":", 2); + + if (g_strv_length (tokens) == 1) { + ret = validate_dns_option (tokens[0], FALSE, ipv6, option_descs); + if (ret && out_name) + *out_name = g_strdup (tokens[0]); + goto out; + } + + if (!tokens[1][0]) { + ret = FALSE; + goto out; + } + + for (ptr = tokens[1]; *ptr; ptr++) { + if (!g_ascii_isdigit (*ptr)) { + ret = FALSE; + goto out; + } + } + + ret = FALSE; + if (validate_dns_option (tokens[0], TRUE, ipv6, option_descs)) { + int value = _nm_utils_ascii_str_to_int64 (tokens[1], 10, 0, G_MAXINT32, -1); + if (value >= 0) { + if (out_name) + *out_name = g_strdup (tokens[0]); + if (out_value) + *out_value = value; + ret = TRUE; + } + } +out: + g_strfreev (tokens); + return ret; +} + +/** + * _nm_utils_dns_option_find_idx: + * @array: an array of strings + * @option: a dns option string * - * Checks if @error is set and corresponds to the D-Bus error @dbus_error_name. + * Searches for an option in an array of strings. The match is + * performed only the option name; the option value is ignored. * - * Returns: %TRUE or %FALSE + * Returns: the index of the option in the array or -1 if was not + * found. */ -gboolean -_nm_dbus_error_has_name (GError *error, - const char *dbus_error_name) +int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) { - gboolean has_name = FALSE; + gboolean ret; + char *option_name, *tmp_name; + int i; + + if (!_nm_utils_dns_option_validate (option, &option_name, NULL, FALSE, NULL)) + return -1; - if (error && g_dbus_error_is_remote_error (error)) { - char *error_name; + for (i = 0; i < array->len; i++) { + if (_nm_utils_dns_option_validate (array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { + ret = strcmp (tmp_name, option_name); + g_free (tmp_name); + if (!ret) { + g_free (option_name); + return i; + } + } - error_name = g_dbus_error_get_remote_error (error); - has_name = !g_strcmp0 (error_name, dbus_error_name); - g_free (error_name); } - return has_name; + g_free (option_name); + return -1; } /** @@ -3651,7 +4005,7 @@ _nm_dbus_error_has_name (GError *error, * * Returns: a newly allocated string or %NULL * - * Since: 1.0.6 + * Since: 1.2 */ char *nm_utils_enum_to_str (GType type, int value) { @@ -3689,13 +4043,15 @@ char *nm_utils_enum_to_str (GType type, int value) g_type_class_unref (class); return ret; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, char *, nm_utils_enum_to_str, + (GType type, int value), (type, value)); /** * nm_utils_enum_from_str: * @type: the %GType of the enum * @str: the input string - * @out_value: (out) (allow-none) the output value - * @err_token: (out) (allow-none) location to store the first unrecognized token + * @out_value: (out) (allow-none): the output value + * @err_token: (out) (allow-none): location to store the first unrecognized token * * Converts a string to the matching enum value. * @@ -3706,7 +4062,7 @@ char *nm_utils_enum_to_str (GType type, int value) * * Returns: %TRUE if the conversion was successful, %FALSE otherwise * - * Since: 1.0.6 + * Since: 1.2 */ gboolean nm_utils_enum_from_str (GType type, const char *str, int *out_value, char **err_token) @@ -3760,3 +4116,59 @@ gboolean nm_utils_enum_from_str (GType type, const char *str, g_type_class_unref (class); return ret; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, gboolean, nm_utils_enum_from_str, + (GType type, const char *str, int *out_value, char **err_token), + (type, str, out_value, err_token)); + +/** + * nm_utils_enum_get_values: + * @type: the %GType of the enum + * @from: the first element to be returned + * @to: the last element to be returned + * + * Returns the list of possible values for a given enum. + * + * Returns: (transfer full): a NULL-terminated dynamically-allocated array of static strings + * or %NULL on error + * + * Since: 1.2 + */ +const char **nm_utils_enum_get_values (GType type, gint from, gint to) +{ + GTypeClass *class; + GPtrArray *array; + gint i; + + class = g_type_class_ref (type); + array = g_ptr_array_new (); + + if (G_IS_ENUM_CLASS (class)) { + GEnumClass *enum_class = G_ENUM_CLASS (class); + GEnumValue *enum_value; + + for (i = 0; i < enum_class->n_values; i++) { + enum_value = &enum_class->values[i]; + if (enum_value->value >= from && enum_value->value <= to) + g_ptr_array_add (array, (gpointer) enum_value->value_nick); + } + } else if (G_IS_FLAGS_CLASS (class)) { + GFlagsClass *flags_class = G_FLAGS_CLASS (class); + GFlagsValue *flags_value; + + for (i = 0; i < flags_class->n_values; i++) { + flags_value = &flags_class->values[i]; + if (flags_value->value >= from && flags_value->value <= to) + g_ptr_array_add (array, (gpointer) flags_value->value_nick); + } + } else { + g_type_class_unref (class); + g_ptr_array_free (array, TRUE); + g_return_val_if_reached (NULL); + } + + g_type_class_unref (class); + g_ptr_array_add (array, NULL); + + return (const char **) g_ptr_array_free (array, FALSE); +} + diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index e97b823e..407c14e2 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright 2005 - 2013 Red Hat, Inc. + * Copyright 2005 - 2014 Red Hat, Inc. */ #ifndef __NM_UTILS_H__ @@ -127,6 +127,10 @@ gboolean nm_utils_file_is_pkcs12 (const char *filename); typedef gboolean (*NMUtilsFileSearchInPathsPredicate) (const char *filename, gpointer user_data); +struct stat; + +typedef gboolean (*NMUtilsCheckFilePredicate) (const char *filename, const struct stat *stat, gpointer user_data, GError **error); + const char *nm_utils_file_search_in_paths (const char *progname, const char *try_first, const char *const *paths, @@ -139,9 +143,9 @@ guint32 nm_utils_wifi_freq_to_channel (guint32 freq); guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band); guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band); gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 const guint *nm_utils_wifi_2ghz_freqs (void); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 const guint *nm_utils_wifi_5ghz_freqs (void); const char *nm_utils_wifi_strength_bars (guint8 strength); @@ -188,12 +192,20 @@ gboolean nm_utils_ipaddr_valid (int family, const char *ip); gboolean nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 +int nm_utils_bond_mode_string_to_int (const char *mode); +NM_AVAILABLE_IN_1_2 +const char *nm_utils_bond_mode_int_to_string (int mode); + +NM_AVAILABLE_IN_1_2 char *nm_utils_enum_to_str (GType type, int value); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 gboolean nm_utils_enum_from_str (GType type, const char *str, int *out_value, char **err_token); +NM_AVAILABLE_IN_1_2 +const char **nm_utils_enum_get_values (GType type, gint from, gint to); + G_END_DECLS #endif /* __NM_UTILS_H__ */ diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h index 730330ab..859a3a8c 100644 --- a/libnm-core/nm-version.h +++ b/libnm-core/nm-version.h @@ -76,16 +76,18 @@ # define NM_AVAILABLE_IN_1_0 #endif -#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0_4 -# define NM_AVAILABLE_IN_1_0_4 G_UNAVAILABLE(1,0.4) +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_2 +# define NM_DEPRECATED_IN_1_2 G_DEPRECATED +# define NM_DEPRECATED_IN_1_2_FOR(f) G_DEPRECATED_FOR(f) #else -# define NM_AVAILABLE_IN_1_0_4 +# define NM_DEPRECATED_IN_1_2 +# define NM_DEPRECATED_IN_1_2_FOR(f) #endif -#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0_6 -# define NM_AVAILABLE_IN_1_0_6 G_UNAVAILABLE(1,0.6) +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_2 +# define NM_AVAILABLE_IN_1_2 G_UNAVAILABLE(1,2) #else -# define NM_AVAILABLE_IN_1_0_6 +# define NM_AVAILABLE_IN_1_2 #endif #endif /* NM_VERSION_H */ diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c new file mode 100644 index 00000000..2d4fdf9c --- /dev/null +++ b/libnm-core/nm-vpn-editor-plugin.c @@ -0,0 +1,287 @@ +/* -*- 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 2008 Novell, Inc. + * Copyright 2008 - 2010 Red Hat, Inc. + * Copyright 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-vpn-editor-plugin.h" + +#include <gio/gio.h> + +#include "nm-macros-internal.h" +#include "gsystem-local-alloc.h" +#include "nm-core-internal.h" + +static void nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface); + +G_DEFINE_INTERFACE (NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT) + +static void +nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface) +{ + /* Properties */ + + /** + * NMVpnEditorPlugin:name: + * + * Short display name of the VPN plugin. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:description: + * + * Longer description of the VPN plugin. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_DESCRIPTION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:service: + * + * D-Bus service name of the plugin's VPN service. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_SERVICE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/*********************************************************************/ + +/** + * nm_vpn_editor_plugin_load_from_file: + * @plugin_filename: The path to the share library to load. + * Apply some common heuristics to find the library, such as + * appending "so" file ending. + * If the path is not an absolute path or no matching module + * can be found, lookup inside a directory defined at compile time. + * Due to this, @check_file might be called for two different paths. + * @check_service: if not-null, check that the loaded plugin advertises + * the given service. + * @check_owner: if non-negative, check whether the file is owned + * by UID @check_owner or by root. In this case also check that + * the file is not writable by anybody else. + * @check_file: (scope call): optional callback to validate the file prior to + * loading the shared library. + * @user_data: user data for @check_file + * @error: on failure the error reason. + * + * Load the shared libary @plugin_filename and create a new + * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory + * function. + * + * Returns: (transfer full): a new plugin instance or %NULL on error. + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_editor_plugin_load_from_file (const char *plugin_filename, + const char *check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error) +{ + GModule *module = NULL; + gs_free_error GError *local = NULL; + NMVpnEditorPluginFactory factory = NULL; + NMVpnEditorPlugin *editor_plugin = NULL; + + g_return_val_if_fail (plugin_filename && *plugin_filename, NULL); + + /* _nm_utils_check_module_file() fails with ENOENT if the plugin file + * does not exist. That is relevant, because nm-applet checks for that. */ + if (_nm_utils_check_module_file (plugin_filename, + check_owner, + check_file, + user_data, + &local)) + module = g_module_open (plugin_filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + + if (!module) { + if (local) { + g_propagate_error (error, local); + local = NULL; + } else { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load plugin %s"), plugin_filename); + } + return NULL; + } + g_clear_error (&local); + + if (g_module_symbol (module, "nm_vpn_editor_plugin_factory", (gpointer) &factory)) { + gs_free_error GError *factory_error = NULL; + gboolean success = FALSE; + + editor_plugin = factory (&factory_error); + + g_assert (!editor_plugin || G_IS_OBJECT (editor_plugin)); + + if (editor_plugin) { + gs_free char *plug_name = NULL, *plug_service = NULL; + + /* Validate plugin properties */ + + g_object_get (G_OBJECT (editor_plugin), + NM_VPN_EDITOR_PLUGIN_NAME, &plug_name, + NM_VPN_EDITOR_PLUGIN_SERVICE, &plug_service, + NULL); + + if (!plug_name || !*plug_name) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load VPN plugin in '%s': missing plugin name"), + g_module_name (module)); + } else if ( check_service + && g_strcmp0 (plug_service, check_service) != 0) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load VPN plugin in '%s': invalid service name"), + g_module_name (module)); + } else { + /* Success! */ + g_object_set_data_full (G_OBJECT (editor_plugin), "gmodule", module, + (GDestroyNotify) g_module_close); + success = TRUE; + } + } else { + if (factory_error) { + g_propagate_error (error, factory_error); + factory_error = NULL; + } else { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unknown error initializing plugin %s"), plugin_filename); + } + } + + if (!success) { + g_module_close (module); + editor_plugin = NULL; + } + } else { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("failed to load nm_vpn_editor_plugin_factory() from %s (%s)"), + g_module_name (module), g_module_error ()); + g_module_close (module); + editor_plugin = NULL; + } + + return editor_plugin; +} + +/*********************************************************************/ + +/** + * nm_vpn_editor_plugin_get_editor: + * + * Returns: (transfer full): + */ +NMVpnEditor * +nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_editor (plugin, connection, error); +} + +NMVpnEditorPluginCapability +nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), 0); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_capabilities (plugin); +} + +/** + * nm_vpn_editor_plugin_import: + * + * Returns: (transfer full): + */ +NMConnection * +nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin, + const char *path, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) { + g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file != NULL, NULL); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file (plugin, path, error); + } + + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("the plugin does not support import capability")); + return NULL; +} + +gboolean +nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE); + + if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) { + g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file != NULL, FALSE); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file (plugin, path, connection, error); + } + + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("the plugin does not support export capability")); + return FALSE; +} + +char * +nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin, + NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename) + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename (plugin, connection); + return NULL; +} + diff --git a/libnm-core/nm-vpn-editor-plugin.h b/libnm-core/nm-vpn-editor-plugin.h new file mode 100644 index 00000000..16e9533d --- /dev/null +++ b/libnm-core/nm-vpn-editor-plugin.h @@ -0,0 +1,152 @@ +/* -*- 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 2008 Novell, Inc. + * Copyright 2008 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_EDITOR_PLUGIN_H__ +#define __NM_VPN_EDITOR_PLUGIN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include <glib.h> +#include <glib-object.h> + +#include "nm-connection.h" +#include "nm-utils.h" + +G_BEGIN_DECLS + +typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin; +typedef struct _NMVpnEditor NMVpnEditor; + +/* Plugin's factory function that returns a GObject that implements + * NMVpnEditorPlugin. + */ +#ifndef __GI_SCANNER__ +typedef NMVpnEditorPlugin * (*NMVpnEditorPluginFactory) (GError **error); +NMVpnEditorPlugin *nm_vpn_editor_plugin_factory (GError **error); +#endif + + +/**************************************************/ +/* Editor plugin interface */ +/**************************************************/ + +#define NM_TYPE_VPN_EDITOR_PLUGIN (nm_vpn_editor_plugin_get_type ()) +#define NM_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPlugin)) +#define NM_IS_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN)) +#define NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPluginInterface)) + +/** + * NMVpnEditorPluginCapability: + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: unknown or no capability + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: the plugin can import new connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: the plugin can export connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: the plugin supports IPv6 addressing + * + * Flags that indicate certain capabilities of the plugin to editor programs. + **/ +typedef enum /*< flags >*/ { + NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04 +} NMVpnEditorPluginCapability; + +/* Short display name of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_NAME "name" + +/* Longer description of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_DESCRIPTION "description" + +/* D-Bus service name of the plugin's VPN service */ +#define NM_VPN_EDITOR_PLUGIN_SERVICE "service" + +/** + * NMVpnEditorPluginInterface: + * @g_iface: the parent interface + * @get_editor: returns an #NMVpnEditor, pre-filled with values from @connection + * if non-%NULL. + * @get_capabilities: returns a bitmask of capabilities. + * @import_from_file: Try to import a connection from the specified path. On + * success, return a partial #NMConnection object. On error, return %NULL and + * set @error with additional information. Note that @error can be %NULL, in + * which case no additional error information should be provided. + * @export_to_file: Export the given connection to the specified path. Return + * %TRUE on success. On error, return %FALSE and set @error with additional + * error information. Note that @error can be %NULL, in which case no + * additional error information should be provided. + * @get_suggested_filename: For a given connection, return a suggested file + * name. Returned value will be %NULL or a suggested file name to be freed by + * the caller. + * + * Interface for VPN editor plugins. + */ +typedef struct { + GTypeInterface g_iface; + + NMVpnEditor * (*get_editor) (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error); + + NMVpnEditorPluginCapability (*get_capabilities) (NMVpnEditorPlugin *plugin); + + NMConnection * (*import_from_file) (NMVpnEditorPlugin *plugin, + const char *path, + GError **error); + + gboolean (*export_to_file) (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error); + + char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection); +} NMVpnEditorPluginInterface; + +GType nm_vpn_editor_plugin_get_type (void); + +NMVpnEditor *nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error); + +NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin); + +NMConnection *nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin, + const char *path, + GError **error); +gboolean nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error); +char *nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin, + NMConnection *connection); + +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_editor_plugin_load_from_file (const char *plugin_filename, + const char *check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error); + +G_END_DECLS + +#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */ diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c new file mode 100644 index 00000000..3a4796b9 --- /dev/null +++ b/libnm-core/nm-vpn-plugin-info.c @@ -0,0 +1,1030 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-vpn-plugin-info.h" + +#include <gio/gio.h> +#include <string.h> +#include <errno.h> +#include <sys/stat.h> + +#include "gsystem-local-alloc.h" +#include "nm-errors.h" +#include "nm-macros-internal.h" +#include "nm-core-internal.h" + +#define DEFAULT_DIR_ETC NMCONFDIR"/VPN" +#define DEFAULT_DIR_LIB NMLIBDIR"/VPN" + +enum { + PROP_0, + PROP_NAME, + PROP_FILENAME, + PROP_KEYFILE, + + LAST_PROP, +}; + +typedef struct { + char *filename; + char *name; + char *service; + char **aliases; + GKeyFile *keyfile; + + /* It is convenient for nm_vpn_plugin_info_lookup_property() to return a const char *, + * contrary to what g_key_file_get_string() does. Hence we must cache the returned + * value somewhere... let's put it in an internal hash table. + * This contains a clone of all the strings in keyfile. */ + GHashTable *keys; + + gboolean editor_plugin_loaded; + NMVpnEditorPlugin *editor_plugin; +} NMVpnPluginInfoPrivate; + +static void nm_vpn_plugin_info_initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMVpnPluginInfo, nm_vpn_plugin_info, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_vpn_plugin_info_initable_iface_init); + ) + +#define NM_VPN_PLUGIN_INFO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoPrivate)) + +/*********************************************************************/ + +/** + * nm_vpn_plugin_info_validate_filename: + * @filename: the filename to check + * + * Regular name files have a certain pattern. That basically means + * they have the file extension "name". Check if @filename + * is valid according to that pattern. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_validate_filename (const char *filename) +{ + if (!filename || !g_str_has_suffix (filename, ".name")) + return FALSE; + + /* originally, we didn't do further checks... but here we go. */ + if (filename[0] == '.') { + /* this also rejects name ".name" alone. */ + return FALSE; + } + return TRUE; +} + +static gboolean +nm_vpn_plugin_info_check_file_full (const char *filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat *out_st, + GError **error) +{ + if (!filename || !*filename) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("missing filename")); + return FALSE; + } + + if (check_absolute && !g_path_is_absolute (filename)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("filename must be an absolute path (%s)"), filename); + return FALSE; + } + + if ( do_validate_filename + && !nm_vpn_plugin_info_validate_filename (filename)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("filename has invalid format (%s)"), filename); + return FALSE; + } + + return _nm_utils_check_file (filename, + check_owner, + check_file, + user_data, + out_st, + error); +} + +/** + * _nm_vpn_plugin_info_check_file: + * @filename: + * @check_absolute: if %TRUE, only allow absolute path names. + * @do_validate_filename: if %TRUE, only accept the filename if + * nm_vpn_plugin_info_validate_filename() succeeds. + * @check_owner: if non-negative, only accept the file if the + * owner UID is equal to @check_owner or if the owner is 0. + * In this case, also check that the file is not writable by + * other users. + * @check_file: pass a callback to do your own validation. + * @user_data: user data for @check_file. + * @error: (allow-none): (out): the error reason if the check fails. + * + * Check whether the file exists and is a valid name file (in keyfile format). + * Additionally, also check for file permissions. + * + * Returns: %TRUE if a file @filename exists and has valid permissions. + * + * Since: 1.2 + */ +gboolean +_nm_vpn_plugin_info_check_file (const char *filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error) +{ + return nm_vpn_plugin_info_check_file_full (filename, check_absolute, do_validate_filename, check_owner, check_file, user_data, NULL, error); +} + +typedef struct { + NMVpnPluginInfo *plugin_info; + struct stat stat; +} LoadDirInfo; + +static int +_sort_files (LoadDirInfo *a, LoadDirInfo *b) +{ + time_t ta, tb; + + ta = MAX (a->stat.st_mtime, a->stat.st_ctime); + tb = MAX (b->stat.st_mtime, b->stat.st_ctime); + if (ta < tb) + return 1; + if (ta > tb) + return -1; + return g_strcmp0 (nm_vpn_plugin_info_get_filename (a->plugin_info), + nm_vpn_plugin_info_get_filename (b->plugin_info)); +} + +/** + * _nm_vpn_plugin_info_get_default_dir_etc: + * + * Returns: (transfer none): compile time constant of the default + * VPN plugin directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_etc () +{ + return DEFAULT_DIR_ETC; +} + +/** + * _nm_vpn_plugin_info_get_default_dir_lib: + * + * Returns: (transfer none): compile time constant of the default + * VPN plugin directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_lib () +{ + return DEFAULT_DIR_LIB; +} + +/** + * _nm_vpn_plugin_info_get_default_dir_user: + * + * Returns: The user can specify a different directory for VPN plugins + * by setting NM_VPN_PLUGIN_DIR environment variable. Return + * that directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_user () +{ + return g_getenv ("NM_VPN_PLUGIN_DIR"); +} + +/** + * _nm_vpn_plugin_info_list_load_dir: + * @dirname: the name of the directory to load. + * @do_validate_filename: only consider filenames that have a certain + * pattern (i.e. end with ".name"). + * @check_owner: if set to a non-negative number, check that the file + * owner is either the same uid or 0. In that case, also check + * that the file is not writable by group or other. + * @check_file: (allow-none): callback to check whether the file is valid. + * @user_data: data for @check_file + * + * Iterate over the content of @dirname and load name files. + * + * Returns: (transfer full) (element-type NMVpnPluginInfo): list of loaded plugin infos. + */ +GSList * +_nm_vpn_plugin_info_list_load_dir (const char *dirname, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data) +{ + GDir *dir; + const char *fn; + GArray *array; + GSList *res = NULL; + guint i; + + g_return_val_if_fail (dirname && dirname[0], NULL); + + dir = g_dir_open (dirname, 0, NULL); + if (!dir) + return NULL; + + array = g_array_new (FALSE, FALSE, sizeof (LoadDirInfo)); + + while ((fn = g_dir_read_name (dir))) { + gs_free char *filename = NULL; + LoadDirInfo info = { 0 }; + + filename = g_build_filename (dirname, fn, NULL); + if (nm_vpn_plugin_info_check_file_full (filename, + FALSE, + do_validate_filename, + check_owner, + check_file, + user_data, + &info.stat, + NULL)) { + info.plugin_info = nm_vpn_plugin_info_new_from_file (filename, NULL); + if (info.plugin_info) { + g_array_append_val (array, info); + continue; + } + } + } + g_dir_close (dir); + + /* sort the files so that we have a stable behavior. The directory might contain + * duplicate VPNs, so while nm_vpn_plugin_info_list_load() would load them all, the + * caller probably wants to reject duplicates. Having a stable order means we always + * reject the same files in face of duplicates. */ + g_array_sort (array, (GCompareFunc) _sort_files); + + for (i = 0; i < array->len; i++) + res = g_slist_prepend (res, g_array_index (array, LoadDirInfo, i).plugin_info); + + g_array_unref (array); + + return g_slist_reverse (res); +} + +/** + * nm_vpn_plugin_info_list_load: + * + * Returns: (element-type NMVpnPluginInfo) (transfer full): list of plugins + * loaded from the default directories rejecting duplicates. + * + * Since: 1.2 + */ +GSList * +nm_vpn_plugin_info_list_load () +{ + int i; + gint64 uid; + GSList *list = NULL; + GSList *infos, *info; + const char *dir[] = { + /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with + * preference to the former. + * + * load user directory with highest priority. */ + _nm_vpn_plugin_info_get_default_dir_user (), + + /* lib directory has higher priority then etc. The reason is that + * etc is deprecated and used by old plugins. We expect newer plugins + * to install their file in lib, where they have higher priority. + * + * Optimally, there are no duplicates anyway, so it doesn't really matter. */ + _nm_vpn_plugin_info_get_default_dir_lib (), + _nm_vpn_plugin_info_get_default_dir_etc (), + }; + + uid = getuid (); + + for (i = 0; i < G_N_ELEMENTS (dir); i++) { + if ( !dir[i] + || _nm_utils_strv_find_first ((char **) dir, i, dir[i]) >= 0) + continue; + + infos = _nm_vpn_plugin_info_list_load_dir (dir[i], TRUE, uid, NULL, NULL); + + for (info = infos; info; info = info->next) + nm_vpn_plugin_info_list_add (&list, info->data, NULL); + + g_slist_free_full (infos, g_object_unref); + } + return list; +} + +/*********************************************************************/ + +static gboolean +_check_no_conflict (NMVpnPluginInfo *i1, NMVpnPluginInfo *i2, GError **error) +{ + NMVpnPluginInfoPrivate *priv1, *priv2; + uint i; + struct { + const char *group; + const char *key; + } check_list[] = { + { NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "service" }, + { NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM, "plugin" }, + { NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties" }, + }; + + priv1 = NM_VPN_PLUGIN_INFO_GET_PRIVATE (i1); + priv2 = NM_VPN_PLUGIN_INFO_GET_PRIVATE (i2); + + for (i = 0; i < G_N_ELEMENTS (check_list); i++) { + gs_free NMUtilsStrStrDictKey *k = NULL; + const char *s1, *s2; + + k = _nm_utils_strstrdictkey_create (check_list[i].group, check_list[i].key); + s1 = g_hash_table_lookup (priv1->keys, k); + if (!s1) + continue; + s2 = g_hash_table_lookup (priv2->keys, k); + if (!s2) + continue; + + if (strcmp (s1, s2) == 0) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("there exists a conflicting plugin (%s) that has the same %s.%s value"), + priv2->name, + check_list[i].group, check_list[i].key); + return FALSE; + } + } + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_add: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @plugin_info: instance to add + * @error: failure reason + * + * Returns: %TRUE if the plugin was added to @list. This will fail + * to add duplicate plugins. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_list_add (GSList **list, NMVpnPluginInfo *plugin_info, GError **error) +{ + GSList *iter; + const char *name; + + g_return_val_if_fail (list, FALSE); + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info), FALSE); + + name = nm_vpn_plugin_info_get_name (plugin_info); + for (iter = *list; iter; iter = iter->next) { + if (iter->data == plugin_info) + return TRUE; + + if (strcmp (nm_vpn_plugin_info_get_name (iter->data), name) == 0) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("there exists a conflicting plugin with the same name (%s)"), + name); + return FALSE; + } + + /* the plugin must have unique values for certain properties. E.g. two different + * plugins cannot share the same service name. */ + if (!_check_no_conflict (plugin_info, iter->data, error)) + return FALSE; + } + + *list = g_slist_append (*list, g_object_ref (plugin_info)); + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_remove: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @plugin_info: instance + * + * Remove @plugin_info from @list. + * + * Returns: %TRUE if @plugin_info was in @list and successfully removed. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_list_remove (GSList **list, NMVpnPluginInfo *plugin_info) +{ + g_return_val_if_fail (list, FALSE); + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info), FALSE); + + if (!g_slist_find (*list, plugin_info)) + return FALSE; + + *list = g_slist_remove (*list, plugin_info); + g_object_unref (plugin_info); + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_find_by_name: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @name: name to search + * + * Returns: (transfer none): the first plugin with a matching @name (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_name (GSList *list, const char *name) +{ + GSList *iter; + + if (!name) + g_return_val_if_reached (NULL); + + for (iter = list; iter; iter = iter->next) { + if (strcmp (nm_vpn_plugin_info_get_name (iter->data), name) == 0) + return iter->data; + } + return NULL; +} + +/** + * nm_vpn_plugin_info_list_find_by_filename: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @filename: filename to search + * + * Returns: (transfer none): the first plugin with a matching @filename (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename) +{ + GSList *iter; + + if (!filename) + g_return_val_if_reached (NULL); + + for (iter = list; iter; iter = iter->next) { + if (g_strcmp0 (nm_vpn_plugin_info_get_filename (iter->data), filename) == 0) + return iter->data; + } + return NULL; +} + +/** + * nm_vpn_plugin_info_list_find_by_service: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @service: service to search + * + * Returns: (transfer none): the first plugin with a matching @service (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service) +{ + GSList *iter; + + if (!service) + g_return_val_if_reached (NULL); + + /* First, consider the primary service name. */ + for (iter = list; iter; iter = iter->next) { + if (strcmp (NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data)->service, service) == 0) + return iter->data; + } + + /* Then look into the aliases. */ + for (iter = list; iter; iter = iter->next) { + char **aliases = (NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data))->aliases; + + if (!aliases) + continue; + if (_nm_utils_strv_find_first (aliases, -1, service) >= 0) + return iter->data; + } + return NULL; +} + +/*********************************************************************/ + +/** + * nm_vpn_plugin_info_get_filename: + * @self: plugin info instance + * + * Returns: (transfer none): the filename. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->filename; +} + +/** + * nm_vpn_plugin_info_get_name: + * @self: plugin info instance + * + * Returns: (transfer none): the name. Cannot be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->name; +} + +/** + * nm_vpn_plugin_info_get_plugin: + * @self: plugin info instance + * + * Returns: (transfer none): the plugin. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + return g_hash_table_lookup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keys, + _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM, "plugin")); +} + +/** + * nm_vpn_plugin_info_get_program: + * @self: plugin info instance + * + * Returns: (transfer none): the program. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + return g_hash_table_lookup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keys, + _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "program")); +} + +/** + * nm_vpn_plugin_info_supports_multiple: + * @self: plugin info instance + * + * Returns: %TRUE if the service supports multiple instances with different bus names, otherwise %FALSE + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE); + + return g_key_file_get_boolean (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keyfile, + NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, + "supports-multiple-connections", + NULL); +} + + +/** + * nm_vpn_plugin_info_lookup_property: + * @self: plugin info instance + * @group: group name + * @key: name of the property + * + * Returns: (transfer none): #NMVpnPluginInfo is internally a #GKeyFile. Returns the matching + * property. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key) +{ + NMVpnPluginInfoPrivate *priv; + gs_free NMUtilsStrStrDictKey *k = NULL; + + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + g_return_val_if_fail (group, NULL); + g_return_val_if_fail (key, NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + + k = _nm_utils_strstrdictkey_create (group, key); + return g_hash_table_lookup (priv->keys, k); +} + +/*********************************************************************/ + +/** + * nm_vpn_plugin_info_get_editor_plugin: + * @self: plugin info instance + * + * Returns: (transfer none): the cached #NMVpnEditorPlugin instance. + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *self) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->editor_plugin; +} + +/** + * nm_vpn_plugin_info_set_editor_plugin: + * @self: plugin info instance + * @plugin: (allow-none): plugin instance + * + * Set the internal plugin instance. If %NULL, only clear the previous instance. + * + * Since: 1.2 + */ +void +nm_vpn_plugin_info_set_editor_plugin (NMVpnPluginInfo *self, NMVpnEditorPlugin *plugin) +{ + NMVpnPluginInfoPrivate *priv; + NMVpnEditorPlugin *old; + + g_return_if_fail (NM_IS_VPN_PLUGIN_INFO (self)); + g_return_if_fail (!plugin || G_IS_OBJECT (plugin)); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + + if (!plugin) { + priv->editor_plugin_loaded = FALSE; + g_clear_object (&priv->editor_plugin); + } else { + old = priv->editor_plugin; + priv->editor_plugin = g_object_ref (plugin); + priv->editor_plugin_loaded = TRUE; + if (old) + g_object_unref (old); + } +} + +/** + * nm_vpn_plugin_info_load_editor_plugin: + * @self: plugin info instance + * @error: error reason on failure + * + * Returns: (transfer none): loads the plugin and returns the newly created + * instance. The plugin is owned by @self and can be later retrieved again + * via nm_vpn_plugin_info_get_editor_plugin(). You can load the + * plugin only once, unless you reset the state via + * nm_vpn_plugin_info_set_editor_plugin(). + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error) +{ + NMVpnPluginInfoPrivate *priv; + const char *plugin_filename; + + g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + + if (priv->editor_plugin) + return priv->editor_plugin; + + plugin_filename = nm_vpn_plugin_info_get_plugin (self); + if (!plugin_filename || !*plugin_filename) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("missing \"plugin\" setting")); + return NULL; + } + + /* We only try once to load the plugin. If we previously tried and it was + * unsuccessful, error out immediately. */ + if (priv->editor_plugin_loaded) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("%s: don't retry loading plugin which already failed previously"), priv->name); + return NULL; + } + + priv->editor_plugin_loaded = TRUE; + priv->editor_plugin = nm_vpn_editor_plugin_load_from_file (plugin_filename, + priv->service, + getuid (), + NULL, + NULL, + error); + return priv->editor_plugin; +} + +/*********************************************************************/ + +/** + * nm_vpn_plugin_info_new_from_file: + * @filename: filename to read. + * @error: on failure, the error reason. + * + * Read the plugin info from file @filename. Does not do + * any further verification on the file. You might want to check + * file permissions and ownership of the file. + * + * Returns: %NULL if there is any error or a newly created + * #NMVpnPluginInfo instance. + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_new_from_file (const char *filename, + GError **error) +{ + g_return_val_if_fail (filename, NULL); + + return NM_VPN_PLUGIN_INFO (g_initable_new (NM_TYPE_VPN_PLUGIN_INFO, + NULL, + error, + NM_VPN_PLUGIN_INFO_FILENAME, filename, + NULL)); +} + +/** + * nm_vpn_plugin_info_new_with_data: + * @filename: optional filename. + * @keyfile: inject data for the plugin info instance. + * @error: construction may fail if the keyfile lacks mandatory fields. + * In this case, return the error reason. + * + * This constructor does not read any data from file but + * takes instead a @keyfile argument. + * + * Returns: new plugin info instance. + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_new_with_data (const char *filename, + GKeyFile *keyfile, + GError **error) +{ + g_return_val_if_fail (keyfile, NULL); + + return NM_VPN_PLUGIN_INFO (g_initable_new (NM_TYPE_VPN_PLUGIN_INFO, + NULL, + error, + NM_VPN_PLUGIN_INFO_FILENAME, filename, + NM_VPN_PLUGIN_INFO_KEYFILE, keyfile, + NULL)); +} + +/*********************************************************************/ + +static void +nm_vpn_plugin_info_init (NMVpnPluginInfo *plugin) +{ +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (initable); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + gs_strfreev char **groups = NULL; + guint i, j; + + if (!priv->keyfile) { + if (!priv->filename) { + g_set_error_literal (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing filename to load VPN plugin info")); + return FALSE; + } + priv->keyfile = g_key_file_new (); + if (!g_key_file_load_from_file (priv->keyfile, priv->filename, G_KEY_FILE_NONE, error)) + return FALSE; + } + + /* we reqire at least a "name" */ + priv->name = g_key_file_get_string (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "name", NULL); + if (!priv->name || !priv->name[0]) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing name for VPN plugin info")); + return FALSE; + } + + /* we also require "service", because that how we associate NMSettingVpn:service-type with the + * NMVpnPluginInfo. */ + priv->service = g_key_file_get_string (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "service", NULL); + if (!priv->service || !*priv->service) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing service for VPN plugin info")); + return FALSE; + } + + priv->aliases = g_key_file_get_string_list (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "aliases", NULL, NULL); + + priv->keys = g_hash_table_new_full (_nm_utils_strstrdictkey_hash, + _nm_utils_strstrdictkey_equal, + g_free, g_free); + groups = g_key_file_get_groups (priv->keyfile, NULL); + for (i = 0; groups && groups[i]; i++) { + gs_strfreev char **keys = NULL; + + keys = g_key_file_get_keys (priv->keyfile, groups[i], NULL, NULL); + for (j = 0; keys && keys[j]; j++) { + char *s; + + /* Lookup the value via get_string(). We want that behavior. + * You could still lookup the original values via g_key_file_get_value() + * based on priv->keyfile. */ + s = g_key_file_get_string (priv->keyfile, groups[i], keys[j], NULL); + if (s) + g_hash_table_insert (priv->keys, _nm_utils_strstrdictkey_create (groups[i], keys[j]), s); + } + } + + return TRUE; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_FILENAME: + priv->filename = g_value_dup_string (value); + break; + case PROP_KEYFILE: + priv->keyfile = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_FILENAME: + g_value_set_string (value, priv->filename); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (object); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + + g_clear_object (&priv->editor_plugin); + + G_OBJECT_CLASS (nm_vpn_plugin_info_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (object); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self); + + g_free (priv->name); + g_free (priv->service); + g_strfreev (priv->aliases); + g_free (priv->filename); + g_key_file_unref (priv->keyfile); + g_hash_table_unref (priv->keys); + + G_OBJECT_CLASS (nm_vpn_plugin_info_parent_class)->finalize (object); +} + +static void +nm_vpn_plugin_info_class_init (NMVpnPluginInfoClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (plugin_class); + + g_type_class_add_private (object_class, sizeof (NMVpnPluginInfoPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /* properties */ + + /** + * NMVpnPluginInfo:name: + * + * The name of the VPN plugin. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_VPN_PLUGIN_INFO_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnPluginInfo:filename: + * + * The filename from which the info was loaded. + * Can be %NULL if the instance was not loaded from + * a file (i.e. the keyfile instance was passed to the + * constructor). + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_FILENAME, + g_param_spec_string (NM_VPN_PLUGIN_INFO_FILENAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnPluginInfo:keyfile: + * + * Initalize the instance with a different keyfile instance. + * When passing a keyfile instance, the constructor will not + * try to read from filename. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_KEYFILE, + g_param_spec_boxed (NM_VPN_PLUGIN_INFO_KEYFILE, "", "", + G_TYPE_KEY_FILE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +nm_vpn_plugin_info_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} + diff --git a/libnm-core/nm-vpn-plugin-info.h b/libnm-core/nm-vpn-plugin-info.h new file mode 100644 index 00000000..667a4fe2 --- /dev/null +++ b/libnm-core/nm-vpn-plugin-info.h @@ -0,0 +1,114 @@ +/* -*- 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 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_PLUGIN_INFO_H__ +#define __NM_VPN_PLUGIN_INFO_H__ + +#include <glib.h> +#include <glib-object.h> + +#include "nm-utils.h" +#include "nm-vpn-editor-plugin.h" + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_PLUGIN_INFO (nm_vpn_plugin_info_get_type ()) +#define NM_VPN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfo)) +#define NM_VPN_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass)) +#define NM_IS_VPN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_PLUGIN_INFO)) +#define NM_IS_VPN_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_PLUGIN_INFO)) +#define NM_VPN_PLUGIN_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass)) + +#define NM_VPN_PLUGIN_INFO_NAME "name" +#define NM_VPN_PLUGIN_INFO_FILENAME "filename" +#define NM_VPN_PLUGIN_INFO_KEYFILE "keyfile" + +#define NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION "VPN Connection" +#define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm" +#define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME" + +typedef struct { + NM_AVAILABLE_IN_1_2 + GObject parent; +} NMVpnPluginInfo; + +typedef struct { + NM_AVAILABLE_IN_1_2 + GObjectClass parent; + + /*< private >*/ + NM_AVAILABLE_IN_1_2 + gpointer padding[8]; +} NMVpnPluginInfoClass NM_AVAILABLE_IN_1_2; + +NM_AVAILABLE_IN_1_2 +GType nm_vpn_plugin_info_get_type (void); + +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_new_from_file (const char *filename, + GError **error); + +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_new_with_data (const char *filename, + GKeyFile *keyfile, + GError **error); + +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_validate_filename (const char *filename); + +NM_AVAILABLE_IN_1_2 +GSList *nm_vpn_plugin_info_list_load (void); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_list_add (GSList **list, NMVpnPluginInfo *plugin_info, GError **error); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_list_remove (GSList **list, NMVpnPluginInfo *plugin_info); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_name (GSList *list, const char *name); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service); + + +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +void nm_vpn_plugin_info_set_editor_plugin (NMVpnPluginInfo *self, + NMVpnEditorPlugin *plugin); +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, + GError **error); + +G_END_DECLS + +#endif /* __NM_VPN_PLUGIN_INFO_H__ */ diff --git a/libnm-core/tests/Makefile.am b/libnm-core/tests/Makefile.am index bcccfda9..92c816fd 100644 --- a/libnm-core/tests/Makefile.am +++ b/libnm-core/tests/Makefile.am @@ -1,5 +1,3 @@ -if ENABLE_TESTS - include $(GLIB_MAKEFILE) GLIB_GENERATED = nm-core-tests-enum-types.h nm-core-tests-enum-types.c @@ -9,11 +7,13 @@ GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM BUILT_SOURCES = $(GLIB_GENERATED) +if ENABLE_TESTS + certsdir = $(srcdir)/certs AM_CPPFLAGS = \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ + -I${top_srcdir}/shared \ + -I${top_builddir}/shared \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -DNETWORKMANAGER_COMPILATION \ diff --git a/libnm-core/tests/Makefile.in b/libnm-core/tests/Makefile.in index e46146a4..43892d75 100644 --- a/libnm-core/tests/Makefile.in +++ b/libnm-core/tests/Makefile.in @@ -460,7 +460,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CKDB_PATH = @CKDB_PATH@ CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ @@ -472,8 +471,6 @@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ @@ -483,6 +480,7 @@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ +DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -537,16 +535,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ +LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -583,6 +578,8 @@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@ +NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -611,7 +608,6 @@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ @@ -626,6 +622,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@ +SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ @@ -686,6 +684,7 @@ mkdir_p = @mkdir_p@ nmbinary = @nmbinary@ nmconfdir = @nmconfdir@ nmdatadir = @nmdatadir@ +nmlibdir = @nmlibdir@ nmrundir = @nmrundir@ nmstatedir = @nmstatedir@ oldincludedir = @oldincludedir@ @@ -693,6 +692,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -708,15 +708,15 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -@ENABLE_TESTS_TRUE@GLIB_GENERATED = nm-core-tests-enum-types.h nm-core-tests-enum-types.c -@ENABLE_TESTS_TRUE@nm_core_tests_enum_types_sources = test-general-enums.h -@ENABLE_TESTS_TRUE@GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM -@ENABLE_TESTS_TRUE@GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -@ENABLE_TESTS_TRUE@BUILT_SOURCES = $(GLIB_GENERATED) +GLIB_GENERATED = nm-core-tests-enum-types.h nm-core-tests-enum-types.c +nm_core_tests_enum_types_sources = test-general-enums.h +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +BUILT_SOURCES = $(GLIB_GENERATED) @ENABLE_TESTS_TRUE@certsdir = $(srcdir)/certs @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ -I${top_srcdir}/include \ -@ENABLE_TESTS_TRUE@ -I${top_builddir}/include \ +@ENABLE_TESTS_TRUE@ -I${top_srcdir}/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@ -DNETWORKMANAGER_COMPILATION \ @@ -1306,8 +1306,7 @@ uninstall-am: .PRECIOUS: Makefile - -@ENABLE_TESTS_TRUE@include $(GLIB_MAKEFILE) +include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@@VALGRIND_RULES@ diff --git a/libnm-core/tests/nm-core-tests-enum-types.c b/libnm-core/tests/nm-core-tests-enum-types.c index 80271e52..e6eaa60b 100644 --- a/libnm-core/tests/nm-core-tests-enum-types.c +++ b/libnm-core/tests/nm-core-tests-enum-types.c @@ -3,6 +3,8 @@ /* Generated by glib-mkenums. Do not edit */ +#include "config.h" + #include "nm-core-tests-enum-types.h" #include "test-general-enums.h" diff --git a/libnm-core/tests/test-compare.c b/libnm-core/tests/test-compare.c index 12db9c23..914330fe 100644 --- a/libnm-core/tests/test-compare.c +++ b/libnm-core/tests/test-compare.c @@ -24,8 +24,7 @@ #include <arpa/inet.h> #include <netinet/in.h> -#include "nm-glib-compat.h" - +#include "nm-default.h" #include "nm-property-compare.h" #include "nm-test-utils.h" diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c index e4ca8086..926cddb0 100644 --- a/libnm-core/tests/test-crypto.c +++ b/libnm-core/tests/test-crypto.c @@ -23,13 +23,12 @@ #include "config.h" -#include <glib.h> #include <unistd.h> #include <stdlib.h> -#include <glib/gi18n.h> #include <stdio.h> #include <string.h> +#include "nm-default.h" #include "crypto.h" #include "nm-utils.h" #include "nm-errors.h" diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 53d8195c..e8eb0baf 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -7,7 +7,7 @@ * 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 + * but WITHOUT SC WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * @@ -23,14 +23,14 @@ #include "config.h" -#include <glib.h> #include <string.h> #include <nm-utils.h> -#include "gsystem-local-alloc.h" +#include "nm-default.h" #include "nm-setting-private.h" #include "nm-utils.h" +#include "nm-utils-private.h" #include "nm-core-internal.h" #include "nm-core-tests-enum-types.h" @@ -60,11 +60,19 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" #include "nm-simple-connection.h" -#include "nm-glib-compat.h" +#include "nm-keyfile-internal.h" #include "nm-test-utils.h" #include "test-general-enums.h" +/* When passing a "bool" typed argument to a variadic function that + * expects a gboolean, the compiler will promote the integer type + * to have at least size (int). That way: + * g_object_set (obj, PROP_BOOL, bool_val, NULL); + * will just work correctly. */ +G_STATIC_ASSERT (sizeof (gboolean) == sizeof (int)); +G_STATIC_ASSERT (sizeof (bool) <= sizeof (int)); + static void vpn_check_func (const char *key, const char *value, gpointer user_data) { @@ -748,6 +756,35 @@ test_setting_gsm_without_number (void) NM_CONNECTION_ERROR_INVALID_PROPERTY); } +static void +test_setting_gsm_sim_operator_id (void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + g_assert (s_gsm); + + /* Valid */ + g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "12345", NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); + + g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "123456", NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); + + /* Invalid */ + g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "", NULL); + nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, " ", NULL); + nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "abcdef", NULL); + nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + static NMSettingWirelessSecurity * make_test_wsec_setting (const char *detail) { @@ -1972,6 +2009,7 @@ test_connection_diff_a_only (void) { NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_CONNECTION_METERED, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_LLDP, NM_SETTING_DIFF_RESULT_IN_A }, { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } } }, { NM_SETTING_WIRED_SETTING_NAME, { @@ -1994,6 +2032,7 @@ test_connection_diff_a_only (void) { NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DNS_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_GATEWAY, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, @@ -2001,8 +2040,10 @@ test_connection_diff_a_only (void) { NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP4_CONFIG_DHCP_FQDN, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A }, { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, @@ -2851,7 +2892,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip4, "11.22.0.0")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->dns->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip4, 1)); g_test_assert_expected_messages (); @@ -2861,7 +2902,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->dns_search->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 1)); g_test_assert_expected_messages (); @@ -2873,7 +2914,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip4, addr)); ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->addresses->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip4, 1)); g_test_assert_expected_messages (); @@ -2886,13 +2927,20 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip4, route)); ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->routes->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip4, 1)); g_test_assert_expected_messages (); nm_setting_ip_config_add_route (s_ip4, route); ASSERT_CHANGED (nm_setting_ip_config_clear_routes (s_ip4)); + ASSERT_CHANGED (nm_setting_ip_config_add_dns_option (s_ip4, "debug")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns_option (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->dns_options->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_option (s_ip4, 1)); + g_test_assert_expected_messages (); + nm_ip_address_unref (addr); nm_ip_route_unref (route); g_object_unref (connection); @@ -2920,7 +2968,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->dns->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip6, 1)); g_test_assert_expected_messages (); @@ -2930,7 +2978,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->dns_search->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 1)); g_test_assert_expected_messages (); @@ -2943,7 +2991,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip6, addr)); ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->addresses->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip6, 1)); g_test_assert_expected_messages (); @@ -2956,7 +3004,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip6, route)); ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < priv->routes->len*"); ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip6, 1)); g_test_assert_expected_messages (); @@ -3964,6 +4012,51 @@ typedef struct { } HexItem; static void +test_setting_compare_default_strv (void) +{ + gs_unref_object NMConnection *c1 = NULL, *c2 = NULL; + char **strv; + NMSettingIPConfig *s_ip2, *s_ip1; + gboolean compare; + GHashTable *out_settings = NULL; + + c1 = nmtst_create_minimal_connection ("test_compare_default_strv", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + nmtst_assert_connection_verifies_and_normalizable (c1); + + c2 = nm_simple_connection_new_clone (c1); + nmtst_assert_connection_verifies_without_normalization (c2); + + nmtst_assert_connection_equals (c1, FALSE, c2, FALSE); + + s_ip1 = nm_connection_get_setting_ip4_config (c1); + s_ip2 = nm_connection_get_setting_ip4_config (c2); + + nm_setting_ip_config_clear_dns_options (s_ip2, FALSE); + g_object_get (G_OBJECT (s_ip2), NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert (!strv); + nmtst_assert_connection_equals (c1, FALSE, c2, FALSE); + + nm_setting_ip_config_clear_dns_options (s_ip2, TRUE); + g_object_get (G_OBJECT (s_ip2), NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert (strv && !strv[0]); + g_strfreev (strv); + + compare = nm_setting_diff ((NMSetting *) s_ip1, (NMSetting *) s_ip2, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, &out_settings); + g_assert (!compare); + g_assert (out_settings); + g_assert (g_hash_table_contains (out_settings, NM_SETTING_IP_CONFIG_DNS_OPTIONS)); + g_hash_table_unref (out_settings); + out_settings = NULL; + + compare = nm_connection_diff (c1, c2, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings); + g_assert (!compare); + g_assert (out_settings); + g_hash_table_unref (out_settings); + out_settings = NULL; +} + +static void test_hexstr2bin (void) { static const HexItem items[] = { @@ -4227,6 +4320,138 @@ test_nm_utils_ascii_str_to_int64 (void) /******************************************************************************/ +static void +test_nm_utils_strstrdictkey (void) +{ +#define _VALUES_STATIC(_v1, _v2) { .v1 = _v1, .v2 = _v2, .v_static = _nm_utils_strstrdictkey_static (_v1, _v2), } + const struct { + const char *v1; + const char *v2; + NMUtilsStrStrDictKey *v_static; + } *val1, *val2, values[] = { + { NULL, NULL }, + { "", NULL }, + { NULL, "" }, + { "a", NULL }, + { NULL, "a" }, + _VALUES_STATIC ("", ""), + _VALUES_STATIC ("a", ""), + _VALUES_STATIC ("", "a"), + _VALUES_STATIC ("a", "b"), + }; + guint i, j; + + for (i = 0; i < G_N_ELEMENTS (values); i++) { + gs_free NMUtilsStrStrDictKey *key1 = NULL; + + val1 = &values[i]; + + key1 = _nm_utils_strstrdictkey_create (val1->v1, val1->v2); + if (val1->v_static) { + g_assert (_nm_utils_strstrdictkey_equal (key1, val1->v_static)); + g_assert (_nm_utils_strstrdictkey_equal (val1->v_static, key1)); + g_assert_cmpint (_nm_utils_strstrdictkey_hash (key1), ==, _nm_utils_strstrdictkey_hash (val1->v_static)); + } + + for (j = 0; j < G_N_ELEMENTS (values); j++) { + gs_free NMUtilsStrStrDictKey *key2 = NULL; + + val2 = &values[j]; + key2 = _nm_utils_strstrdictkey_create (val2->v1, val2->v2); + if (i != j) { + g_assert (!_nm_utils_strstrdictkey_equal (key1, key2)); + g_assert (!_nm_utils_strstrdictkey_equal (key2, key1)); + } + } + } +} + +/******************************************************************************/ + +static void +test_nm_utils_dns_option_validate_do (char *option, gboolean ipv6, const NMUtilsDNSOptionDesc *descs, + gboolean exp_result, char *exp_name, gboolean exp_value) +{ + char *name; + long value = 0; + gboolean result; + + result = _nm_utils_dns_option_validate (option, &name, &value, ipv6, descs); + + g_assert (result == exp_result); + g_assert_cmpstr (name, ==, exp_name); + g_assert (value == exp_value); + + g_free (name); +} + +static const NMUtilsDNSOptionDesc opt_descs[] = { + /* name num ipv6 */ + { "opt1", FALSE, FALSE }, + { "opt2", TRUE, FALSE }, + { "opt3", FALSE, TRUE }, + { "opt4", TRUE, TRUE }, + { NULL, FALSE, FALSE } +}; + +static void +test_nm_utils_dns_option_validate (void) +{ + /* opt ipv6 descs result name value */ + test_nm_utils_dns_option_validate_do ("", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do (":", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do (":1", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do (":val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt", FALSE, NULL, TRUE, "opt", -1); + test_nm_utils_dns_option_validate_do ("opt:", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt:12", FALSE, NULL, TRUE, "opt", 12); + test_nm_utils_dns_option_validate_do ("opt:12 ", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt:val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt:2val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt:2:3", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt-6", FALSE, NULL, TRUE, "opt-6", -1); + + test_nm_utils_dns_option_validate_do ("opt1", FALSE, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do ("opt1", TRUE, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do ("opt1:3", FALSE, opt_descs, FALSE, NULL, -1); + + test_nm_utils_dns_option_validate_do ("opt2", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt2:5", FALSE, opt_descs, TRUE, "opt2", 5); + + test_nm_utils_dns_option_validate_do ("opt3", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt3", TRUE, opt_descs, TRUE, "opt3", -1); + + test_nm_utils_dns_option_validate_do ("opt4", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt4", TRUE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt4:40", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do ("opt4:40", TRUE, opt_descs, TRUE, "opt4", 40); +} + +static void +test_nm_utils_dns_option_find_idx (void) +{ + GPtrArray *options; + + options = g_ptr_array_new (); + + g_ptr_array_add (options, "debug"); + g_ptr_array_add (options, "timeout:5"); + g_ptr_array_add (options, "edns0"); + + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "debug"), ==, 0); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "debug:1"), ==, 0); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "timeout"), ==, 1); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "timeout:5"), ==, 1); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "timeout:2"), ==, 1); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "edns0"), ==, 2); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, "rotate"), ==, -1); + g_assert_cmpint (_nm_utils_dns_option_find_idx (options, ""), ==, -1); + + g_ptr_array_free (options, TRUE); +} + +/******************************************************************************/ + enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED { _DUMMY_1 = -1, }; @@ -4349,6 +4574,41 @@ test_g_ptr_array_insert (void) /******************************************************************************/ +static void +test_g_hash_table_get_keys_as_array (void) +{ + GHashTable *table = g_hash_table_new (g_str_hash, g_str_equal); + guint length = 0; + char **keys; + + g_hash_table_insert (table, "one", "1"); + g_hash_table_insert (table, "two", "2"); + g_hash_table_insert (table, "three", "3"); + + keys = (char **) _nm_g_hash_table_get_keys_as_array (table, &length); + g_assert (keys); + g_assert_cmpuint (length, ==, 3); + + g_assert ( !strcmp (keys[0], "one") + || !strcmp (keys[1], "one") + || !strcmp (keys[2], "one")); + + g_assert ( !strcmp (keys[0], "two") + || !strcmp (keys[1], "two") + || !strcmp (keys[2], "two")); + + g_assert ( !strcmp (keys[0], "three") + || !strcmp (keys[1], "three") + || !strcmp (keys[2], "three")); + + g_assert (!keys[3]); + + g_free (keys); + g_hash_table_unref (table); +} + +/******************************************************************************/ + static int _test_find_binary_search_cmp (gconstpointer a, gconstpointer b, gpointer dummy) { @@ -4452,6 +4712,101 @@ test_nm_utils_ptrarray_find_binary_search (void) } /******************************************************************************/ +static void +test_nm_utils_enum_from_str_do (GType type, const char *str, + gboolean exp_result, int exp_flags, + const char *exp_err_token) +{ + int flags = 1; + char *err_token = NULL; + gboolean result; + + result = nm_utils_enum_from_str (type, str, &flags, &err_token); + + g_assert (result == exp_result); + g_assert_cmpint (flags, ==, exp_flags); + g_assert_cmpstr (err_token, ==, exp_err_token); + + g_free (err_token); +} + +static void +test_nm_utils_enum_to_str_do (GType type, int flags, const char *exp_str) +{ + char *str; + + str = nm_utils_enum_to_str (type, flags); + g_assert_cmpstr (str, ==, exp_str); + g_free (str); +} + +static void +test_nm_utils_enum_get_values_do (GType type, int from, int to, const char *exp_str) +{ + const char **strv; + char *str; + + strv = nm_utils_enum_get_values (type, from, to); + g_assert (strv); + str = g_strjoinv (",", (char **) strv); + g_assert_cmpstr (str, ==, exp_str); + g_free (str); + g_free (strv); +} + + +static void test_nm_utils_enum (void) +{ + GType bool_enum = nm_test_general_bool_enum_get_type(); + GType meta_flags = nm_test_general_meta_flags_get_type(); + GType color_flags = nm_test_general_color_flags_get_type(); + + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, "yes"); + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN, "unknown"); + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, NULL); + + test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_NONE, ""); + test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_BAZ, "baz"); + test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_FOO | + NM_TEST_GENERAL_META_FLAGS_BAR | + NM_TEST_GENERAL_META_FLAGS_BAZ, "foo, bar, baz"); + + test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED, "red"); + test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, ""); + test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED | + NM_TEST_GENERAL_COLOR_FLAGS_GREEN, "red, green"); + + test_nm_utils_enum_from_str_do (bool_enum, "", FALSE, 0, NULL); + test_nm_utils_enum_from_str_do (bool_enum, " ", FALSE, 0, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "invalid", FALSE, 0, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "yes", TRUE, NM_TEST_GENERAL_BOOL_ENUM_YES, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "no", TRUE, NM_TEST_GENERAL_BOOL_ENUM_NO, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "yes,no", FALSE, 0, NULL); + + test_nm_utils_enum_from_str_do (meta_flags, "", TRUE, 0, NULL); + test_nm_utils_enum_from_str_do (meta_flags, " ", TRUE, 0, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "foo", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "foo,baz", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | + NM_TEST_GENERAL_META_FLAGS_BAZ, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "foo, baz", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | + NM_TEST_GENERAL_META_FLAGS_BAZ, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "foo,,bar", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | + NM_TEST_GENERAL_META_FLAGS_BAR, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "foo,baz,quux,bar", FALSE, 0, "quux"); + + test_nm_utils_enum_from_str_do (color_flags, "green", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_GREEN, NULL); + test_nm_utils_enum_from_str_do (color_flags, "blue,red", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_BLUE | + NM_TEST_GENERAL_COLOR_FLAGS_RED, NULL); + test_nm_utils_enum_from_str_do (color_flags, "blue,white", FALSE, 0, "white"); + + test_nm_utils_enum_get_values_do (bool_enum, 0, G_MAXINT, "no,yes,maybe,unknown"); + test_nm_utils_enum_get_values_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, + NM_TEST_GENERAL_BOOL_ENUM_MAYBE, "yes,maybe"); + test_nm_utils_enum_get_values_do (meta_flags, 0, G_MAXINT, "none,foo,bar,baz"); + test_nm_utils_enum_get_values_do (color_flags, 0, G_MAXINT, "blue,red,green"); +} + +/******************************************************************************/ static int _test_nm_in_set_get (int *call_counter, gboolean allow_called, int value) @@ -4540,81 +4895,6 @@ test_nm_in_set (void) /******************************************************************************/ -static void -test_nm_utils_enum_from_str_do (GType type, const char *str, - gboolean exp_result, int exp_flags, - const char *exp_err_token) -{ - int flags = 1; - char *err_token = NULL; - gboolean result; - - result = nm_utils_enum_from_str (type, str, &flags, &err_token); - - g_assert (result == exp_result); - g_assert_cmpint (flags, ==, exp_flags); - g_assert_cmpstr (err_token, ==, exp_err_token); - - g_free (err_token); -} - -static void -test_nm_utils_enum_to_str_do (GType type, int flags, const char *exp_str) -{ - char *str; - - str = nm_utils_enum_to_str (type, flags); - g_assert_cmpstr (str, ==, exp_str); - g_free (str); -} - -static void test_nm_utils_enum (void) -{ - GType bool_enum = nm_test_general_bool_enum_get_type(); - GType meta_flags = nm_test_general_meta_flags_get_type(); - GType color_flags = nm_test_general_color_flags_get_type(); - - test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, "yes"); - test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN, "unknown"); - test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, NULL); - - test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_NONE, ""); - test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_BAZ, "baz"); - test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_FOO | - NM_TEST_GENERAL_META_FLAGS_BAR | - NM_TEST_GENERAL_META_FLAGS_BAZ, "foo, bar, baz"); - - test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED, "red"); - test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, ""); - test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED | - NM_TEST_GENERAL_COLOR_FLAGS_GREEN, "red, green"); - - test_nm_utils_enum_from_str_do (bool_enum, "", FALSE, 0, NULL); - test_nm_utils_enum_from_str_do (bool_enum, " ", FALSE, 0, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "invalid", FALSE, 0, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "yes", TRUE, NM_TEST_GENERAL_BOOL_ENUM_YES, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "no", TRUE, NM_TEST_GENERAL_BOOL_ENUM_NO, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "yes,no", FALSE, 0, NULL); - - test_nm_utils_enum_from_str_do (meta_flags, "", TRUE, 0, NULL); - test_nm_utils_enum_from_str_do (meta_flags, " ", TRUE, 0, NULL); - test_nm_utils_enum_from_str_do (meta_flags, "foo", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO, NULL); - test_nm_utils_enum_from_str_do (meta_flags, "foo,baz", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | - NM_TEST_GENERAL_META_FLAGS_BAZ, NULL); - test_nm_utils_enum_from_str_do (meta_flags, "foo, baz", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | - NM_TEST_GENERAL_META_FLAGS_BAZ, NULL); - test_nm_utils_enum_from_str_do (meta_flags, "foo,,bar", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | - NM_TEST_GENERAL_META_FLAGS_BAR, NULL); - test_nm_utils_enum_from_str_do (meta_flags, "foo,baz,quux,bar", FALSE, 0, "quux"); - - test_nm_utils_enum_from_str_do (color_flags, "green", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_GREEN, NULL); - test_nm_utils_enum_from_str_do (color_flags, "blue,red", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_BLUE | - NM_TEST_GENERAL_COLOR_FLAGS_RED, NULL); - test_nm_utils_enum_from_str_do (color_flags, "blue,white", FALSE, 0, "white"); -} - -/******************************************************************************/ - NMTST_DEFINE (); int main (int argc, char **argv) @@ -4632,6 +4912,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars); g_test_add_func ("/core/general/test_setting_gsm_apn_underscore", test_setting_gsm_apn_underscore); g_test_add_func ("/core/general/test_setting_gsm_without_number", test_setting_gsm_without_number); + g_test_add_func ("/core/general/test_setting_gsm_sim_operator_id", test_setting_gsm_sim_operator_id); g_test_add_func ("/core/general/test_setting_to_dbus_all", test_setting_to_dbus_all); g_test_add_func ("/core/general/test_setting_to_dbus_no_secrets", test_setting_to_dbus_no_secrets); g_test_add_func ("/core/general/test_setting_to_dbus_only_secrets", test_setting_to_dbus_only_secrets); @@ -4710,6 +4991,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/test_setting_802_1x_changed_signal", test_setting_802_1x_changed_signal); g_test_add_func ("/core/general/test_setting_ip4_gateway", test_setting_ip4_gateway); g_test_add_func ("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway); + g_test_add_func ("/core/general/test_setting_compare_default_strv", test_setting_compare_default_strv); g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin); g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string); @@ -4718,7 +5000,12 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64); g_test_add_func ("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two); g_test_add_func ("/core/general/_glib_compat_g_ptr_array_insert", test_g_ptr_array_insert); + g_test_add_func ("/core/general/_glib_compat_g_hash_table_get_keys_as_array", test_g_hash_table_get_keys_as_array); g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search); + g_test_add_func ("/core/general/_nm_utils_strstrdictkey", test_nm_utils_strstrdictkey); + + g_test_add_func ("/core/general/_nm_utils_dns_option_validate", test_nm_utils_dns_option_validate); + g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx); g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum); diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c index 178fddd5..4c0c7f5d 100644 --- a/libnm-core/tests/test-secrets.c +++ b/libnm-core/tests/test-secrets.c @@ -21,9 +21,9 @@ #include "config.h" -#include <glib.h> #include <string.h> +#include "nm-default.h" #include "nm-setting-8021x.h" #include "nm-setting-cdma.h" #include "nm-setting-connection.h" diff --git a/libnm-core/tests/test-setting-8021x.c b/libnm-core/tests/test-setting-8021x.c index 16f6016e..49d7448e 100644 --- a/libnm-core/tests/test-setting-8021x.c +++ b/libnm-core/tests/test-setting-8021x.c @@ -21,11 +21,11 @@ #include "config.h" -#include <glib.h> #include <string.h> #include <nm-utils.h> +#include "nm-default.h" #include "nm-setting-connection.h" #include "nm-setting-8021x.h" diff --git a/libnm-core/tests/test-setting-dcb.c b/libnm-core/tests/test-setting-dcb.c index f7554e81..f8b789c1 100644 --- a/libnm-core/tests/test-setting-dcb.c +++ b/libnm-core/tests/test-setting-dcb.c @@ -21,14 +21,14 @@ #include "config.h" -#include <glib.h> #include <string.h> #include <nm-utils.h> -#include <nm-glib-compat.h> +#include "nm-default.h" #include "nm-setting-dcb.h" #include "nm-connection.h" #include "nm-errors.h" -#include "gsystem-local-alloc.h" + +#include "nm-test-utils.h" #define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \ NM_SETTING_DCB_FLAG_ADVERTISE | \ @@ -303,18 +303,12 @@ test_dcb_bandwidth_sums (void) #define TPATH "/libnm/settings/dcb/" +NMTST_DEFINE (); + int main (int argc, char **argv) { - g_test_init (&argc, &argv, NULL); - -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - -#if !GLIB_CHECK_VERSION(2,34,0) - g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); -#endif + nmtst_init (&argc, &argv, TRUE); g_test_add_func (TPATH "flags-valid", test_dcb_flags_valid); g_test_add_func (TPATH "flags-invalid", test_dcb_flags_invalid); diff --git a/libnm-core/tests/test-settings-defaults.c b/libnm-core/tests/test-settings-defaults.c index 7d7715cb..21e16f3d 100644 --- a/libnm-core/tests/test-settings-defaults.c +++ b/libnm-core/tests/test-settings-defaults.c @@ -21,11 +21,11 @@ #include "config.h" -#include <glib.h> #include <string.h> #include <nm-utils.h> +#include "nm-default.h" #include "nm-setting-8021x.h" #include "nm-setting-cdma.h" #include "nm-setting-connection.h" |