From 494f296a3baab08522617b24b1f126d8f9a17502 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 20 Jan 2016 16:26:51 +0100 Subject: Imported Upstream version 1.1.90 --- libnm/Makefile.am | 26 +- libnm/Makefile.in | 91 +- libnm/NetworkManager.h | 6 + libnm/libnm.pc.in | 1 + libnm/libnm.ver | 204 ++++- libnm/nm-access-point.c | 13 +- libnm/nm-access-point.h | 2 +- libnm/nm-active-connection.c | 2 +- libnm/nm-client.c | 114 ++- libnm/nm-client.h | 9 +- libnm/nm-dbus-helpers.c | 242 ++---- libnm/nm-dbus-helpers.h | 13 +- libnm/nm-device-adsl.c | 1 - libnm/nm-device-bond.c | 4 +- libnm/nm-device-bridge.c | 4 +- libnm/nm-device-bt.c | 4 +- libnm/nm-device-ethernet.c | 141 +++- libnm/nm-device-ethernet.h | 3 + libnm/nm-device-generic.c | 1 - libnm/nm-device-infiniband.c | 4 +- libnm/nm-device-ip-tunnel.c | 544 ++++++++++++ libnm/nm-device-ip-tunnel.h | 90 ++ libnm/nm-device-macvlan.c | 347 ++++++++ libnm/nm-device-macvlan.h | 72 ++ libnm/nm-device-modem.c | 4 +- libnm/nm-device-olpc-mesh.c | 4 +- libnm/nm-device-team.c | 4 +- libnm/nm-device-tun.c | 439 ++++++++++ libnm/nm-device-tun.h | 78 ++ libnm/nm-device-vlan.c | 4 +- libnm/nm-device-vxlan.c | 815 ++++++++++++++++++ libnm/nm-device-vxlan.h | 110 +++ libnm/nm-device-wifi.c | 17 +- libnm/nm-device-wifi.h | 4 +- libnm/nm-device-wimax.c | 40 +- libnm/nm-device-wimax.h | 10 + libnm/nm-device.c | 573 ++++++++++++- libnm/nm-device.h | 51 +- libnm/nm-enum-types.c | 32 +- libnm/nm-enum-types.h | 2 - libnm/nm-ifcfg-rh-docs.xml | 21 +- libnm/nm-ip-config.c | 7 +- libnm/nm-keyfile-docs.xml | 8 + libnm/nm-manager.c | 102 ++- libnm/nm-manager.h | 5 + libnm/nm-object-cache.c | 2 +- libnm/nm-object-cache.h | 3 +- libnm/nm-object-private.h | 2 +- libnm/nm-object.c | 201 +++-- libnm/nm-property-docs.xml | 79 +- libnm/nm-remote-connection.c | 4 +- libnm/nm-remote-settings.c | 8 +- libnm/nm-secret-agent-old.c | 2 +- libnm/nm-setting-docs-overrides.xml | 8 + libnm/nm-setting-docs.xml | 79 +- libnm/nm-types.h | 4 + libnm/nm-vpn-editor-plugin.c | 181 ---- libnm/nm-vpn-editor-plugin.h | 189 ----- libnm/nm-vpn-editor.c | 69 ++ libnm/nm-vpn-editor.h | 86 ++ libnm/nm-vpn-plugin-old.c | 88 +- libnm/nm-vpn-plugin-old.h | 36 +- libnm/nm-vpn-service-plugin.c | 1302 +++++++++++++++++++++++++++++ libnm/nm-vpn-service-plugin.h | 160 ++++ libnm/nm-wimax-nsp.c | 3 +- libnm/tests/Makefile.am | 18 +- libnm/tests/Makefile.in | 72 +- libnm/tests/common.c | 187 ----- libnm/tests/common.h | 37 - libnm/tests/test-nm-client.c | 380 ++++++++- libnm/tests/test-remote-settings-client.c | 21 +- libnm/tests/test-secret-agent.c | 34 +- 72 files changed, 6334 insertions(+), 1189 deletions(-) create mode 100644 libnm/nm-device-ip-tunnel.c create mode 100644 libnm/nm-device-ip-tunnel.h create mode 100644 libnm/nm-device-macvlan.c create mode 100644 libnm/nm-device-macvlan.h create mode 100644 libnm/nm-device-tun.c create mode 100644 libnm/nm-device-tun.h create mode 100644 libnm/nm-device-vxlan.c create mode 100644 libnm/nm-device-vxlan.h delete mode 100644 libnm/nm-vpn-editor-plugin.c delete mode 100644 libnm/nm-vpn-editor-plugin.h create mode 100644 libnm/nm-vpn-editor.c create mode 100644 libnm/nm-vpn-editor.h create mode 100644 libnm/nm-vpn-service-plugin.c create mode 100644 libnm/nm-vpn-service-plugin.h delete mode 100644 libnm/tests/common.c delete mode 100644 libnm/tests/common.h (limited to 'libnm') diff --git a/libnm/Makefile.am b/libnm/Makefile.am index fec008a0..80cdccb0 100644 --- a/libnm/Makefile.am +++ b/libnm/Makefile.am @@ -3,15 +3,15 @@ include $(GLIB_MAKEFILE) SUBDIRS = . tests AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ + -I$(top_srcdir)/shared \ + -I$(top_builddir)/shared \ -I$(top_builddir)/introspection \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/libnm \ -I$(top_builddir)/libnm \ -DG_LOG_DOMAIN=\""libnm"\" \ - -DNETWORKMANAGER_COMPILATION \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(GUDEV_CFLAGS) \ @@ -26,7 +26,7 @@ lib_LTLIBRARIES = libnm.la libnmincludedir = $(includedir)/libnm libnminclude_hfiles = \ - $(top_builddir)/include/nm-version-macros.h \ + $(top_builddir)/shared/nm-version-macros.h \ NetworkManager.h \ nm-access-point.h \ nm-active-connection.h \ @@ -38,10 +38,14 @@ libnminclude_hfiles = \ nm-device-ethernet.h \ nm-device-generic.h \ nm-device-infiniband.h \ + nm-device-ip-tunnel.h \ + nm-device-macvlan.h \ nm-device-modem.h \ nm-device-olpc-mesh.h \ nm-device-team.h \ + nm-device-tun.h \ nm-device-vlan.h \ + nm-device-vxlan.h \ nm-device-wifi.h \ nm-device-wimax.h \ nm-device.h \ @@ -52,12 +56,13 @@ libnminclude_hfiles = \ nm-remote-connection.h \ nm-types.h \ nm-vpn-connection.h \ - nm-vpn-editor-plugin.h \ + nm-vpn-editor.h \ nm-wimax-nsp.h libnminclude_nointrospect_hfiles = \ nm-secret-agent-old.h \ - nm-vpn-plugin-old.h + nm-vpn-plugin-old.h \ + nm-vpn-service-plugin.h libnminclude_HEADERS = \ $(libnminclude_hfiles) \ @@ -88,10 +93,14 @@ libnm_la_csources = \ nm-device-ethernet.c \ nm-device-generic.c \ nm-device-infiniband.c \ + nm-device-ip-tunnel.c \ + nm-device-macvlan.c \ nm-device-modem.c \ nm-device-olpc-mesh.c \ nm-device-team.c \ + nm-device-tun.c \ nm-device-vlan.c \ + nm-device-vxlan.c \ nm-device-wifi.c \ nm-device-wimax.c \ nm-device.c \ @@ -110,7 +119,8 @@ libnm_la_csources = \ nm-secret-agent-old.c \ nm-vpn-connection.c \ nm-vpn-plugin-old.c \ - nm-vpn-editor-plugin.c \ + nm-vpn-editor.c \ + nm-vpn-service-plugin.c \ nm-wimax-nsp.c libnm_la_SOURCES = \ @@ -132,7 +142,7 @@ libnm_la_LIBADD = \ SYMBOL_VIS_FILE=$(srcdir)/libnm.ver libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "0:0:0" + -version-info "1:0:1" ### diff --git a/libnm/Makefile.in b/libnm/Makefile.in index fe710af7..6e7fcd42 100644 --- a/libnm/Makefile.in +++ b/libnm/Makefile.in @@ -161,15 +161,17 @@ am__objects_1 = nm-access-point.lo nm-active-connection.lo \ nm-client.lo nm-dbus-helpers.lo nm-device-adsl.lo \ nm-device-bond.lo nm-device-bridge.lo nm-device-bt.lo \ nm-device-ethernet.lo nm-device-generic.lo \ - nm-device-infiniband.lo nm-device-modem.lo \ - nm-device-olpc-mesh.lo nm-device-team.lo nm-device-vlan.lo \ - nm-device-wifi.lo nm-device-wimax.lo nm-device.lo \ - nm-dhcp-config.lo nm-dhcp4-config.lo nm-dhcp6-config.lo \ - nm-enum-types.lo nm-ip-config.lo nm-ip4-config.lo \ - nm-ip6-config.lo nm-manager.lo nm-object-cache.lo nm-object.lo \ - nm-remote-connection.lo nm-remote-settings.lo \ - nm-secret-agent-old.lo nm-vpn-connection.lo \ - nm-vpn-plugin-old.lo nm-vpn-editor-plugin.lo nm-wimax-nsp.lo + nm-device-infiniband.lo nm-device-ip-tunnel.lo \ + nm-device-macvlan.lo nm-device-modem.lo nm-device-olpc-mesh.lo \ + nm-device-team.lo nm-device-tun.lo nm-device-vlan.lo \ + nm-device-vxlan.lo nm-device-wifi.lo nm-device-wimax.lo \ + nm-device.lo nm-dhcp-config.lo nm-dhcp4-config.lo \ + nm-dhcp6-config.lo nm-enum-types.lo nm-ip-config.lo \ + nm-ip4-config.lo nm-ip6-config.lo nm-manager.lo \ + nm-object-cache.lo nm-object.lo nm-remote-connection.lo \ + nm-remote-settings.lo nm-secret-agent-old.lo \ + nm-vpn-connection.lo nm-vpn-plugin-old.lo nm-vpn-editor.lo \ + nm-vpn-service-plugin.lo nm-wimax-nsp.lo am__objects_2 = am_libnm_la_OBJECTS = $(am__objects_1) $(am__objects_2) libnm_la_OBJECTS = $(am_libnm_la_OBJECTS) @@ -303,7 +305,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@ @@ -315,8 +316,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@ @@ -326,6 +325,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@ @@ -380,16 +380,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@ @@ -426,6 +423,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@ @@ -454,7 +453,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@ @@ -469,6 +467,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@ @@ -529,6 +529,7 @@ mkdir_p = @mkdir_p@ nmbinary = @nmbinary@ nmconfdir = @nmconfdir@ nmdatadir = @nmdatadir@ +nmlibdir = @nmlibdir@ nmrundir = @nmrundir@ nmstatedir = @nmstatedir@ oldincludedir = @oldincludedir@ @@ -536,6 +537,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -553,15 +555,15 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ + -I$(top_srcdir)/shared \ + -I$(top_builddir)/shared \ -I$(top_builddir)/introspection \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/libnm \ -I$(top_builddir)/libnm \ -DG_LOG_DOMAIN=\""libnm"\" \ - -DNETWORKMANAGER_COMPILATION \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(GUDEV_CFLAGS) \ @@ -570,7 +572,7 @@ AM_CPPFLAGS = \ 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 \ @@ -589,16 +591,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 \ @@ -607,12 +613,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 \ @@ -623,6 +632,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 \ @@ -641,30 +651,36 @@ 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 # libnm lib_LTLIBRARIES = libnm.la libnmincludedir = $(includedir)/libnm libnminclude_hfiles = \ - $(top_builddir)/include/nm-version-macros.h \ + $(top_builddir)/shared/nm-version-macros.h \ NetworkManager.h \ nm-access-point.h \ nm-active-connection.h \ @@ -676,10 +692,14 @@ libnminclude_hfiles = \ nm-device-ethernet.h \ nm-device-generic.h \ nm-device-infiniband.h \ + nm-device-ip-tunnel.h \ + nm-device-macvlan.h \ nm-device-modem.h \ nm-device-olpc-mesh.h \ nm-device-team.h \ + nm-device-tun.h \ nm-device-vlan.h \ + nm-device-vxlan.h \ nm-device-wifi.h \ nm-device-wimax.h \ nm-device.h \ @@ -690,12 +710,13 @@ libnminclude_hfiles = \ nm-remote-connection.h \ nm-types.h \ nm-vpn-connection.h \ - nm-vpn-editor-plugin.h \ + nm-vpn-editor.h \ nm-wimax-nsp.h libnminclude_nointrospect_hfiles = \ nm-secret-agent-old.h \ - nm-vpn-plugin-old.h + nm-vpn-plugin-old.h \ + nm-vpn-service-plugin.h libnminclude_HEADERS = \ $(libnminclude_hfiles) \ @@ -726,10 +747,14 @@ libnm_la_csources = \ nm-device-ethernet.c \ nm-device-generic.c \ nm-device-infiniband.c \ + nm-device-ip-tunnel.c \ + nm-device-macvlan.c \ nm-device-modem.c \ nm-device-olpc-mesh.c \ nm-device-team.c \ + nm-device-tun.c \ nm-device-vlan.c \ + nm-device-vxlan.c \ nm-device-wifi.c \ nm-device-wimax.c \ nm-device.c \ @@ -748,7 +773,8 @@ libnm_la_csources = \ nm-secret-agent-old.c \ nm-vpn-connection.c \ nm-vpn-plugin-old.c \ - nm-vpn-editor-plugin.c \ + nm-vpn-editor.c \ + nm-vpn-service-plugin.c \ nm-wimax-nsp.c libnm_la_SOURCES = \ @@ -768,7 +794,7 @@ libnm_la_LIBADD = \ SYMBOL_VIS_FILE = $(srcdir)/libnm.ver libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "0:0:0" + -version-info "1:0:1" ### @@ -904,10 +930,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ethernet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-generic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-infiniband.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ip-tunnel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-macvlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-olpc-mesh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-tun.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vlan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vxlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-wifi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-wimax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device.Plo@am__quote@ @@ -925,8 +955,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-remote-settings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-secret-agent-old.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-connection.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-editor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-plugin-old.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-service-plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wimax-nsp.Plo@am__quote@ .c.o: diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 251a0422..35cd07ae 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -61,16 +61,20 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -81,7 +85,9 @@ #include #include #include +#include #include +#include #include #undef __NETWORKMANAGER_H_INSIDE__ diff --git a/libnm/libnm.pc.in b/libnm/libnm.pc.in index 5fe26b6a..afc5e4d9 100644 --- a/libnm/libnm.pc.in +++ b/libnm/libnm.pc.in @@ -2,6 +2,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +vpnservicedir=@nmlibdir@/VPN Name: libnm Description: Convenience library for clients of NetworkManager diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 90c5de04..ed008eee 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -821,17 +821,6 @@ global: nm_vpn_plugin_error_get_type; nm_vpn_plugin_error_quark; nm_vpn_plugin_failure_get_type; - nm_vpn_plugin_old_disconnect; - nm_vpn_plugin_old_failure; - nm_vpn_plugin_old_get_connection; - nm_vpn_plugin_old_get_secret_flags; - nm_vpn_plugin_old_get_state; - nm_vpn_plugin_old_get_type; - nm_vpn_plugin_old_read_vpn_details; - nm_vpn_plugin_old_secrets_required; - nm_vpn_plugin_old_set_ip4_config; - nm_vpn_plugin_old_set_login_banner; - nm_vpn_plugin_old_set_state; nm_vpn_service_state_get_type; nm_wep_key_type_get_type; nm_wimax_nsp_connection_valid; @@ -846,24 +835,209 @@ local: }; libnm_1_0_4 { -global: - nm_setting_connection_autoconnect_slaves_get_type; - nm_setting_connection_get_autoconnect_slaves; + #nm_setting_connection_autoconnect_slaves_get_type@libnm_1_0_4; + #nm_setting_connection_get_autoconnect_slaves@libnm_1_0_4; } libnm_1_0_0; libnm_1_0_6 { + #nm_access_point_get_last_seen@libnm_1_0_6; + #nm_device_get_metered@libnm_1_0_6; + #nm_device_wifi_request_scan_options@libnm_1_0_6; + #nm_device_wifi_request_scan_options_async@libnm_1_0_6; + #nm_metered_get_type@libnm_1_0_6; + #nm_setting_connection_get_metered@libnm_1_0_6; + #nm_setting_wired_get_wake_on_lan@libnm_1_0_6; + #nm_setting_wired_get_wake_on_lan_password@libnm_1_0_6; + #nm_setting_wired_wake_on_lan_get_type@libnm_1_0_6; + #nm_utils_enum_from_str@libnm_1_0_6; + #nm_utils_enum_to_str@libnm_1_0_6; + #nm_utils_wifi_2ghz_freqs@libnm_1_0_6; + #nm_utils_wifi_5ghz_freqs@libnm_1_0_6; +} libnm_1_0_4; + +libnm_1_2_0 { global: nm_access_point_get_last_seen; + nm_client_get_all_devices; + nm_connection_get_setting_ip_tunnel; + nm_connection_get_setting_macvlan; + nm_connection_get_setting_vxlan; + nm_connection_verify_secrets; + nm_device_ethernet_get_s390_subchannels; + nm_device_get_lldp_neighbors; nm_device_get_metered; + nm_device_get_nm_plugin_missing; + nm_device_ip_tunnel_get_encapsulation_limit; + nm_device_ip_tunnel_get_flow_label; + nm_device_ip_tunnel_get_input_key; + nm_device_ip_tunnel_get_local; + nm_device_ip_tunnel_get_mode; + nm_device_ip_tunnel_get_output_key; + nm_device_ip_tunnel_get_parent; + nm_device_ip_tunnel_get_path_mtu_discovery; + nm_device_ip_tunnel_get_remote; + nm_device_ip_tunnel_get_tos; + nm_device_ip_tunnel_get_ttl; + nm_device_ip_tunnel_get_type; + nm_device_is_real; + nm_device_macvlan_get_hw_address; + nm_device_macvlan_get_mode; + nm_device_macvlan_get_no_promisc; + nm_device_macvlan_get_parent; + nm_device_macvlan_get_tap; + nm_device_macvlan_get_type; + nm_device_reapply; + nm_device_reapply_async; + nm_device_reapply_finish; + nm_device_set_managed; + nm_device_tun_get_group; + nm_device_tun_get_hw_address; + nm_device_tun_get_mode; + nm_device_tun_get_multi_queue; + nm_device_tun_get_owner; + nm_device_tun_get_no_pi; + nm_device_tun_get_type; + nm_device_tun_get_vnet_hdr; + nm_device_vxlan_get_ageing; + nm_device_vxlan_get_dst_port; + nm_device_vxlan_get_group; + nm_device_vxlan_get_hw_address; + nm_device_vxlan_get_id; + nm_device_vxlan_get_l2miss; + nm_device_vxlan_get_l3miss; + nm_device_vxlan_get_learning; + nm_device_vxlan_get_limit; + nm_device_vxlan_get_local; + nm_device_vxlan_get_parent; + nm_device_vxlan_get_proxy; + nm_device_vxlan_get_src_port_max; + nm_device_vxlan_get_src_port_min; + nm_device_vxlan_get_tos; + nm_device_vxlan_get_ttl; + nm_device_vxlan_get_type; nm_device_wifi_request_scan_options; nm_device_wifi_request_scan_options_async; + nm_ip_tunnel_mode_get_type; + nm_lldp_neighbor_get_attr_names; + nm_lldp_neighbor_get_attr_string_value; + nm_lldp_neighbor_get_attr_type; + nm_lldp_neighbor_get_attr_uint_value; + nm_lldp_neighbor_get_type; + nm_lldp_neighbor_new; + nm_lldp_neighbor_ref; + nm_lldp_neighbor_unref; + nm_manager_get_all_devices; nm_metered_get_type; + nm_setting_802_1x_check_cert_scheme; + nm_setting_bridge_get_multicast_snooping; + nm_setting_connection_autoconnect_slaves_get_type; + nm_setting_connection_get_autoconnect_slaves; + nm_setting_connection_get_lldp; nm_setting_connection_get_metered; + nm_setting_connection_lldp_get_type; + nm_setting_gsm_get_device_id; + nm_setting_gsm_get_sim_id; + nm_setting_gsm_get_sim_operator_id; + nm_setting_ip4_config_get_dhcp_fqdn; + nm_setting_ip4_config_get_dhcp_timeout; + nm_setting_ip6_config_addr_gen_mode_get_type; + nm_setting_ip6_config_get_addr_gen_mode; + nm_setting_ip_config_add_dns_option; + nm_setting_ip_config_clear_dns_options; + nm_setting_ip_config_get_dns_option; + nm_setting_ip_config_get_num_dns_options; + nm_setting_ip_config_has_dns_options; + nm_setting_ip_config_remove_dns_option; + nm_setting_ip_config_remove_dns_option_by_value; + nm_setting_ip_tunnel_get_input_key; + nm_setting_ip_tunnel_get_local; + nm_setting_ip_tunnel_get_mode; + nm_setting_ip_tunnel_get_mtu; + nm_setting_ip_tunnel_get_output_key; + nm_setting_ip_tunnel_get_parent; + nm_setting_ip_tunnel_get_path_mtu_discovery; + nm_setting_ip_tunnel_get_remote; + nm_setting_ip_tunnel_get_tos; + nm_setting_ip_tunnel_get_type; + nm_setting_ip_tunnel_get_ttl; + nm_setting_ip_tunnel_new; + nm_setting_mac_randomization_get_type; + nm_setting_tun_get_group; + nm_setting_tun_get_mode; + nm_setting_tun_get_multi_queue; + nm_setting_tun_get_owner; + nm_setting_tun_get_pi; + nm_setting_tun_get_type; + nm_setting_tun_get_vnet_hdr; + nm_setting_tun_mode_get_type; + nm_setting_tun_new; + nm_setting_verify_secrets; + nm_setting_vpn_get_timeout; + nm_setting_macvlan_get_mode; + nm_setting_macvlan_get_parent; + nm_setting_macvlan_get_promiscuous; + nm_setting_macvlan_get_tap; + nm_setting_macvlan_get_type; + nm_setting_macvlan_mode_get_type; + nm_setting_macvlan_new; + nm_setting_vxlan_get_ageing; + nm_setting_vxlan_get_destination_port; + nm_setting_vxlan_get_id; + nm_setting_vxlan_get_l2_miss; + nm_setting_vxlan_get_l3_miss; + nm_setting_vxlan_get_learning; + nm_setting_vxlan_get_limit; + nm_setting_vxlan_get_local; + nm_setting_vxlan_get_parent; + nm_setting_vxlan_get_proxy; + nm_setting_vxlan_get_remote; + nm_setting_vxlan_get_rsc; + nm_setting_vxlan_get_source_port_max; + nm_setting_vxlan_get_source_port_min; + nm_setting_vxlan_get_tos; + nm_setting_vxlan_get_ttl; + nm_setting_vxlan_get_type; + nm_setting_vxlan_new; nm_setting_wired_get_wake_on_lan; nm_setting_wired_get_wake_on_lan_password; nm_setting_wired_wake_on_lan_get_type; + nm_setting_wireless_get_powersave; + nm_setting_wireless_get_mac_address_randomization; + nm_utils_bond_mode_int_to_string; + nm_utils_bond_mode_string_to_int; nm_utils_enum_from_str; nm_utils_enum_to_str; + nm_utils_enum_get_values; nm_utils_wifi_2ghz_freqs; nm_utils_wifi_5ghz_freqs; -} libnm_1_0_4; + nm_vpn_editor_plugin_load_from_file; + nm_vpn_plugin_info_get_filename; + nm_vpn_plugin_info_get_editor_plugin; + nm_vpn_plugin_info_get_name; + nm_vpn_plugin_info_get_plugin; + nm_vpn_plugin_info_get_program; + nm_vpn_plugin_info_get_type; + nm_vpn_plugin_info_load_editor_plugin; + nm_vpn_plugin_info_lookup_property; + nm_vpn_plugin_info_new_from_file; + nm_vpn_plugin_info_new_with_data; + nm_vpn_plugin_info_set_editor_plugin; + nm_vpn_plugin_info_validate_filename; + nm_vpn_plugin_info_list_add; + nm_vpn_plugin_info_list_find_by_filename; + nm_vpn_plugin_info_list_find_by_name; + nm_vpn_plugin_info_list_find_by_service; + nm_vpn_plugin_info_list_load; + nm_vpn_plugin_info_list_remove; + nm_vpn_service_plugin_disconnect; + nm_vpn_service_plugin_failure; + nm_vpn_service_plugin_get_connection; + nm_vpn_service_plugin_get_secret_flags; + nm_vpn_service_plugin_get_type; + nm_vpn_service_plugin_read_vpn_details; + nm_vpn_service_plugin_secrets_required; + nm_vpn_service_plugin_set_config; + nm_vpn_service_plugin_set_ip4_config; + nm_vpn_service_plugin_set_ip6_config; + nm_vpn_service_plugin_set_login_banner; +} libnm_1_0_0; diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c index c071a927..852b2808 100644 --- a/libnm/nm-access-point.c +++ b/libnm/nm-access-point.c @@ -23,17 +23,17 @@ #include -#include "nm-glib-compat.h" - #include #include #include #include #include +#include "nm-default.h" #include "nm-access-point.h" #include "nm-dbus-interface.h" #include "nm-object-private.h" +#include "nm-macros-internal.h" G_DEFINE_TYPE (NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) @@ -49,7 +49,7 @@ typedef struct { NM80211Mode mode; guint32 max_bitrate; guint8 strength; - gint32 last_seen; + gint last_seen; } NMAccessPointPrivate; enum { @@ -232,15 +232,16 @@ nm_access_point_get_strength (NMAccessPoint *ap) * * Returns: the last seen time in seconds * - * Since: 1.0.6 + * Since: 1.2 **/ -gint32 +gint nm_access_point_get_last_seen (NMAccessPoint *ap) { g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), -1); return NM_ACCESS_POINT_GET_PRIVATE (ap)->last_seen; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, gint, nm_access_point_get_last_seen, (NMAccessPoint *ap), (ap)); /** * nm_access_point_connection_valid: @@ -630,7 +631,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) * access point was found in scan results. A value of -1 means the * access point has not been found in a scan. * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_LAST_SEEN, diff --git a/libnm/nm-access-point.h b/libnm/nm-access-point.h index 24208fa8..f1e26548 100644 --- a/libnm/nm-access-point.h +++ b/libnm/nm-access-point.h @@ -74,7 +74,7 @@ guint32 nm_access_point_get_frequency (NMAccessPoint *ap); NM80211Mode nm_access_point_get_mode (NMAccessPoint *ap); guint32 nm_access_point_get_max_bitrate (NMAccessPoint *ap); guint8 nm_access_point_get_strength (NMAccessPoint *ap); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 gint nm_access_point_get_last_seen (NMAccessPoint *ap); GPtrArray * nm_access_point_filter_connections (NMAccessPoint *ap, diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c index 31f51328..b1608027 100644 --- a/libnm/nm-active-connection.c +++ b/libnm/nm-active-connection.c @@ -23,6 +23,7 @@ #include +#include "nm-default.h" #include "nm-dbus-interface.h" #include "nm-active-connection.h" #include "nm-object-private.h" @@ -31,7 +32,6 @@ #include "nm-device-private.h" #include "nm-connection.h" #include "nm-vpn-connection.h" -#include "nm-glib-compat.h" #include "nm-dbus-helpers.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 982717ce..dc6db0aa 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -24,6 +24,7 @@ #include #include +#include "nm-default.h" #include "nm-client.h" #include "nm-manager.h" #include "nm-remote-settings.h" @@ -35,7 +36,6 @@ #include "nm-vpn-connection.h" #include "nm-remote-connection.h" #include "nm-object-cache.h" -#include "nm-glib-compat.h" #include "nm-dbus-helpers.h" void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); @@ -73,6 +73,7 @@ enum { PROP_PRIMARY_CONNECTION, PROP_ACTIVATING_CONNECTION, PROP_DEVICES, + PROP_ALL_DEVICES, PROP_CONNECTIONS, PROP_HOSTNAME, PROP_CAN_MODIFY, @@ -84,6 +85,8 @@ enum { enum { DEVICE_ADDED, DEVICE_REMOVED, + ANY_DEVICE_ADDED, + ANY_DEVICE_REMOVED, PERMISSION_CHANGED, CONNECTION_ADDED, CONNECTION_REMOVED, @@ -719,6 +722,34 @@ nm_client_get_devices (NMClient *client) return nm_manager_get_devices (NM_CLIENT_GET_PRIVATE (client)->manager); } +/** + * nm_client_get_all_devices: + * @client: a #NMClient + * + * Gets both real devices and device placeholders (eg, software devices which + * do not currently exist, but could be created automatically by NetworkManager + * if one of their NMDevice::ActivatableConnections was activated). Use + * nm_device_is_real() to determine whether each device is a real device or + * a placeholder. + * + * Use nm_device_get_type() or the NM_IS_DEVICE_XXXX() functions to determine + * what kind of device each member of the returned array is, and then you may + * use device-specific methods such as nm_device_ethernet_get_hw_address(). + * + * Returns: (transfer none) (element-type NMDevice): a #GPtrArray + * containing all the #NMDevices. The returned array is owned by the + * #NMClient object and should not be modified. + * + * Since: 1.2 + **/ +const GPtrArray * +nm_client_get_all_devices (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_all_devices (NM_CLIENT_GET_PRIVATE (client)->manager); +} + /** * nm_client_get_device_by_path: * @client: a #NMClient @@ -1660,6 +1691,7 @@ manager_device_added (NMManager *manager, { g_signal_emit (client, signals[DEVICE_ADDED], 0, device); } + static void manager_device_removed (NMManager *manager, NMDevice *device, @@ -1668,6 +1700,22 @@ manager_device_removed (NMManager *manager, g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); } +static void +manager_any_device_added (NMManager *manager, + NMDevice *device, + gpointer client) +{ + g_signal_emit (client, signals[ANY_DEVICE_ADDED], 0, device); +} + +static void +manager_any_device_removed (NMManager *manager, + NMDevice *device, + gpointer client) +{ + g_signal_emit (client, signals[ANY_DEVICE_REMOVED], 0, device); +} + static void manager_permission_changed (NMManager *manager, NMClientPermission permission, @@ -1707,6 +1755,10 @@ constructed (GObject *object) G_CALLBACK (manager_device_added), client); g_signal_connect (priv->manager, "device-removed", G_CALLBACK (manager_device_removed), client); + g_signal_connect (priv->manager, "any-device-added", + G_CALLBACK (manager_any_device_added), client); + g_signal_connect (priv->manager, "any-device-removed", + G_CALLBACK (manager_any_device_removed), client); g_signal_connect (priv->manager, "permission-changed", G_CALLBACK (manager_permission_changed), client); @@ -1873,6 +1925,7 @@ get_property (GObject *object, guint prop_id, case PROP_ACTIVATING_CONNECTION: case PROP_DEVICES: case PROP_METERED: + case PROP_ALL_DEVICES: g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager), pspec->name, value); break; @@ -2092,7 +2145,7 @@ nm_client_class_init (NMClientClass *client_class) /** * NMClient:devices: * - * List of known network devices. + * List of real network devices. Does not include placeholder devices. * * Element-type: NMDevice **/ @@ -2103,6 +2156,21 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMClient:all-devices: + * + * List of both real devices and device placeholders. + * + * Element-type: NMDevice + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_ALL_DEVICES, + g_param_spec_boxed (NM_CLIENT_ALL_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * NMClient:connections: * @@ -2150,7 +2218,7 @@ nm_client_class_init (NMClientClass *client_class) * * Whether the connectivity is metered. * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_METERED, @@ -2166,7 +2234,8 @@ nm_client_class_init (NMClientClass *client_class) * @client: the client that received the signal * @device: (type NMDevice): the new device * - * Notifies that a #NMDevice is added. + * Notifies that a #NMDevice is added. This signal is not emitted for + * placeholder devices. **/ signals[DEVICE_ADDED] = g_signal_new (NM_CLIENT_DEVICE_ADDED, @@ -2182,7 +2251,8 @@ nm_client_class_init (NMClientClass *client_class) * @client: the client that received the signal * @device: (type NMDevice): the removed device * - * Notifies that a #NMDevice is removed. + * Notifies that a #NMDevice is removed. This signal is not emitted for + * placeholder devices. **/ signals[DEVICE_REMOVED] = g_signal_new (NM_CLIENT_DEVICE_REMOVED, @@ -2193,6 +2263,40 @@ nm_client_class_init (NMClientClass *client_class) G_TYPE_NONE, 1, G_TYPE_OBJECT); + /** + * NMClient::any-device-added: + * @client: the client that received the signal + * @device: (type NMDevice): the new device + * + * Notifies that a #NMDevice is added. This signal is emitted for both + * regular devices and placeholder devices. + **/ + signals[ANY_DEVICE_ADDED] = + g_signal_new (NM_CLIENT_ANY_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, any_device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + /** + * NMClient::any-device-removed: + * @client: the client that received the signal + * @device: (type NMDevice): the removed device + * + * Notifies that a #NMDevice is removed. This signal is emitted for both + * regular devices and placeholder devices. + **/ + signals[ANY_DEVICE_REMOVED] = + g_signal_new (NM_CLIENT_ANY_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, any_device_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + /** * NMClient::permission-changed: * @client: the client that received the signal diff --git a/libnm/nm-client.h b/libnm/nm-client.h index fc309fa1..54d6deee 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -53,6 +53,7 @@ G_BEGIN_DECLS #define NM_CLIENT_PRIMARY_CONNECTION "primary-connection" #define NM_CLIENT_ACTIVATING_CONNECTION "activating-connection" #define NM_CLIENT_DEVICES "devices" +#define NM_CLIENT_ALL_DEVICES "all-devices" #define NM_CLIENT_CONNECTIONS "connections" #define NM_CLIENT_HOSTNAME "hostname" #define NM_CLIENT_CAN_MODIFY "can-modify" @@ -60,6 +61,8 @@ G_BEGIN_DECLS #define NM_CLIENT_DEVICE_ADDED "device-added" #define NM_CLIENT_DEVICE_REMOVED "device-removed" +#define NM_CLIENT_ANY_DEVICE_ADDED "any-device-added" +#define NM_CLIENT_ANY_DEVICE_REMOVED "any-device-removed" #define NM_CLIENT_PERMISSION_CHANGED "permission-changed" #define NM_CLIENT_CONNECTION_ADDED "connection-added" #define NM_CLIENT_CONNECTION_REMOVED "connection-removed" @@ -164,6 +167,8 @@ typedef struct { /* Signals */ void (*device_added) (NMClient *client, NMDevice *device); void (*device_removed) (NMClient *client, NMDevice *device); + void (*any_device_added) (NMClient *client, NMDevice *device); + void (*any_device_removed) (NMClient *client, NMDevice *device); void (*permission_changed) (NMClient *client, NMClientPermission permission, NMClientPermissionResult result); @@ -171,7 +176,7 @@ typedef struct { void (*connection_removed) (NMClient *client, NMRemoteConnection *connection); /*< private >*/ - gpointer padding[8]; + gpointer padding[6]; } NMClientClass; GType nm_client_get_type (void); @@ -248,6 +253,8 @@ gboolean nm_client_save_hostname_finish (NMClient *client, /* Devices */ const GPtrArray *nm_client_get_devices (NMClient *client); +NM_AVAILABLE_IN_1_2 +const GPtrArray *nm_client_get_all_devices(NMClient *client); NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); NMDevice *nm_client_get_device_by_iface (NMClient *client, const char *iface); diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c index 45e09442..3c039375 100644 --- a/libnm/nm-dbus-helpers.c +++ b/libnm/nm-dbus-helpers.c @@ -21,11 +21,11 @@ #include "config.h" #include -#include -#include "nm-glib-compat.h" +#include "nm-default.h" #include "nm-dbus-helpers.h" #include "nm-dbus-interface.h" +#include "nm-macros-internal.h" static GBusType nm_bus = G_BUS_TYPE_SYSTEM; @@ -44,79 +44,9 @@ _nm_dbus_bus_type (void) return nm_bus; } -static struct { - GMutex mutex; - GWeakRef weak_ref; -} private_connection; - -static void -_private_dbus_connection_closed_cb (GDBusConnection *connection, - gboolean remote_peer_vanished, - GError *error, - gpointer user_data) -{ - GDBusConnection *p; - - g_mutex_lock (&private_connection.mutex); - p = g_weak_ref_get (&private_connection.weak_ref); - if (connection == p) { - g_signal_handlers_disconnect_by_func (G_OBJECT (connection), G_CALLBACK (_private_dbus_connection_closed_cb), NULL); - g_weak_ref_set (&private_connection.weak_ref, NULL); - } - if (p) - g_object_unref (p); - g_mutex_unlock (&private_connection.mutex); -} - -static GDBusConnection * -_private_dbus_connection_internalize (GDBusConnection *connection) -{ - GDBusConnection *p; - - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); - g_return_val_if_fail (!g_dbus_connection_is_closed (connection), NULL); - - g_mutex_lock (&private_connection.mutex); - p = g_weak_ref_get (&private_connection.weak_ref); - if (p) { - g_object_unref (connection); - connection = p; - } else { - g_weak_ref_set (&private_connection.weak_ref, connection); - g_signal_connect (connection, "closed", G_CALLBACK (_private_dbus_connection_closed_cb), NULL); - } - g_mutex_unlock (&private_connection.mutex); - return connection; -} - GDBusConnection * _nm_dbus_new_connection (GCancellable *cancellable, GError **error) { - GDBusConnection *connection = NULL; - - /* If running as root try the private bus first */ - if (0 == geteuid () && !g_test_initialized ()) { - - GError *local = NULL; - GDBusConnection *p; - - p = g_weak_ref_get (&private_connection.weak_ref); - if (p) - return p; - - connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private", - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, - NULL, cancellable, &local); - if (connection) - return _private_dbus_connection_internalize (connection); - - if (g_error_matches (local, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_propagate_error (error, local); - return NULL; - } - g_error_free (local); - } - return g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error); } @@ -137,65 +67,6 @@ new_connection_async_got_system (GObject *source, GAsyncResult *result, gpointer g_object_unref (simple); } -static void -new_connection_async_got_private (GObject *source, GAsyncResult *result, gpointer user_data) -{ - GSimpleAsyncResult *simple = user_data; - GDBusConnection *connection; - GError *error = NULL; - - connection = g_dbus_connection_new_for_address_finish (result, &error); - if (connection) { - connection = _private_dbus_connection_internalize (connection); - g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); - g_simple_async_result_complete (simple); - g_object_unref (simple); - return; - } - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); - return; - } - - g_clear_error (&error); - g_bus_get (_nm_dbus_bus_type (), - g_object_get_data (G_OBJECT (simple), "cancellable"), - new_connection_async_got_system, simple); -} - -static void -_nm_dbus_new_connection_async_do (GSimpleAsyncResult *simple, GCancellable *cancellable) -{ - g_dbus_connection_new_for_address ("unix:path=" NMRUNDIR "/private", - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, - NULL, - cancellable, - new_connection_async_got_private, simple); -} - -static gboolean -_nm_dbus_new_connection_async_get_private (gpointer user_data) -{ - GSimpleAsyncResult *simple = user_data; - GDBusConnection *p; - - p = g_weak_ref_get (&private_connection.weak_ref); - if (!p) { - /* The connection is gone. Create a new one async... */ - _nm_dbus_new_connection_async_do (simple, - g_object_get_data (G_OBJECT (simple), "cancellable")); - } else { - g_simple_async_result_set_op_res_gpointer (simple, p, g_object_unref); - g_simple_async_result_complete (simple); - g_object_unref (simple); - } - - return G_SOURCE_REMOVE; -} - void _nm_dbus_new_connection_async (GCancellable *cancellable, GAsyncReadyCallback callback, @@ -205,25 +76,9 @@ _nm_dbus_new_connection_async (GCancellable *cancellable, simple = g_simple_async_result_new (NULL, callback, user_data, _nm_dbus_new_connection_async); - /* If running as root try the private bus first */ - if (0 == geteuid () && !g_test_initialized ()) { - GDBusConnection *p; - - if (cancellable) { - g_object_set_data_full (G_OBJECT (simple), "cancellable", - g_object_ref (cancellable), g_object_unref); - } - p = g_weak_ref_get (&private_connection.weak_ref); - if (p) { - g_object_unref (p); - g_idle_add (_nm_dbus_new_connection_async_get_private, simple); - } else - _nm_dbus_new_connection_async_do (simple, cancellable); - } else { - g_bus_get (_nm_dbus_bus_type (), - cancellable, - new_connection_async_got_system, simple); - } + g_bus_get (_nm_dbus_bus_type (), + cancellable, + new_connection_async_got_system, simple); } GDBusConnection * @@ -262,6 +117,67 @@ _nm_dbus_register_proxy_type (const char *interface, #define NM_DBUS_PROXY_FLAGS (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | \ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) +/* D-Bus has an upper limit on number of Match rules and it's rather easy + * to hit as the proxy likes to add one for each object. Let's remove the Match + * rule the proxy added and ensure a less granular rule is present instead. + * + * Also, don't do this immediately since it has a performance penalty. + * Still better than loosing the signals altogether. + * + * Ideally, we should be able to tell glib not to hook its rules: + * https://bugzilla.gnome.org/show_bug.cgi?id=758749 + */ +static void +_nm_dbus_proxy_replace_match (GDBusProxy *proxy) +{ + GDBusConnection *connection = g_dbus_proxy_get_connection (proxy); + static unsigned match_counter = 1024; + gchar *match; + + nm_assert (!g_strcmp0 (g_dbus_proxy_get_name (proxy), NM_DBUS_SERVICE)); + + if (match_counter == 1) { + /* If we hit the low matches watermark, install a + * less granular one. */ + g_dbus_connection_call (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "AddMatch", + g_variant_new ("(s)", "type='signal',sender='" NM_DBUS_SERVICE "'"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); + } + + if (match_counter) + match_counter--; + if (match_counter) + return; + + /* Remove what this proxy added. */ + match = g_strdup_printf ("type='signal',sender='" NM_DBUS_SERVICE "'," + "interface='%s',path='%s'", + g_dbus_proxy_get_interface_name (proxy), + g_dbus_proxy_get_object_path (proxy)); + g_dbus_connection_call (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RemoveMatch", + g_variant_new ("(s)", match), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); + g_free (match); +} + GDBusProxy * _nm_dbus_new_proxy_for_connection (GDBusConnection *connection, const char *path, @@ -269,6 +185,7 @@ _nm_dbus_new_proxy_for_connection (GDBusConnection *connection, GCancellable *cancellable, GError **error) { + GDBusProxy *proxy; GType proxy_type; const char *name; @@ -281,13 +198,16 @@ _nm_dbus_new_proxy_for_connection (GDBusConnection *connection, else name = NM_DBUS_SERVICE; - return g_initable_new (proxy_type, cancellable, error, - "g-connection", connection, - "g-flags", NM_DBUS_PROXY_FLAGS, - "g-name", name, - "g-object-path", path, - "g-interface-name", interface, - NULL); + proxy = g_initable_new (proxy_type, cancellable, error, + "g-connection", connection, + "g-flags", NM_DBUS_PROXY_FLAGS, + "g-name", name, + "g-object-path", path, + "g-interface-name", interface, + NULL); + _nm_dbus_proxy_replace_match (proxy); + + return proxy; } void @@ -324,13 +244,15 @@ GDBusProxy * _nm_dbus_new_proxy_for_connection_finish (GAsyncResult *result, GError **error) { - GObject *source, *proxy; + GObject *source; + GDBusProxy *proxy; source = g_async_result_get_source_object (result); - proxy = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error); + proxy = G_DBUS_PROXY (g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error)); g_object_unref (source); + _nm_dbus_proxy_replace_match (proxy); - return G_DBUS_PROXY (proxy); + return proxy; } /* Binds the properties on a generated server-side GDBus object to the diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h index ca779d3a..497739f0 100644 --- a/libnm/nm-dbus-helpers.h +++ b/libnm/nm-dbus-helpers.h @@ -21,18 +21,9 @@ #ifndef __NM_DBUS_HELPERS_PRIVATE_H__ #define __NM_DBUS_HELPERS_PRIVATE_H__ -#include - -/* Copied from dbus/dbus-shared.h */ -#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" -#define DBUS_PATH_DBUS "/org/freedesktop/DBus" -#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" - -#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" -#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" -#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" -#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" +#include "nm-default.h" +#include "nm-dbus-compat.h" GBusType _nm_dbus_bus_type (void); diff --git a/libnm/nm-device-adsl.c b/libnm/nm-device-adsl.c index 99771548..b9d609da 100644 --- a/libnm/nm-device-adsl.c +++ b/libnm/nm-device-adsl.c @@ -29,7 +29,6 @@ #include "nm-setting-connection.h" #include -#include G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) diff --git a/libnm/nm-device-bond.c b/libnm/nm-device-bond.c index 6bb67323..3bfcb94c 100644 --- a/libnm/nm-device-bond.c +++ b/libnm/nm-device-bond.c @@ -21,14 +21,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-bond.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-bridge.c b/libnm/nm-device-bridge.c index ce28f2c2..5afc46e3 100644 --- a/libnm/nm-device-bridge.c +++ b/libnm/nm-device-bridge.c @@ -21,14 +21,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-bridge.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c index 77526464..f89be172 100644 --- a/libnm/nm-device-bt.c +++ b/libnm/nm-device-bt.c @@ -22,14 +22,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-bt.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c index be2cb4dc..537a6f4c 100644 --- a/libnm/nm-device-ethernet.c +++ b/libnm/nm-device-ethernet.c @@ -22,15 +22,13 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include #include +#include "nm-default.h" #include "nm-device-ethernet.h" #include "nm-device-private.h" #include "nm-object-private.h" @@ -44,6 +42,7 @@ typedef struct { char *perm_hw_address; guint32 speed; gboolean carrier; + char **s390_subchannels; } NMDeviceEthernetPrivate; enum { @@ -52,6 +51,7 @@ enum { PROP_PERM_HW_ADDRESS, PROP_SPEED, PROP_CARRIER, + PROP_S390_SUBCHANNELS, LAST_PROP }; @@ -122,18 +122,88 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *device) return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->carrier; } +/** + * nm_device_ethernet_get_s390_subchannels: + * @device: a #NMDeviceEthernet + * + * Return the list of s390 subchannels if the device supports them. + * + * Returns: (transfer none) (element-type utf8): array of strings, each specifying + * one subchannel the s390 device uses to communicate to the host. + * + * Since: 1.2 + **/ +const char * const * +nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL); + + return (const char * const *) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->s390_subchannels; +} + +static guint32 +_subchannels_count_num (const char * const *array) +{ + int i; + + if (!array) + return 0; + for (i = 0; array[i]; i++) + /* NOP */; + return i; +} + +static gboolean +match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const char * const *subchans; + guint32 num1, num2; + int i, j; + + *try_mac = TRUE; + + subchans = nm_setting_wired_get_s390_subchannels (s_wired); + num1 = _subchannels_count_num (subchans); + num2 = _subchannels_count_num ((const char * const *) priv->s390_subchannels); + /* connection has no subchannels */ + if (num1 == 0) + return TRUE; + /* connection requires subchannels but the device has none */ + if (num2 == 0) + return FALSE; + /* number of subchannels differ */ + if (num1 != num2) + return FALSE; + + /* Make sure each subchannel in the connection is a subchannel of this device */ + for (i = 0; subchans[i]; i++) { + const char *candidate = subchans[i]; + gboolean found = FALSE; + + for (j = 0; priv->s390_subchannels[j]; j++) { + if (!g_strcmp0 (priv->s390_subchannels[j], candidate)) + found = TRUE; + } + if (!found) + return FALSE; /* a subchannel was not found */ + } + + *try_mac = FALSE; + return TRUE; +} + static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMSettingWired *s_wired; - gboolean is_pppoe = FALSE; if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_compatible (device, connection, error)) return FALSE; - if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) - is_pppoe = TRUE; - else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { + if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { + /* NOP */ + } else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, _("The connection was not an Ethernet or PPPoE connection.")); return FALSE; @@ -142,24 +212,49 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro s_wired = nm_connection_get_setting_wired (connection); /* Wired setting optional for PPPoE */ if (s_wired) { - const char *perm_addr, *setting_addr; - - /* FIXME: filter using s390 subchannels when they are exported over the bus */ + const char *perm_addr, *s_mac; + gboolean try_mac = TRUE; + const char * const *mac_blacklist; + int i; + + /* Check s390 subchannels */ + if (!match_subchans (NM_DEVICE_ETHERNET (device), s_wired, &try_mac)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection and device differ in S390 subchannels.")); + return FALSE; + } /* Check MAC address */ perm_addr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device)); + s_mac = nm_setting_wired_get_mac_address (s_wired); if (perm_addr) { if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, _("Invalid device MAC address.")); return FALSE; } - setting_addr = nm_setting_wired_get_mac_address (s_wired); - if (setting_addr && !nm_utils_hwaddr_matches (setting_addr, -1, perm_addr, -1)) { + if (try_mac && s_mac && !nm_utils_hwaddr_matches (s_mac, -1, perm_addr, -1)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - _("The MACs of the device and the connection didn't match.")); + _("The MACs of the device and the connection do not match.")); return FALSE; } + + /* Check for MAC address blacklist */ + mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { + g_warn_if_reached (); + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("Invalid MAC in the blacklist: %s."), mac_blacklist[i]); + return FALSE; + } + + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_addr, -1)) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("Device MAC (%s) is blacklisted by the connection."), perm_addr); + return FALSE; + } + } } } @@ -195,6 +290,7 @@ init_dbus (NMObject *object) { NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, &priv->perm_hw_address }, { NM_DEVICE_ETHERNET_SPEED, &priv->speed }, { NM_DEVICE_ETHERNET_CARRIER, &priv->carrier }, + { NM_DEVICE_ETHERNET_S390_SUBCHANNELS, &priv->s390_subchannels }, { NULL }, }; @@ -212,6 +308,7 @@ finalize (GObject *object) g_free (priv->hw_address); g_free (priv->perm_hw_address); + g_strfreev (priv->s390_subchannels); G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object); } @@ -223,6 +320,7 @@ get_property (GObject *object, GParamSpec *pspec) { NMDeviceEthernet *device = NM_DEVICE_ETHERNET (object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); switch (prop_id) { case PROP_HW_ADDRESS: @@ -237,6 +335,9 @@ get_property (GObject *object, case PROP_CARRIER: g_value_set_boolean (value, nm_device_ethernet_get_carrier (device)); break; + case PROP_S390_SUBCHANNELS: + g_value_set_boxed (value, priv->s390_subchannels); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -314,4 +415,18 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMDeviceEthernet:s390-subchannels: + * + * Identifies subchannels of this network device used for + * communication with z/VM or s390 host. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_S390_SUBCHANNELS, + g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm/nm-device-ethernet.h b/libnm/nm-device-ethernet.h index 09286e73..07cf4c4d 100644 --- a/libnm/nm-device-ethernet.h +++ b/libnm/nm-device-ethernet.h @@ -41,6 +41,7 @@ G_BEGIN_DECLS #define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_CARRIER "carrier" +#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels" struct _NMDeviceEthernet { NMDevice parent; @@ -59,6 +60,8 @@ const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device); const char * nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device); guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *device); gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *device); +NM_AVAILABLE_IN_1_2 +const char * const *nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device); G_END_DECLS diff --git a/libnm/nm-device-generic.c b/libnm/nm-device-generic.c index 3ed0fa7e..9aeb9bfa 100644 --- a/libnm/nm-device-generic.c +++ b/libnm/nm-device-generic.c @@ -21,7 +21,6 @@ #include "config.h" #include -#include #include "nm-device-generic.h" #include "nm-device-private.h" diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c index bce8a87a..ab3a0bb7 100644 --- a/libnm/nm-device-infiniband.c +++ b/libnm/nm-device-infiniband.c @@ -21,14 +21,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-infiniband.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-ip-tunnel.c b/libnm/nm-device-ip-tunnel.c new file mode 100644 index 00000000..b43b0412 --- /dev/null +++ b/libnm/nm-device-ip-tunnel.c @@ -0,0 +1,544 @@ +/* -*- 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 + +#include +#include +#include + +#include "nm-default.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" + +G_DEFINE_TYPE (NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE) + +#define NM_DEVICE_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelPrivate)) + +typedef struct { + NMIPTunnelMode mode; + NMDevice *parent; + char *local; + char *remote; + guint8 ttl; + guint8 tos; + gboolean path_mtu_discovery; + char *input_key; + char *output_key; + guint8 encap_limit; + guint32 flow_label; +} NMDeviceIPTunnelPrivate; + +enum { + PROP_0, + PROP_MODE, + PROP_PARENT, + PROP_LOCAL, + PROP_REMOTE, + PROP_TTL, + PROP_TOS, + PROP_PATH_MTU_DISCOVERY, + PROP_INPUT_KEY, + PROP_OUTPUT_KEY, + PROP_ENCAPSULATION_LIMIT, + PROP_FLOW_LABEL, + + LAST_PROP +}; + +/** + * nm_device_ip_tunnel_get_mode: + * @device: a #NMDeviceIPTunnel + * + * Returns: the tunneling mode + * + * Since: 1.2 + **/ +NMIPTunnelMode +nm_device_ip_tunnel_get_mode (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->mode; +} + +/** + * nm_device_ip_tunnel_get_parent: + * @device: a #NMDeviceIPTunnel + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_ip_tunnel_get_parent (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->parent; +} + +/** + * nm_device_ip_tunnel_get_local: + * @device: a #NMDeviceIPTunnel + * + * Returns: the local endpoint of the tunnel + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_local (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->local; +} + +/** + * nm_device_ip_tunnel_get_remote: + * @device: a #NMDeviceIPTunnel + * + * Returns: the remote endpoint of the tunnel + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_remote (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->remote; +} + +/** + * nm_device_ip_tunnel_get_ttl: + * @device: a #NMDeviceIPTunnel + * + * Returns: the TTL assigned to tunneled packets + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_ttl (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->ttl; +} + +/** + * nm_device_ip_tunnel_get_tos: + * @device: a #NMDeviceIPTunnel + * + * Returns: type of service (IPv4) or traffic class (IPv6) assigned + * to tunneled packets. + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_tos (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->tos; +} + +/** + * nm_device_ip_tunnel_get_path_mtu_discovery: + * @device: a #NMDeviceIPTunnel + * + * Returns: whether path MTU discovery is enabled + * + * Since: 1.2 + **/ +gboolean +nm_device_ip_tunnel_get_path_mtu_discovery (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), TRUE); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->path_mtu_discovery; +} + +/** + * nm_device_ip_tunnel_get_input_key: + * @device: a #NMDeviceIPTunnel + * + * Returns: the key used for incoming packets + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_input_key (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->input_key; +} + +/** + * nm_device_ip_tunnel_get_output_key: + * @device: a #NMDeviceIPTunnel + * + * Returns: the key used for outgoing packets + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_output_key (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->output_key; +} + +/** + * nm_device_ip_tunnel_get_encapsulation_limit: + * @device: a #NMDeviceIPTunnel + * + * Returns: the maximum permitted encapsulation level + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_encapsulation_limit (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->encap_limit; +} + +/** + * nm_device_ip_tunnel_get_flow_label: + * @device: a #NMDeviceIPTunnel + * + * Returns: the flow label assigned to tunnel packets + * + * Since: 1.2 + **/ +guint +nm_device_ip_tunnel_get_flow_label (NMDeviceIPTunnel *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->flow_label; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an IP tunnel connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_IP_TUNNEL; +} + +/***********************************************************/ + +static void +nm_device_ip_tunnel_init (NMDeviceIPTunnel *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_IP_TUNNEL); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_IP_TUNNEL_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE }, + { NM_DEVICE_IP_TUNNEL_MODE, &priv->mode }, + { NM_DEVICE_IP_TUNNEL_LOCAL, &priv->local }, + { NM_DEVICE_IP_TUNNEL_REMOTE, &priv->remote }, + { NM_DEVICE_IP_TUNNEL_TTL, &priv->ttl }, + { NM_DEVICE_IP_TUNNEL_TOS, &priv->tos }, + { NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, &priv->path_mtu_discovery }, + { NM_DEVICE_IP_TUNNEL_INPUT_KEY, &priv->input_key }, + { NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, &priv->output_key }, + { NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, &priv->encap_limit }, + { NM_DEVICE_IP_TUNNEL_FLOW_LABEL, &priv->flow_label }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object); + + g_free (priv->local); + g_free (priv->remote); + g_free (priv->input_key); + g_free (priv->output_key); + g_clear_object (&priv->parent); + + G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceIPTunnel *device = NM_DEVICE_IP_TUNNEL (object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object (value, nm_device_ip_tunnel_get_parent (device)); + break; + case PROP_MODE: + g_value_set_uint (value, nm_device_ip_tunnel_get_mode (device)); + break; + case PROP_LOCAL: + g_value_set_string (value, nm_device_ip_tunnel_get_local (device)); + break; + case PROP_REMOTE: + g_value_set_string (value, nm_device_ip_tunnel_get_remote (device)); + break; + case PROP_TTL: + g_value_set_uint (value, nm_device_ip_tunnel_get_ttl (device)); + break; + case PROP_TOS: + g_value_set_uint (value, nm_device_ip_tunnel_get_tos (device)); + break; + case PROP_PATH_MTU_DISCOVERY: + g_value_set_boolean (value, nm_device_ip_tunnel_get_path_mtu_discovery (device)); + break; + case PROP_INPUT_KEY: + g_value_set_string (value, nm_device_ip_tunnel_get_input_key (device)); + break; + case PROP_OUTPUT_KEY: + g_value_set_string (value, nm_device_ip_tunnel_get_output_key (device)); + break; + case PROP_ENCAPSULATION_LIMIT: + g_value_set_uint (value, nm_device_ip_tunnel_get_encapsulation_limit (device)); + break; + case PROP_FLOW_LABEL: + g_value_set_uint (value, nm_device_ip_tunnel_get_flow_label (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *bond_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (bond_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bond_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (bond_class); + + g_type_class_add_private (bond_class, sizeof (NMDeviceIPTunnelPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /* properties */ + + /** + * NMDeviceIPTunnel:mode: + * + * The tunneling mode of the device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_DEVICE_IP_TUNNEL_MODE, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_object (NM_DEVICE_IP_TUNNEL_PARENT, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:local: + * + * The local endpoint of the tunnel. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_LOCAL, + g_param_spec_string (NM_DEVICE_IP_TUNNEL_LOCAL, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:remote: + * + * The remote endpoint of the tunnel. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_REMOTE, + g_param_spec_string (NM_DEVICE_IP_TUNNEL_REMOTE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:ttl: + * + * The TTL assigned 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_uchar (NM_DEVICE_IP_TUNNEL_TTL, "", "", + 0, 255, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:tos: + * + * The type of service (IPv4) or traffic class (IPv6) assigned to + * tunneled packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TOS, + g_param_spec_uchar (NM_DEVICE_IP_TUNNEL_TOS, "", "", + 0, 255, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:path-mtu-discovery: + * + * Whether path MTU discovery is enabled on this tunnel. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PATH_MTU_DISCOVERY, + g_param_spec_boolean (NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:input-key: + * + * The key used for tunneled input packets, if applicable. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_INPUT_KEY, + g_param_spec_string (NM_DEVICE_IP_TUNNEL_INPUT_KEY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel:output-key: + * + * The key used for tunneled output packets, if applicable. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_OUTPUT_KEY, + g_param_spec_string (NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel: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_uchar (NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, "", "", + 0, 255, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceIPTunnel: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_DEVICE_IP_TUNNEL_FLOW_LABEL, "", "", + 0, (1 << 20) - 1, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-ip-tunnel.h b/libnm/nm-device-ip-tunnel.h new file mode 100644 index 00000000..820eab16 --- /dev/null +++ b/libnm/nm-device-ip-tunnel.h @@ -0,0 +1,90 @@ +/* -*- 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_DEVICE_IP_TUNNEL_H__ +#define __NM_DEVICE_IP_TUNNEL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type ()) +#define NM_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) +#define NM_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) +#define NM_IS_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_IS_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_DEVICE_IP_TUNNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) + +#define NM_DEVICE_IP_TUNNEL_MODE "mode" +#define NM_DEVICE_IP_TUNNEL_PARENT "parent" +#define NM_DEVICE_IP_TUNNEL_LOCAL "local" +#define NM_DEVICE_IP_TUNNEL_REMOTE "remote" +#define NM_DEVICE_IP_TUNNEL_TTL "ttl" +#define NM_DEVICE_IP_TUNNEL_TOS "tos" +#define NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY "path-mtu-discovery" +#define NM_DEVICE_IP_TUNNEL_INPUT_KEY "input-key" +#define NM_DEVICE_IP_TUNNEL_OUTPUT_KEY "output-key" +#define NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit" +#define NM_DEVICE_IP_TUNNEL_FLOW_LABEL "flow-label" + +struct _NMDeviceIPTunnel { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceIPTunnelClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_ip_tunnel_get_type (void); + +NM_AVAILABLE_IN_1_2 +NMDevice * nm_device_ip_tunnel_get_parent (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +NMIPTunnelMode nm_device_ip_tunnel_get_mode (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_ip_tunnel_get_local (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_ip_tunnel_get_remote (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_ttl (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_tos (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_ip_tunnel_get_path_mtu_discovery (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_ip_tunnel_get_input_key (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_ip_tunnel_get_output_key (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_encapsulation_limit (NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_ip_tunnel_get_flow_label (NMDeviceIPTunnel *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_IP_TUNNEL_H__ */ diff --git a/libnm/nm-device-macvlan.c b/libnm/nm-device-macvlan.c new file mode 100644 index 00000000..3b4bfd35 --- /dev/null +++ b/libnm/nm-device-macvlan.c @@ -0,0 +1,347 @@ +/* -*- 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 + +#include +#include +#include +#include + +#include "nm-default.h" +#include "nm-device-macvlan.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate)) + +typedef struct { + NMDevice *parent; + char *mode; + gboolean no_promisc; + gboolean tap; + char *hw_address; +} NMDeviceMacvlanPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_MODE, + PROP_NO_PROMISC, + PROP_TAP, + PROP_HW_ADDRESS, + + LAST_PROP +}; + +/** + * nm_device_macvlan_get_parent: + * @device: a #NMDeviceMacvlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_macvlan_get_parent (NMDeviceMacvlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE); + + return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent; +} + +/** + * nm_device_macvlan_get_mode: + * @device: a #NMDeviceMacvlan + * + * Gets the MACVLAN mode of the device. + * + * Returns: the MACVLAN mode. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + **/ +const char * +nm_device_macvlan_get_mode (NMDeviceMacvlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL); + + return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->mode; +} + +/** + * nm_device_macvlan_get_no_promisc + * @device: a #NMDeviceMacvlan + * + * Gets the no-promiscuous flag of the device. + * + * Returns: the no-promiscuous flag of the device. + * + * Since: 1.2 + **/ +gboolean +nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE); + + return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->no_promisc; +} + +/** + * nm_device_macvlan_get_tap: + * @device: a #NMDeviceMacvlan + * + * Gets the device type (MACVLAN or MACVTAP). + * + * Returns: %TRUE if the device is a MACVTAP, %FALSE if it is a MACVLAN. + * + * Since: 1.2 + **/ +gboolean +nm_device_macvlan_get_tap (NMDeviceMacvlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE); + + return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->tap; +} + +/** + * nm_device_macvlan_get_hw_address: + * @device: a #NMDeviceMacvlan + * + * Gets the hardware (MAC) address of the #NMDeviceMacvlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + **/ +const char * +nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL); + + return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->hw_address; +} + + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); + NMSettingMacvlan *s_macvlan; + + if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a MAC-VLAN connection.")); + return FALSE; + } + + s_macvlan = nm_connection_get_setting_macvlan (connection); + if (s_macvlan) { + if (nm_setting_macvlan_get_tap (s_macvlan) != priv->tap) + return FALSE; + } + + return TRUE; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_macvlan_get_hw_address (NM_DEVICE_MACVLAN (device)); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_MACVLAN; +} + +/***********************************************************/ + +static void +nm_device_macvlan_init (NMDeviceMacvlan *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_MACVLAN); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_MACVLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE }, + { NM_DEVICE_MACVLAN_MODE, &priv->mode }, + { NM_DEVICE_MACVLAN_NO_PROMISC, &priv->no_promisc }, + { NM_DEVICE_MACVLAN_TAP, &priv->tap }, + { NM_DEVICE_MACVLAN_HW_ADDRESS, &priv->hw_address }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_macvlan_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_MACVLAN, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); + + g_free (priv->mode); + g_free (priv->hw_address); + g_clear_object (&priv->parent); + + G_OBJECT_CLASS (nm_device_macvlan_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceMacvlan *device = NM_DEVICE_MACVLAN (object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object (value, nm_device_macvlan_get_parent (device)); + break; + case PROP_MODE: + g_value_set_string (value, nm_device_macvlan_get_mode (device)); + break; + case PROP_NO_PROMISC: + g_value_set_boolean (value, nm_device_macvlan_get_no_promisc (device)); + break; + case PROP_TAP: + g_value_set_boolean (value, nm_device_macvlan_get_tap (device)); + break; + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_macvlan_get_hw_address (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_macvlan_class_init (NMDeviceMacvlanClass *gre_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (gre_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class); + + g_type_class_add_private (gre_class, sizeof (NMDeviceMacvlanPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_MACVLAN); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceMacvlan:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_object (NM_DEVICE_MACVLAN_PARENT, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceMacvlan:mode: + * + * The MACVLAN mode. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceMacvlan:no-promisc: + * + * Whether the device has the no-promiscuos flag. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_NO_PROMISC, + g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceMacvlan:tap: + * + * Whether the device is a MACVTAP. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TAP, + g_param_spec_boolean (NM_DEVICE_MACVLAN_TAP, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceMacvlan:hw-address: + * + * The hardware (MAC) address of the device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_MACVLAN_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-macvlan.h b/libnm/nm-device-macvlan.h new file mode 100644 index 00000000..7ffb80c1 --- /dev/null +++ b/libnm/nm-device-macvlan.h @@ -0,0 +1,72 @@ +/* -*- 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_DEVICE_MACVLAN_H__ +#define __NM_DEVICE_MACVLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type ()) +#define NM_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) +#define NM_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) +#define NM_IS_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACVLAN)) +#define NM_IS_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACVLAN)) +#define NM_DEVICE_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) + +#define NM_DEVICE_MACVLAN_PARENT "parent" +#define NM_DEVICE_MACVLAN_MODE "mode" +#define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" +#define NM_DEVICE_MACVLAN_TAP "tap" +#define NM_DEVICE_MACVLAN_HW_ADDRESS "hw-address" + +struct _NMDeviceMacvlan { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceMacvlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_macvlan_get_type (void); + +NM_AVAILABLE_IN_1_2 +NMDevice * nm_device_macvlan_get_parent (NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_macvlan_get_mode (NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_macvlan_get_tap (NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_MACVLAN_H__ */ diff --git a/libnm/nm-device-modem.c b/libnm/nm-device-modem.c index dcbb447a..9fe5acb6 100644 --- a/libnm/nm-device-modem.c +++ b/libnm/nm-device-modem.c @@ -22,14 +22,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-modem.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-olpc-mesh.c b/libnm/nm-device-olpc-mesh.c index 108e5339..8e6cb1ab 100644 --- a/libnm/nm-device-olpc-mesh.c +++ b/libnm/nm-device-olpc-mesh.c @@ -21,13 +21,11 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include +#include "nm-default.h" #include "nm-device-olpc-mesh.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c index cff1d718..c38c58c1 100644 --- a/libnm/nm-device-team.c +++ b/libnm/nm-device-team.c @@ -21,14 +21,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-team.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-tun.c b/libnm/nm-device-tun.c new file mode 100644 index 00000000..ce2558f0 --- /dev/null +++ b/libnm/nm-device-tun.c @@ -0,0 +1,439 @@ +/* -*- 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 +#include + +#include +#include +#include + +#include "nm-default.h" +#include "nm-device-tun.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE) + +#define NM_DEVICE_TUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TUN, NMDeviceTunPrivate)) + +typedef struct { + char *hw_address; + char *mode; + gint64 owner; + gint64 group; + gboolean no_pi; + gboolean vnet_hdr; + gboolean multi_queue; +} NMDeviceTunPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_MODE, + PROP_OWNER, + PROP_GROUP, + PROP_NO_PI, + PROP_VNET_HDR, + PROP_MULTI_QUEUE, + + LAST_PROP +}; + +/** + * nm_device_tun_get_hw_address: + * @device: a #NMDeviceTun + * + * Gets the hardware (MAC) address of the #NMDeviceTun + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + **/ +const char * +nm_device_tun_get_hw_address (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), NULL); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_tun_get_mode: + * @device: a #NMDeviceTun + * + * Returns the TUN/TAP mode for the device. + * + * Returns: 'tun' or 'tap' + * + * Since: 1.2 + **/ +const char * +nm_device_tun_get_mode (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), NULL); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->mode; +} + +/** + * nm_device_tun_get_owner: + * @device: a #NMDeviceTun + * + * Gets the tunnel owner. + * + * Returns: the uid of the tunnel owner, or -1 if it has no owner. + * + * Since: 1.2 + **/ +gint64 +nm_device_tun_get_owner (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), -1); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->owner; +} + +/** + * nm_device_tun_get_group: + * @device: a #NMDeviceTun + * + * Gets the tunnel group. + * + * Returns: the gid of the tunnel group, or -1 if it has no owner. + * + * Since: 1.2 + **/ +gint64 +nm_device_tun_get_group (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), -1); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->group; +} + +/** + * nm_device_tun_get_pi: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_NO_PI flag. + * + * Returns: %TRUE if the device has the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_no_pi (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->no_pi; +} + +/** + * nm_device_tun_get_vnet_hdr: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_VNET_HDR flag. + * + * Returns: %TRUE if the device has the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_vnet_hdr (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->vnet_hdr; +} + +/** + * nm_device_tun_get_multi_queue: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_MULTI_QUEUE flag. + * + * Returns: %TRUE if the device doesn't have the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_multi_queue (NMDeviceTun *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TUN (device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE (device)->multi_queue; +} + +static int +tun_mode_from_string (const char *string) +{ + if (!g_strcmp0 (string, "tap")) + return NM_SETTING_TUN_MODE_TAP; + else + return NM_SETTING_TUN_MODE_TUN; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (device); + NMSettingTunMode mode; + NMSettingTun *s_tun; + + if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_TUN_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a tun connection.")); + return FALSE; + } + + s_tun = nm_connection_get_setting_tun (connection); + + mode = tun_mode_from_string (priv->mode); + if (s_tun && mode != nm_setting_tun_get_mode (s_tun)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The mode of the device and the connection didn't match")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_TUN; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_tun_get_hw_address (NM_DEVICE_TUN (device)); +} + +/***********************************************************/ + +static void +nm_device_tun_init (NMDeviceTun *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_TUN); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_TUN_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_TUN_MODE, &priv->mode }, + { NM_DEVICE_TUN_OWNER, &priv->owner }, + { NM_DEVICE_TUN_GROUP, &priv->group }, + { NM_DEVICE_TUN_NO_PI, &priv->no_pi }, + { NM_DEVICE_TUN_VNET_HDR, &priv->vnet_hdr }, + { NM_DEVICE_TUN_MULTI_QUEUE, &priv->multi_queue }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_tun_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_TUN, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); + + g_free (priv->mode); + + G_OBJECT_CLASS (nm_device_tun_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceTun *device = NM_DEVICE_TUN (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_tun_get_hw_address (device)); + break; + case PROP_MODE: + g_value_set_string (value, nm_device_tun_get_mode (device)); + break; + case PROP_OWNER: + g_value_set_int64 (value, nm_device_tun_get_owner (device)); + break; + case PROP_GROUP: + g_value_set_int64 (value, nm_device_tun_get_group (device)); + break; + case PROP_NO_PI: + g_value_set_boolean (value, nm_device_tun_get_no_pi (device)); + break; + case PROP_VNET_HDR: + g_value_set_boolean (value, nm_device_tun_get_vnet_hdr (device)); + break; + case PROP_MULTI_QUEUE: + g_value_set_boolean (value, nm_device_tun_get_multi_queue (device)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_tun_class_init (NMDeviceTunClass *gre_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (gre_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class); + + g_type_class_add_private (gre_class, sizeof (NMDeviceTunPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_TUN); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceTun:hw-address: + * + * The hardware (MAC) address of the device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_TUN_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:mode: + * + * The tunnel mode, either "tun" or "tap". + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_string (NM_DEVICE_TUN_MODE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:owner: + * + * The uid of the tunnel owner, or -1 if it has no owner. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_OWNER, + g_param_spec_int64 (NM_DEVICE_TUN_OWNER, "", "", + -1, G_MAXUINT32, -1, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:group: + * + * The gid of the tunnel group, or -1 if it has no owner. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_GROUP, + g_param_spec_int64 (NM_DEVICE_TUN_GROUP, "", "", + -1, G_MAXUINT32, -1, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:no-pi: + * + * The tunnel's "TUN_NO_PI" flag; true if no protocol info is + * prepended to the tunnel packets. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_NO_PI, + g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:vnet-hdr: + * + * The tunnel's "TUN_VNET_HDR" flag; true if the tunnel packets + * include a virtio network header. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_VNET_HDR, + g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTun:multi-queue: + * + * The tunnel's "TUN_TAP_MQ" flag; true if callers can connect to + * the tap device multiple times, for multiple send/receive + * queues. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MULTI_QUEUE, + g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-tun.h b/libnm/nm-device-tun.h new file mode 100644 index 00000000..b83e2b3f --- /dev/null +++ b/libnm/nm-device-tun.h @@ -0,0 +1,78 @@ +/* -*- 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_DEVICE_TUN_H__ +#define __NM_DEVICE_TUN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type ()) +#define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) +#define NM_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) +#define NM_IS_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TUN)) +#define NM_IS_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TUN)) +#define NM_DEVICE_TUN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) + +#define NM_DEVICE_TUN_HW_ADDRESS "hw-address" +#define NM_DEVICE_TUN_OWNER "owner" +#define NM_DEVICE_TUN_GROUP "group" +#define NM_DEVICE_TUN_MODE "mode" +#define NM_DEVICE_TUN_NO_PI "no-pi" +#define NM_DEVICE_TUN_VNET_HDR "vnet-hdr" +#define NM_DEVICE_TUN_MULTI_QUEUE "multi-queue" + +struct _NMDeviceTun { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceTunClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_tun_get_type (void); + +NM_AVAILABLE_IN_1_2 +const char * nm_device_tun_get_hw_address (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_tun_get_mode (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gint64 nm_device_tun_get_owner (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gint64 nm_device_tun_get_group (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_no_pi (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_vnet_hdr (NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_multi_queue (NMDeviceTun *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_TUN_H__ */ diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c index fb6e3bd7..b285eea9 100644 --- a/libnm/nm-device-vlan.c +++ b/libnm/nm-device-vlan.c @@ -21,15 +21,13 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include #include +#include "nm-default.h" #include "nm-device-vlan.h" #include "nm-device-private.h" #include "nm-object-private.h" diff --git a/libnm/nm-device-vxlan.c b/libnm/nm-device-vxlan.c new file mode 100644 index 00000000..4718080e --- /dev/null +++ b/libnm/nm-device-vxlan.c @@ -0,0 +1,815 @@ +/* -*- 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 + +#include +#include +#include + +#include "nm-default.h" +#include "nm-device-vxlan.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanPrivate)) + +typedef struct { + NMDevice *parent; + char *hw_address; + gboolean carrier; + guint id; + char *group; + char *local; + guint src_port_min; + guint src_port_max; + guint dst_port; + guint tos; + guint ttl; + guint limit; + gboolean learning; + guint ageing; + gboolean proxy; + gboolean rsc; + gboolean l2miss; + gboolean l3miss; +} NMDeviceVxlanPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_PARENT, + PROP_ID, + PROP_GROUP, + PROP_LOCAL, + PROP_TOS, + PROP_TTL, + PROP_LIMIT, + PROP_LEARNING, + PROP_AGEING, + PROP_DST_PORT, + PROP_SRC_PORT_MIN, + PROP_SRC_PORT_MAX, + PROP_PROXY, + PROP_RSC, + PROP_L2MISS, + PROP_L3MISS, + + LAST_PROP +}; + +/** + * nm_device_vxlan_get_hw_address: + * @device: a #NMDeviceVxlan + * + * Gets the hardware (MAC) address of the #NMDeviceVxlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + **/ +const char * +nm_device_vxlan_get_hw_address (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_vxlan_get_carrier: + * @device: a #NMDeviceVxlan + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier. + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_carrier (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_vxlan_get_parent: + * @device: a #NMDeviceVxlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_vxlan_get_parent (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->parent; +} + +/** + * nm_device_vxlan_get_id: + * @device: a #NMDeviceVxlan + * + * Returns: the device's VXLAN ID. + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_id (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->id; +} + +/** + * nm_device_vxlan_get_group: + * @device: a #NMDeviceVxlan + * + * Returns: The unicast destination IP address or the multicast + * IP address joined + * + * Since: 1.2 + **/ +const char * +nm_device_vxlan_get_group (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->group; +} + +/** + * nm_device_vxlan_get_local: + * @device: a #NMDeviceVxlan + * + * Returns: the source IP address to use in outgoing packets + * + * Since: 1.2 + **/ +const char * +nm_device_vxlan_get_local (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->local; +} + +/** + * nm_device_vxlan_get_src_port_min: + * @device: a #NMDeviceVxlan + * + * Returns: the minimum UDP source port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_src_port_min (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->src_port_min; +} + +/** + * nm_device_vxlan_get_src_port_max: + * @device: a #NMDeviceVxlan + * + * Returns: the maximum UDP source port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_src_port_max (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->src_port_max; +} + +/** + * nm_device_vxlan_get_dst_port: + * @device: a #NMDeviceVxlan + * + * Returns: the UDP destination port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_dst_port (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->dst_port; +} + +/** + * nm_device_vxlan_get_learning: + * @device: a #NMDeviceVxlan + * + * Returns: whether address learning is enabled + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_learning (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->learning; +} + +/** + * nm_device_vxlan_get_ageing: + * @device: a #NMDeviceVxlan + * + * Returns: the lifetime in seconds of FDB entries learnt by the kernel + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_ageing (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->ageing; +} + +/** + * nm_device_vxlan_get_tos: + * @device: a #NMDeviceVxlan + * + * Returns: the TOS value to use in outgoing packets + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_tos (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->tos; +} + +/** + * nm_device_vxlan_get_ttl: + * @device: a #NMDeviceVxlan + * + * Returns: the time-to-live value to use in outgoing packets + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_ttl (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->ttl; +} + +/** + * nm_device_vxlan_get_limit: + * @device: a #NMDeviceVxlan + * + * Returns: the maximum number of entries that can be added to the + * forwarding table + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_limit (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->limit; +} + +/** + * nm_device_vxlan_get_proxy: + * @device: a #NMDeviceVxlan + * + * Returns: whether ARP proxy is turned on + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_proxy (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->proxy; +} + +/** + * nm_device_vxlan_get_rsc: + * @device: a #NMDeviceVxlan + * + * Returns: whether route short circuit is turned on + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_rsc (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->rsc; +} + +/** + * nm_device_vxlan_get_l2miss: + * @device: a #NMDeviceVxlan + * + * Returns: whether netlink LL ADDR miss notifications are generated + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_l2miss (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->l2miss; +} + +/** + * nm_device_vxlan_get_l3miss: + * @device: a #NMDeviceVxlan + * + * Returns: wether netlink IP ADDR miss notifications are generated + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_l3miss (NMDeviceVxlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE (device)->l3miss; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVxlan *s_vxlan; + + if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VXLAN connection.")); + return FALSE; + } + + s_vxlan = nm_connection_get_setting_vxlan (connection); + if (nm_setting_vxlan_get_id (s_vxlan) != nm_device_vxlan_get_id (NM_DEVICE_VXLAN (device))) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VXLAN identifiers of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_VXLAN; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_vxlan_get_hw_address (NM_DEVICE_VXLAN (device)); +} + +/***********************************************************/ + +static void +nm_device_vxlan_init (NMDeviceVxlan *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_VXLAN); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_VXLAN_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_VXLAN_CARRIER, &priv->carrier }, + { NM_DEVICE_VXLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE }, + { NM_DEVICE_VXLAN_ID, &priv->id }, + { NM_DEVICE_VXLAN_GROUP, &priv->group }, + { NM_DEVICE_VXLAN_LOCAL, &priv->local }, + { NM_DEVICE_VXLAN_SRC_PORT_MIN, &priv->src_port_min }, + { NM_DEVICE_VXLAN_SRC_PORT_MAX, &priv->src_port_max }, + { NM_DEVICE_VXLAN_DST_PORT, &priv->dst_port }, + { NM_DEVICE_VXLAN_TOS, &priv->tos }, + { NM_DEVICE_VXLAN_TTL, &priv->ttl }, + { NM_DEVICE_VXLAN_LIMIT, &priv->limit }, + { NM_DEVICE_VXLAN_LEARNING, &priv->learning }, + { NM_DEVICE_VXLAN_AGEING, &priv->ageing }, + { NM_DEVICE_VXLAN_PROXY, &priv->proxy }, + { NM_DEVICE_VXLAN_RSC, &priv->rsc }, + { NM_DEVICE_VXLAN_L2MISS, &priv->l2miss }, + { NM_DEVICE_VXLAN_L3MISS, &priv->l3miss }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_vxlan_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_VXLAN, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_clear_object (&priv->parent); + + G_OBJECT_CLASS (nm_device_vxlan_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceVxlan *device = NM_DEVICE_VXLAN (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_vxlan_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_vxlan_get_carrier (device)); + break; + case PROP_PARENT: + g_value_set_object (value, nm_device_vxlan_get_parent (device)); + break; + case PROP_ID: + g_value_set_uint (value, nm_device_vxlan_get_id (device)); + break; + case PROP_GROUP: + g_value_set_string (value, nm_device_vxlan_get_group (device)); + break; + case PROP_LOCAL: + g_value_set_string (value, nm_device_vxlan_get_local (device)); + break; + case PROP_TOS: + g_value_set_uint (value, nm_device_vxlan_get_tos (device)); + break; + case PROP_TTL: + g_value_set_uint (value, nm_device_vxlan_get_ttl (device)); + break; + case PROP_LIMIT: + g_value_set_uint (value, nm_device_vxlan_get_limit (device)); + break; + case PROP_LEARNING: + g_value_set_boolean (value, nm_device_vxlan_get_learning (device)); + break; + case PROP_AGEING: + g_value_set_uint (value, nm_device_vxlan_get_ageing (device)); + break; + case PROP_DST_PORT: + g_value_set_uint (value, nm_device_vxlan_get_dst_port (device)); + break; + case PROP_SRC_PORT_MIN: + g_value_set_uint (value, nm_device_vxlan_get_src_port_min (device)); + break; + case PROP_SRC_PORT_MAX: + g_value_set_uint (value, nm_device_vxlan_get_src_port_max (device)); + break; + case PROP_PROXY: + g_value_set_boolean (value, nm_device_vxlan_get_proxy (device)); + break; + case PROP_RSC: + g_value_set_boolean (value, nm_device_vxlan_get_rsc (device)); + break; + case PROP_L2MISS: + g_value_set_boolean (value, nm_device_vxlan_get_l2miss (device)); + break; + case PROP_L3MISS: + g_value_set_boolean (value, nm_device_vxlan_get_l3miss (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_vxlan_class_init (NMDeviceVxlanClass *vxlan_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (vxlan_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vxlan_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (vxlan_class); + + g_type_class_add_private (vxlan_class, sizeof (NMDeviceVxlanPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_VXLAN); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceVxlan:hw-address: + * + * The hardware (MAC) address of the device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_VXLAN_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:carrier: + * + * Whether the device has carrier. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_VXLAN_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_object (NM_DEVICE_VXLAN_PARENT, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:id: + * + * The device's VXLAN ID. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_uint (NM_DEVICE_VXLAN_ID, "", "", + 0, (1 << 24) - 1, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:group: + * + * The unicast destination IP address used in outgoing packets when the + * destination link layer address is not known in the VXLAN device + * forwarding database or the multicast IP address joined. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_GROUP, + g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:local: + * + * 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_DEVICE_VXLAN_LOCAL, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:tos: + * + * The TOS value to use in outgoing packets. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_TOS, + g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, "", "", + 0, 255, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:ttl: + * + * 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_uchar (NM_DEVICE_VXLAN_TTL, "", "", + 0, 255, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:learning: + * + * 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_DEVICE_VXLAN_LEARNING, "", "", + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:ageing: + * + * 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_DEVICE_VXLAN_AGEING, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:limit: + * + * The maximum number of entries that can be added to the forwarding table. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_LIMIT, + g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:dst-port: + * + * The UDP destination port used to communicate with the remote VXLAN tunnel + * endpoint. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_DST_PORT, + g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", + 0, 65535, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:src-port-min: + * + * The minimum UDP source port used to communicate with the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_SRC_PORT_MIN, + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "", + 0, 65535, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:src-port-max: + * + * The maximum UDP source port used to communicate with the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_SRC_PORT_MAX, + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "", + 0, 65535, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:proxy: + * + * Whether ARP proxy is turned on. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_PROXY, + g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:rsc: + * + * Whether route short circuit is turned on. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_RSC, + g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:l2miss: + * + * Whether netlink LL ADDR miss notifications are generated. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_L2MISS, + g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVxlan:l3miss: + * + * Whether netlink IP ADDR miss notifications are generated. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_L3MISS, + g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-vxlan.h b/libnm/nm-device-vxlan.h new file mode 100644 index 00000000..1fb63597 --- /dev/null +++ b/libnm/nm-device-vxlan.h @@ -0,0 +1,110 @@ +/* -*- 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_DEVICE_VXLAN_H__ +#define __NM_DEVICE_VXLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type ()) +#define NM_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) +#define NM_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) +#define NM_IS_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VXLAN)) +#define NM_IS_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VXLAN)) +#define NM_DEVICE_VXLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) + +#define NM_DEVICE_VXLAN_HW_ADDRESS "hw-address" +#define NM_DEVICE_VXLAN_CARRIER "carrier" +#define NM_DEVICE_VXLAN_PARENT "parent" +#define NM_DEVICE_VXLAN_ID "id" +#define NM_DEVICE_VXLAN_GROUP "group" +#define NM_DEVICE_VXLAN_LOCAL "local" +#define NM_DEVICE_VXLAN_SRC_PORT_MIN "src-port-min" +#define NM_DEVICE_VXLAN_SRC_PORT_MAX "src-port-max" +#define NM_DEVICE_VXLAN_LEARNING "learning" +#define NM_DEVICE_VXLAN_AGEING "ageing" +#define NM_DEVICE_VXLAN_TOS "tos" +#define NM_DEVICE_VXLAN_TTL "ttl" +#define NM_DEVICE_VXLAN_LIMIT "limit" +#define NM_DEVICE_VXLAN_PROXY "proxy" +#define NM_DEVICE_VXLAN_RSC "rsc" +#define NM_DEVICE_VXLAN_L2MISS "l2miss" +#define NM_DEVICE_VXLAN_L3MISS "l3miss" +#define NM_DEVICE_VXLAN_DST_PORT "dst-port" + +struct _NMDeviceVxlan { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceVxlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_vxlan_get_type (void); +NM_AVAILABLE_IN_1_2 +const char * nm_device_vxlan_get_hw_address (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_carrier (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +NMDevice * nm_device_vxlan_get_parent (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_id (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_vxlan_get_group (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +const char * nm_device_vxlan_get_local (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_src_port_min (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_src_port_max (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_dst_port (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_learning (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_ageing (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_tos (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_ttl (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_limit (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_proxy (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_rsc (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_l2miss (NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_l3miss (NMDeviceVxlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VXLAN_H__ */ diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c index 536f3082..9019e038 100644 --- a/libnm/nm-device-wifi.c +++ b/libnm/nm-device-wifi.c @@ -22,15 +22,13 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include #include +#include "nm-default.h" #include "nm-device-wifi.h" #include "nm-access-point.h" #include "nm-device-private.h" @@ -38,6 +36,7 @@ #include "nm-object-cache.h" #include "nm-core-internal.h" #include "nm-dbus-helpers.h" +#include "nm-macros-internal.h" #include "nmdbus-device-wifi.h" @@ -356,7 +355,7 @@ nm_device_wifi_request_scan (NMDeviceWifi *device, * Returns: %TRUE on success, %FALSE on error, in which case @error will be * set. * - * Since: 1.0.6 + * Since: 1.2 **/ gboolean nm_device_wifi_request_scan_options (NMDeviceWifi *device, @@ -367,6 +366,10 @@ nm_device_wifi_request_scan_options (NMDeviceWifi *device, return _device_wifi_request_scan (device, options, cancellable, error); } +NM_BACKPORT_SYMBOL (libnm_1_0_6, gboolean, nm_device_wifi_request_scan_options, + (NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, GError **error), + (device, options, cancellable, error)); + static void request_scan_cb (GObject *source, GAsyncResult *result, @@ -464,7 +467,7 @@ nm_device_wifi_request_scan_async (NMDeviceWifi *device, * D-Bus call. Valid otions inside the dictionary are: * 'ssids' => array of SSIDs (saay) * - * Since: 1.0.6 + * Since: 1.2 **/ void nm_device_wifi_request_scan_options_async (NMDeviceWifi *device, @@ -476,6 +479,10 @@ nm_device_wifi_request_scan_options_async (NMDeviceWifi *device, _device_wifi_request_scan_async (device, options, cancellable, callback, user_data); } +NM_BACKPORT_SYMBOL (libnm_1_0_6, void, nm_device_wifi_request_scan_options_async, + (NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), + (device, options, cancellable, callback, user_data)); + /** * nm_device_wifi_request_scan_finish: * @device: a #NMDeviceWifi diff --git a/libnm/nm-device-wifi.h b/libnm/nm-device-wifi.h index b5a56980..b5974ba2 100644 --- a/libnm/nm-device-wifi.h +++ b/libnm/nm-device-wifi.h @@ -77,7 +77,7 @@ const GPtrArray * nm_device_wifi_get_access_points (NMDeviceWifi * gboolean nm_device_wifi_request_scan (NMDeviceWifi *device, GCancellable *cancellable, GError **error); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 gboolean nm_device_wifi_request_scan_options (NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, @@ -86,7 +86,7 @@ void nm_device_wifi_request_scan_async (NMDeviceWifi * GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 void nm_device_wifi_request_scan_options_async (NMDeviceWifi *device, GVariant *options, GCancellable *cancellable, diff --git a/libnm/nm-device-wimax.c b/libnm/nm-device-wimax.c index f199b669..55658a59 100644 --- a/libnm/nm-device-wimax.c +++ b/libnm/nm-device-wimax.c @@ -22,14 +22,12 @@ #include "config.h" #include -#include - -#include "nm-glib-compat.h" #include #include #include +#include "nm-default.h" #include "nm-device-wimax.h" #include "nm-wimax-nsp.h" #include "nm-object-private.h" @@ -86,6 +84,8 @@ static guint signals[LAST_SIGNAL] = { 0 }; * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ const char * nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) @@ -102,6 +102,8 @@ nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) * Gets the active #NMWimaxNsp. * * Returns: (transfer full): the access point or %NULL if none is active + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ NMWimaxNsp * nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) @@ -138,6 +140,8 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) * Returns: (element-type NMWimaxNsp): a #GPtrArray containing * all the scanned #NMWimaxNsps. * The returned array is owned by the client and should not be modified. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ const GPtrArray * nm_device_wimax_get_nsps (NMDeviceWimax *wimax) @@ -155,6 +159,8 @@ nm_device_wimax_get_nsps (NMDeviceWimax *wimax) * Gets a #NMWimaxNsp by path. * * Returns: (transfer none): the access point or %NULL if none is found. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ NMWimaxNsp * nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, @@ -208,6 +214,8 @@ clean_up_nsps (NMDeviceWimax *self) * device is not connected. * * Returns: the center frequency in KHz, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ guint nm_device_wimax_get_center_frequency (NMDeviceWimax *self) @@ -227,6 +235,8 @@ nm_device_wimax_get_center_frequency (NMDeviceWimax *self) * device is not connected. * * Returns: the RSSI in dBm, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ gint nm_device_wimax_get_rssi (NMDeviceWimax *self) @@ -245,6 +255,8 @@ nm_device_wimax_get_rssi (NMDeviceWimax *self) * meaning when the device is not connected. * * Returns: the CINR in dB, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ gint nm_device_wimax_get_cinr (NMDeviceWimax *self) @@ -263,6 +275,8 @@ nm_device_wimax_get_cinr (NMDeviceWimax *self) * -5.5 dBm. Has no meaning when the device is not connected. * * Returns: the TX power in dBm, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ gint nm_device_wimax_get_tx_power (NMDeviceWimax *self) @@ -279,6 +293,8 @@ nm_device_wimax_get_tx_power (NMDeviceWimax *self) * Gets the ID of the serving Base Station when the device is connected. * * Returns: the ID of the serving Base Station, or %NULL + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ const char * nm_device_wimax_get_bsid (NMDeviceWimax *self) @@ -536,6 +552,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * NMDeviceWimax:hw-address: * * The hardware (MAC) address of the device. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, @@ -548,6 +566,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * NMDeviceWimax:active-nsp: * * The active #NMWimaxNsp of the device. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_ACTIVE_NSP, @@ -562,6 +582,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * The center frequency (in KHz) of the radio channel the device is using to * communicate with the network when connected. Has no meaning when the * device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_CENTER_FREQ, @@ -577,6 +599,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * the raw received RF signal from the base station is, but does not * indicate the overall quality of the radio link. Has no meaning when the * device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_RSSI, @@ -591,6 +615,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * CINR (Carrier to Interference + Noise Ratio) of the current radio link * in dB. CINR is a more accurate measure of radio link quality. Has no * meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_CINR, @@ -605,6 +631,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * Average power of the last burst transmitted by the device, in units of * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of * -5.5 dBm. Has no meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_TX_POWER, @@ -618,6 +646,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * * The ID of the serving base station as received from the network. Has * no meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ g_object_class_install_property (object_class, PROP_BSID, @@ -648,6 +678,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * @nsp: the new NSP * * Notifies that a #NMWimaxNsp is added to the wimax device. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ signals[NSP_ADDED] = g_signal_new ("nsp-added", @@ -665,6 +697,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) * @nsp: the removed NSP * * Notifies that a #NMWimaxNsp is removed from the wimax device. + * + * Deprecated: 1.2: WiMAX is no longer supported. **/ signals[NSP_REMOVED] = g_signal_new ("nsp-removed", diff --git a/libnm/nm-device-wimax.h b/libnm/nm-device-wimax.h index 60910984..cdd6ba56 100644 --- a/libnm/nm-device-wimax.h +++ b/libnm/nm-device-wimax.h @@ -61,19 +61,29 @@ typedef struct { gpointer padding[4]; } NMDeviceWimaxClass; +NM_DEPRECATED_IN_1_2 GType nm_device_wimax_get_type (void); +NM_DEPRECATED_IN_1_2 const char *nm_device_wimax_get_hw_address (NMDeviceWimax *wimax); +NM_DEPRECATED_IN_1_2 NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax); +NM_DEPRECATED_IN_1_2 NMWimaxNsp *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, const char *path); +NM_DEPRECATED_IN_1_2 const GPtrArray *nm_device_wimax_get_nsps (NMDeviceWimax *wimax); +NM_DEPRECATED_IN_1_2 guint nm_device_wimax_get_center_frequency (NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 gint nm_device_wimax_get_rssi (NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 gint nm_device_wimax_get_cinr (NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 gint nm_device_wimax_get_tx_power (NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 const char * nm_device_wimax_get_bsid (NMDeviceWimax *self); G_END_DECLS diff --git a/libnm/nm-device.c b/libnm/nm-device.c index d3ac705c..7d57b526 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -23,9 +23,9 @@ #include -#include #include +#include "nm-default.h" #include "nm-dbus-interface.h" #include "nm-active-connection.h" #include "nm-device-ethernet.h" @@ -40,7 +40,10 @@ #include "nm-device-team.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" +#include "nm-device-vxlan.h" #include "nm-device-generic.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macvlan.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-dhcp4-config.h" @@ -51,15 +54,17 @@ #include "nm-object-cache.h" #include "nm-remote-connection.h" #include "nm-core-internal.h" -#include "nm-glib-compat.h" #include "nm-utils.h" #include "nm-dbus-helpers.h" +#include "nm-device-tun.h" #include "nm-setting-connection.h" +#include "nm-macros-internal.h" #include "nmdbus-device.h" static GType _nm_device_decide_type (GVariant *value); gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); +static NMLldpNeighbor *nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor); G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, _nm_object_register_type_func (g_define_type_id, @@ -83,8 +88,10 @@ typedef struct { char *type_description; NMMetered metered; NMDeviceCapabilities capabilities; + gboolean real; gboolean managed; gboolean firmware_missing; + gboolean nm_plugin_missing; gboolean autoconnect; NMIPConfig *ip4_config; NMDhcpConfig *dhcp4_config; @@ -104,6 +111,7 @@ typedef struct { char *physical_port_id; guint32 mtu; + GPtrArray *lldp_neighbors; } NMDevicePrivate; enum { @@ -114,9 +122,11 @@ enum { PROP_DRIVER_VERSION, PROP_FIRMWARE_VERSION, PROP_CAPABILITIES, + PROP_REAL, PROP_MANAGED, PROP_AUTOCONNECT, PROP_FIRMWARE_MISSING, + PROP_NM_PLUGIN_MISSING, PROP_IP4_CONFIG, PROP_DHCP4_CONFIG, PROP_IP6_CONFIG, @@ -132,6 +142,7 @@ enum { PROP_PHYSICAL_PORT_ID, PROP_MTU, PROP_METERED, + PROP_LLDP_NEIGHBORS, LAST_PROP }; @@ -144,6 +155,13 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +struct _NMLldpNeighbor { + guint refcount; + GHashTable *attrs; +}; + +G_DEFINE_BOXED_TYPE (NMLldpNeighbor, nm_lldp_neighbor, nm_lldp_neighbor_dup, nm_lldp_neighbor_unref) + static void nm_device_init (NMDevice *device) { @@ -151,6 +169,7 @@ nm_device_init (NMDevice *device) priv->state = NM_DEVICE_STATE_UNKNOWN; priv->reason = NM_DEVICE_STATE_REASON_NONE; + priv->lldp_neighbors = g_ptr_array_new (); } static gboolean @@ -163,6 +182,38 @@ demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gp return TRUE; } +static gboolean +demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + GVariantIter iter, attrs_iter; + GVariant *variant, *attr_variant; + const char *attr_name; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE); + + g_ptr_array_unref (priv->lldp_neighbors); + priv->lldp_neighbors = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref); + g_variant_iter_init (&iter, value); + + while (g_variant_iter_next (&iter, "@a{sv}", &variant)) { + NMLldpNeighbor *neigh; + + neigh = nm_lldp_neighbor_new (); + g_variant_iter_init (&attrs_iter, variant); + + while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_variant)) + g_hash_table_insert (neigh->attrs, g_strdup (attr_name), attr_variant); + + g_variant_unref (variant); + g_ptr_array_add (priv->lldp_neighbors, neigh); + } + + _nm_object_queue_notify (object, NM_DEVICE_LLDP_NEIGHBORS); + + return TRUE; +} + static void device_state_changed (NMDBusDevice *proxy, guint new_state, @@ -182,9 +233,11 @@ init_dbus (NMObject *object) { NM_DEVICE_DRIVER_VERSION, &priv->driver_version }, { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version }, { NM_DEVICE_CAPABILITIES, &priv->capabilities }, + { NM_DEVICE_REAL, &priv->real }, { NM_DEVICE_MANAGED, &priv->managed }, { NM_DEVICE_AUTOCONNECT, &priv->autoconnect }, { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing }, + { NM_DEVICE_NM_PLUGIN_MISSING, &priv->nm_plugin_missing }, { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG }, { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG }, { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG }, @@ -196,6 +249,7 @@ init_dbus (NMObject *object) { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id }, { NM_DEVICE_MTU, &priv->mtu }, { NM_DEVICE_METERED, &priv->metered }, + { NM_DEVICE_LLDP_NEIGHBORS, &priv->lldp_neighbors, demarshal_lldp_neighbors }, /* Properties that exist in D-Bus but that we don't track */ { "ip4-address", NULL }, @@ -315,6 +369,14 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype) return NM_TYPE_DEVICE_VLAN; case NM_DEVICE_TYPE_GENERIC: return NM_TYPE_DEVICE_GENERIC; + case NM_DEVICE_TYPE_TUN: + return NM_TYPE_DEVICE_TUN; + case NM_DEVICE_TYPE_IP_TUNNEL: + return NM_TYPE_DEVICE_IP_TUNNEL; + case NM_DEVICE_TYPE_MACVLAN: + return NM_TYPE_DEVICE_MACVLAN; + case NM_DEVICE_TYPE_VXLAN: + return NM_TYPE_DEVICE_VXLAN; default: g_warning ("Unknown device type %d", dtype); return G_TYPE_INVALID; @@ -347,6 +409,7 @@ dispose (GObject *object) g_clear_object (&priv->active_connection); g_clear_pointer (&priv->available_connections, g_ptr_array_unref); + g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref); G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); } @@ -407,6 +470,9 @@ get_property (GObject *object, case PROP_CAPABILITIES: g_value_set_flags (value, nm_device_get_capabilities (device)); break; + case PROP_REAL: + g_value_set_boolean (value, nm_device_is_real (device)); + break; case PROP_MANAGED: g_value_set_boolean (value, nm_device_get_managed (device)); break; @@ -416,6 +482,9 @@ get_property (GObject *object, case PROP_FIRMWARE_MISSING: g_value_set_boolean (value, nm_device_get_firmware_missing (device)); break; + case PROP_NM_PLUGIN_MISSING: + g_value_set_boolean (value, nm_device_get_nm_plugin_missing (device)); + break; case PROP_IP4_CONFIG: g_value_set_object (value, nm_device_get_ip4_config (device)); break; @@ -455,6 +524,9 @@ get_property (GObject *object, case PROP_METERED: g_value_set_uint (value, nm_device_get_metered (device)); break; + case PROP_LLDP_NEIGHBORS: + g_value_set_boxed (value, nm_device_get_lldp_neighbors (device)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -476,6 +548,11 @@ set_property (GObject *object, /* Construct only */ priv->device_type = g_value_get_enum (value); break; + case PROP_MANAGED: + b = g_value_get_boolean (value); + if (priv->managed != b) + nm_device_set_managed (NM_DEVICE (object), b); + break; case PROP_AUTOCONNECT: b = g_value_get_boolean (value); if (priv->autoconnect != b) @@ -614,6 +691,22 @@ nm_device_class_init (NMDeviceClass *device_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMDevice:real: + * + * Whether the device is real or is a placeholder device that could + * be created automatically by NetworkManager if one of its + * #NMDevice:available-connections was activated. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_REAL, + g_param_spec_boolean (NM_DEVICE_REAL, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * NMDevice:managed: * @@ -651,6 +744,21 @@ nm_device_class_init (NMDeviceClass *device_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMDevice:nm-plugin-missing: + * + * When %TRUE indicates that the NetworkManager plugin for the device + * is not installed. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_NM_PLUGIN_MISSING, + g_param_spec_boolean (NM_DEVICE_NM_PLUGIN_MISSING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * NMDevice:ip4-config: * @@ -804,7 +912,7 @@ nm_device_class_init (NMDeviceClass *device_class) * * Whether the device is metered. * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_METERED, @@ -813,6 +921,18 @@ nm_device_class_init (NMDeviceClass *device_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMDevice:lldp-neighbors: + * + * The LLDP neighbors. + **/ + g_object_class_install_property + (object_class, PROP_LLDP_NEIGHBORS, + g_param_spec_boxed (NM_DEVICE_LLDP_NEIGHBORS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /* signals */ /** @@ -1073,6 +1193,30 @@ nm_device_get_managed (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->managed; } +/** + * nm_device_set_managed: + * @device: a #NMDevice + * @managed: %TRUE to make the device managed by NetworkManager. + * + * Enables or disables management of #NMDevice by NetworkManager. + * + * Since: 1.2 + **/ +void +nm_device_set_managed (NMDevice *device, gboolean managed) +{ + g_return_if_fail (NM_IS_DEVICE (device)); + + managed = !!managed; + + NM_DEVICE_GET_PRIVATE (device)->managed = managed; + + _nm_object_set_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Managed", + "b", managed); +} + /** * nm_device_get_autoconnect: * @device: a #NMDevice @@ -1127,6 +1271,24 @@ nm_device_get_firmware_missing (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->firmware_missing; } +/** + * nm_device_get_nm_plugin_missing: + * @device: a #NMDevice + * + * Indicates that the NetworkManager plugin for the device is not installed. + * + * Returns: %TRUE if the device plugin not installed. + * + * Since: 1.2 + **/ +gboolean +nm_device_get_nm_plugin_missing (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return NM_DEVICE_GET_PRIVATE (device)->nm_plugin_missing; +} + /** * nm_device_get_ip4_config: * @device: a #NMDevice @@ -1406,14 +1568,16 @@ nm_device_get_product (NMDevice *device) g_return_val_if_fail (NM_IS_DEVICE (device), NULL); priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->product) { + if (!priv->product) priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); - if (!priv->product) { - /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ - priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); - } - _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT); - } + + /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ + if (!priv->product) + priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); + + if (!priv->product) + priv->product = g_strdup (""); + return priv->product; } @@ -1434,10 +1598,13 @@ nm_device_get_vendor (NMDevice *device) g_return_val_if_fail (NM_IS_DEVICE (device), NULL); priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->vendor) { + + if (!priv->vendor) priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); - _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR); - } + + if (!priv->vendor) + priv->vendor = g_strdup (""); + return priv->vendor; } @@ -1836,6 +2003,25 @@ nm_device_disambiguate_names (NMDevice **devices, if (!find_duplicates (names, duplicates, num_devices)) goto done; + /* If dealing with Bluetooth devices, try to distinguish them by + * device name. + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i] && NM_IS_DEVICE_BT (devices[i])) { + const char *devname = nm_device_bt_get_name (NM_DEVICE_BT (devices[i])); + + if (!devname) + continue; + + g_free (names[i]); + names[i] = g_strdup_printf ("%s (%s)", + get_device_type_name_with_iface (devices[i]), + devname); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + /* We have multiple identical network cards, so we have to differentiate * them by interface name. */ @@ -1911,7 +2097,7 @@ nm_device_get_mtu (NMDevice *device) * * Returns: the metered setting. * - * Since: 1.0.6 + * Since: 1.2 **/ NMMetered nm_device_get_metered (NMDevice *device) @@ -1921,6 +2107,47 @@ nm_device_get_metered (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->metered; } +NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_device_get_metered, (NMDevice *device), (device)); + +/** + * nm_device_get_lldp_neighbors: + * @device: a #NMDevice + * + * Gets the list of neighbors discovered through LLDP. + * + * Returns: (element-type NMLldpNeighbor) (transfer none): the #GPtrArray + * containing #NMLldpNeighbors. This is the internal copy used by the + * device and must not be modified. The library never modifies the returned + * array and thus it is safe for callers to reference and keep using it. + * + * Since: 1.2 + **/ +GPtrArray * +nm_device_get_lldp_neighbors (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->lldp_neighbors; +} + +/** + * nm_device_is_real: + * @device: a #NMDevice + * + * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device + * that could be automatically created by NetworkManager if one of its + * #NMDevice:available-connections was activated. + * + * Since: 1.2 + **/ +gboolean +nm_device_is_real (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return NM_DEVICE_GET_PRIVATE (device)->real; +} + /** * nm_device_is_software: * @device: a #NMDevice @@ -1937,6 +2164,134 @@ nm_device_is_software (NMDevice *device) return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); } +/** + * nm_device_reapply: + * @device: a #NMDevice + * @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing + * @flags: always set this to zero + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Attempts to update device with changes to the currently active connection + * made since it was last applied. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Since: 1.2 + **/ +gboolean +nm_device_reapply (NMDevice *device, + NMConnection *connection, + guint flags, + GCancellable *cancellable, + GError **error) +{ + GVariant *dict = NULL; + gboolean ret; + + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + if (connection) + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + if (!dict) + dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + + + ret = nmdbus_device_call_reapply_sync (NM_DEVICE_GET_PRIVATE (device)->proxy, + dict, flags, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +device_reapply_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_device_call_reapply_finish (NMDBUS_DEVICE (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_device_reapply_async: + * @device: a #NMDevice + * @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing + * @flags: always set this to zero + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the reapply operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins an attempt to update device with changes to the + * currently active connection made since it was last applied. + * + * Since: 1.2 + **/ +void +nm_device_reapply_async (NMDevice *device, + NMConnection *connection, + guint flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant *dict = NULL; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_DEVICE (device)); + + if (connection) + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + if (!dict) + dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_reapply_async); + + nmdbus_device_call_reapply (NM_DEVICE_GET_PRIVATE (device)->proxy, + dict, flags, cancellable, + device_reapply_cb, simple); +} + +/** + * nm_device_reapply_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_reapply_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + * + * Since: 1.2 + **/ +gboolean +nm_device_reapply_finish (NMDevice *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_reapply_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + /** * nm_device_disconnect: * @device: a #NMDevice @@ -2271,3 +2626,193 @@ nm_device_get_setting_type (NMDevice *device) return NM_DEVICE_GET_CLASS (device)->get_setting_type (device); } + +/** + * nm_lldp_neighbor_new: + * + * Creates a new #NMLldpNeighbor object. + * + * Returns: (transfer full): the new #NMLldpNeighbor object. + * + * Since: 1.2 + **/ +NMLldpNeighbor * +nm_lldp_neighbor_new (void) +{ + NMLldpNeighbor *neigh; + + neigh = g_new0 (NMLldpNeighbor, 1); + neigh->refcount = 1; + neigh->attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) g_variant_unref); + + return neigh; +} + +static NMLldpNeighbor * +nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor) +{ + NMLldpNeighbor *copy; + + copy = nm_lldp_neighbor_new (); + copy->attrs = g_hash_table_ref (neighbor->attrs); + + return copy; +} + +/** + * nm_lldp_neighbor_ref: + * @neighbor: the #NMLldpNeighbor + * + * Increases the reference count of the object. + * + * Since: 1.2 + **/ +void +nm_lldp_neighbor_ref (NMLldpNeighbor *neighbor) +{ + g_return_if_fail (neighbor); + g_return_if_fail (neighbor->refcount > 0); + + neighbor->refcount++; +} + +/** + * nm_lldp_neighbor_unref: + * @neighbor: the #NMLldpNeighbor + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.2 + **/ +void +nm_lldp_neighbor_unref (NMLldpNeighbor *neighbor) +{ + g_return_if_fail (neighbor); + g_return_if_fail (neighbor->refcount > 0); + + if (--neighbor->refcount == 0) { + g_return_if_fail (neighbor->attrs); + g_hash_table_unref (neighbor->attrs); + g_free (neighbor); + } +} + +/** + * nm_lldp_neighbor_get_attr_names: + * @neighbor: the #NMLldpNeighbor + * + * Gets an array of attribute names available for @neighbor. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names. + * + * Since: 1.2 + **/ +char ** +nm_lldp_neighbor_get_attr_names (NMLldpNeighbor *neighbor) +{ + GHashTableIter iter; + const char *key; + GPtrArray *names; + + g_return_val_if_fail (neighbor, NULL); + g_return_val_if_fail (neighbor->attrs, NULL); + + names = g_ptr_array_new (); + + g_hash_table_iter_init (&iter, neighbor->attrs); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) + g_ptr_array_add (names, g_strdup (key)); + + g_ptr_array_add (names, NULL); + + return (char **) g_ptr_array_free (names, FALSE); +} + +/** + * nm_lldp_neighbor_get_attr_string_value: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * @out_value: (out) (allow-none) (transfer none): on return, the attribute value + * + * Gets the string value of attribute with name @name on @neighbor + * + * Returns: %TRUE if a string attribute with name @name was found, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_lldp_neighbor_get_attr_string_value (NMLldpNeighbor *neighbor, char *name, + const char **out_value) +{ + GVariant *variant; + + g_return_val_if_fail (neighbor, FALSE); + g_return_val_if_fail (name && name[0], FALSE); + + variant = g_hash_table_lookup (neighbor->attrs, name); + if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) { + if (out_value) + *out_value = g_variant_get_string (variant, NULL); + return TRUE; + } else + return FALSE; +} + +/** + * nm_lldp_neighbor_get_attr_uint_value: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * @out_value: (out) (allow-none): on return, the attribute value + * + * Gets the uint value of attribute with name @name on @neighbor + * + * Returns: %TRUE if a uint attribute with name @name was found, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_lldp_neighbor_get_attr_uint_value (NMLldpNeighbor *neighbor, char *name, + guint *out_value) +{ + GVariant *variant; + + g_return_val_if_fail (neighbor, FALSE); + g_return_val_if_fail (name && name[0], FALSE); + + variant = g_hash_table_lookup (neighbor->attrs, name); + if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) { + if (out_value) + *out_value = g_variant_get_uint32 (variant); + return TRUE; + } else + return FALSE; +} + +/** + * nm_lldp_neighbor_get_attr_type: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * + * Get the type of an attribute. + * + * Returns: the #GVariantType of the attribute with name @name + * + * Since: 1.2 + **/ +const GVariantType * +nm_lldp_neighbor_get_attr_type (NMLldpNeighbor *neighbor, char *name) +{ + GVariant *variant; + + g_return_val_if_fail (neighbor, NULL); + g_return_val_if_fail (name && name[0], NULL); + + variant = g_hash_table_lookup (neighbor->attrs, name); + if (variant) + return g_variant_get_type (variant); + else + return NULL; + +} diff --git a/libnm/nm-device.h b/libnm/nm-device.h index a61dcf32..bf845ceb 100644 --- a/libnm/nm-device.h +++ b/libnm/nm-device.h @@ -45,9 +45,11 @@ G_BEGIN_DECLS #define NM_DEVICE_DRIVER_VERSION "driver-version" #define NM_DEVICE_FIRMWARE_VERSION "firmware-version" #define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_REAL "real" #define NM_DEVICE_MANAGED "managed" #define NM_DEVICE_AUTOCONNECT "autoconnect" #define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_NM_PLUGIN_MISSING "nm-plugin-missing" #define NM_DEVICE_IP4_CONFIG "ip4-config" #define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_IP6_CONFIG "ip6-config" @@ -61,6 +63,7 @@ G_BEGIN_DECLS #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_MTU "mtu" #define NM_DEVICE_METERED "metered" +#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors" struct _NMDevice { NMObject parent; @@ -89,6 +92,8 @@ typedef struct { gpointer padding[8]; } NMDeviceClass; +typedef struct _NMLldpNeighbor NMLldpNeighbor; + GType nm_device_get_type (void); const char * nm_device_get_iface (NMDevice *device); @@ -102,9 +107,13 @@ const char * nm_device_get_type_description (NMDevice *device); const char * nm_device_get_hw_address (NMDevice *device); NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device); gboolean nm_device_get_managed (NMDevice *device); +NM_AVAILABLE_IN_1_2 +void nm_device_set_managed (NMDevice *device, gboolean managed); gboolean nm_device_get_autoconnect (NMDevice *device); void nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect); gboolean nm_device_get_firmware_missing (NMDevice *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_get_nm_plugin_missing (NMDevice *device); NMIPConfig * nm_device_get_ip4_config (NMDevice *device); NMDhcpConfig * nm_device_get_dhcp4_config (NMDevice *device); NMIPConfig * nm_device_get_ip6_config (NMDevice *device); @@ -115,15 +124,36 @@ NMActiveConnection * nm_device_get_active_connection(NMDevice *device); const GPtrArray * nm_device_get_available_connections(NMDevice *device); const char * nm_device_get_physical_port_id (NMDevice *device); guint32 nm_device_get_mtu (NMDevice *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_is_real (NMDevice *device); gboolean nm_device_is_software (NMDevice *device); const char * nm_device_get_product (NMDevice *device); const char * nm_device_get_vendor (NMDevice *device); const char * nm_device_get_description (NMDevice *device); -NM_AVAILABLE_IN_1_0_6 +NM_AVAILABLE_IN_1_2 NMMetered nm_device_get_metered (NMDevice *device); +NM_AVAILABLE_IN_1_2 +GPtrArray * nm_device_get_lldp_neighbors (NMDevice *device); char ** nm_device_disambiguate_names (NMDevice **devices, int num_devices); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_reapply (NMDevice *device, + NMConnection *connection, + guint flags, + GCancellable *cancellable, + GError **error); +NM_AVAILABLE_IN_1_2 +void nm_device_reapply_async (NMDevice *device, + NMConnection *connection, + guint flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_reapply_finish (NMDevice *device, + GAsyncResult *result, + GError **error); gboolean nm_device_disconnect (NMDevice *device, GCancellable *cancellable, @@ -159,6 +189,25 @@ gboolean nm_device_connection_compatible (NMDevice *device, GType nm_device_get_setting_type (NMDevice *device); +NM_AVAILABLE_IN_1_2 +GType nm_lldp_neighbor_get_type (void); +NM_AVAILABLE_IN_1_2 +NMLldpNeighbor *nm_lldp_neighbor_new (void); +NM_AVAILABLE_IN_1_2 +void nm_lldp_neighbor_ref (NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_2 +void nm_lldp_neighbor_unref (NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_2 +char **nm_lldp_neighbor_get_attr_names (NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_2 +gboolean nm_lldp_neighbor_get_attr_string_value (NMLldpNeighbor *neighbor, char *name, + const char **out_value); +NM_AVAILABLE_IN_1_2 +gboolean nm_lldp_neighbor_get_attr_uint_value (NMLldpNeighbor *neighbor, char *name, + guint *out_value); +NM_AVAILABLE_IN_1_2 +const GVariantType *nm_lldp_neighbor_get_attr_type (NMLldpNeighbor *neighbor, char *name); + G_END_DECLS #endif /* __NM_DEVICE_H__ */ diff --git a/libnm/nm-enum-types.c b/libnm/nm-enum-types.c index 2f190917..e10e9f78 100644 --- a/libnm/nm-enum-types.c +++ b/libnm/nm-enum-types.c @@ -3,6 +3,8 @@ /* Generated by glib-mkenums. Do not edit */ +#include "config.h" + #include "nm-enum-types.h" #include "nm-version-macros.h" @@ -17,10 +19,14 @@ #include "nm-device-ethernet.h" #include "nm-device-generic.h" #include "nm-device-infiniband.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macvlan.h" #include "nm-device-modem.h" #include "nm-device-olpc-mesh.h" #include "nm-device-team.h" +#include "nm-device-tun.h" #include "nm-device-vlan.h" +#include "nm-device-vxlan.h" #include "nm-device-wifi.h" #include "nm-device-wimax.h" #include "nm-device.h" @@ -30,10 +36,11 @@ #include "nm-remote-connection.h" #include "nm-types.h" #include "nm-vpn-connection.h" -#include "nm-vpn-editor-plugin.h" +#include "nm-vpn-editor.h" #include "nm-wimax-nsp.h" #include "nm-secret-agent-old.h" -#include "nm-vpn-plugin-old.h" +#include "nm-vpn-plugin-old.h" +#include "nm-vpn-service-plugin.h" GType nm_client_permission_get_type (void) @@ -107,27 +114,6 @@ nm_client_error_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; -} -GType nm_wimax_nsp_network_type_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; diff --git a/libnm/nm-enum-types.h b/libnm/nm-enum-types.h index 1db04ab8..93d9eb8e 100644 --- a/libnm/nm-enum-types.h +++ b/libnm/nm-enum-types.h @@ -16,8 +16,6 @@ GType nm_client_permission_result_get_type (void) G_GNUC_CONST; #define NM_TYPE_CLIENT_PERMISSION_RESULT (nm_client_permission_result_get_type ()) GType nm_client_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_CLIENT_ERROR (nm_client_error_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 ()) GType nm_wimax_nsp_network_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_WIMAX_NSP_NETWORK_TYPE (nm_wimax_nsp_network_type_get_type ()) G_END_DECLS diff --git a/libnm/nm-ifcfg-rh-docs.xml b/libnm/nm-ifcfg-rh-docs.xml index 2cea2cb2..56c3c7b9 100644 --- a/libnm/nm-ifcfg-rh-docs.xml +++ b/libnm/nm-ifcfg-rh-docs.xml @@ -62,6 +62,7 @@ MACADDR for bridges is an NM extension."/> + @@ -93,6 +94,7 @@ together with this connection."/> + @@ -132,6 +134,8 @@ When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified."/> + + - + @@ -152,6 +157,9 @@ meaning as 'never-default' property."/> + + If set to -1, a default metric based on the device type is used."/> + + + @@ -190,10 +201,12 @@ IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no" default="no" example="IPV6_PRIVACY=rfc30 + + - + + + @@ -265,6 +280,8 @@ is listed."/> + + \ No newline at end of file diff --git a/libnm/nm-ip-config.c b/libnm/nm-ip-config.c index d057903e..fc4567c4 100644 --- a/libnm/nm-ip-config.c +++ b/libnm/nm-ip-config.c @@ -406,7 +406,8 @@ nm_ip_config_get_gateway (NMIPConfig *config) * * Returns: (element-type NMIPAddress) (transfer none): the #GPtrArray * containing #NMIPAddresses. This is the internal copy used by the - * configuration and must not be modified. + * configuration and must not be modified. The library never modifies the + * returned array and thus it is safe for callers to reference and keep using it. **/ GPtrArray * nm_ip_config_get_addresses (NMIPConfig *config) @@ -491,7 +492,9 @@ nm_ip_config_get_wins_servers (NMIPConfig *config) * * Returns: (element-type NMIPRoute) (transfer none): the #GPtrArray containing * #NMIPRoutes. This is the internal copy used by the configuration, and must - * not be modified. + * not be modified. The library never modifies the returned array and thus it is + * safe for callers to reference and keep using it. + * **/ GPtrArray * nm_ip_config_get_routes (NMIPConfig *config) diff --git a/libnm/nm-keyfile-docs.xml b/libnm/nm-keyfile-docs.xml index d080a427..663f8a2e 100644 --- a/libnm/nm-keyfile-docs.xml +++ b/libnm/nm-keyfile-docs.xml @@ -34,6 +34,8 @@ or semicolon separated list of 20 decimal bytes (obsolete)"/> + + @@ -47,6 +49,8 @@ route2=7.7.0.0/16" description="List of IP routes."/> + + @@ -62,6 +66,8 @@ versions of NetworkManager stored this as an integer: 69 ('E') for eve + + @@ -70,6 +76,8 @@ under [vpn] section."/> + + diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index 2a61a010..b4b7e0c7 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -22,9 +22,9 @@ #include "config.h" #include -#include #include +#include "nm-default.h" #include "nm-manager.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" @@ -34,8 +34,8 @@ #include "nm-active-connection.h" #include "nm-vpn-connection.h" #include "nm-object-cache.h" -#include "nm-glib-compat.h" #include "nm-dbus-helpers.h" +#include "nm-macros-internal.h" #include "nmdbus-manager.h" @@ -60,6 +60,7 @@ typedef struct { NMState state; gboolean startup; GPtrArray *devices; + GPtrArray *all_devices; GPtrArray *active_connections; NMConnectivityState connectivity; NMActiveConnection *primary_connection; @@ -104,6 +105,7 @@ enum { PROP_ACTIVATING_CONNECTION, PROP_DEVICES, PROP_METERED, + PROP_ALL_DEVICES, LAST_PROP }; @@ -111,6 +113,8 @@ enum { enum { DEVICE_ADDED, DEVICE_REMOVED, + ANY_DEVICE_ADDED, + ANY_DEVICE_REMOVED, ACTIVE_CONNECTION_ADDED, ACTIVE_CONNECTION_REMOVED, PERMISSION_CHANGED, @@ -136,6 +140,7 @@ nm_manager_init (NMManager *manager) priv->permissions = g_hash_table_new (g_direct_hash, g_direct_equal); priv->devices = g_ptr_array_new (); + priv->all_devices = g_ptr_array_new (); priv->active_connections = g_ptr_array_new (); } @@ -145,8 +150,8 @@ poke_wireless_devices_with_rf_status (NMManager *manager) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); int i; - for (i = 0; i < priv->devices->len; i++) { - NMDevice *device = g_ptr_array_index (priv->devices, i); + for (i = 0; i < priv->all_devices->len; i++) { + NMDevice *device = g_ptr_array_index (priv->all_devices, i); if (NM_IS_DEVICE_WIFI (device)) _nm_device_wifi_set_wireless_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled); @@ -182,6 +187,7 @@ init_dbus (NMObject *object) { NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" }, { NM_MANAGER_METERED, &priv->metered }, + { NM_MANAGER_ALL_DEVICES, &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" }, { NULL }, }; @@ -667,6 +673,14 @@ nm_manager_get_devices (NMManager *manager) return NM_MANAGER_GET_PRIVATE (manager)->devices; } +const GPtrArray * +nm_manager_get_all_devices (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->all_devices; +} + NMDevice * nm_manager_get_device_by_path (NMManager *manager, const char *object_path) { @@ -1180,27 +1194,47 @@ static void free_devices (NMManager *manager, gboolean in_dispose) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - GPtrArray *devices; - NMDevice *device; - int i; + gs_unref_ptrarray GPtrArray *real_devices = NULL; + gs_unref_ptrarray GPtrArray *all_devices = NULL; + GPtrArray *devices = NULL; + guint i, j; - if (!priv->devices) + real_devices = priv->devices; + all_devices = priv->all_devices; + + if (in_dispose) { + priv->devices = NULL; + priv->all_devices = NULL; return; + } - devices = priv->devices; + priv->devices = g_ptr_array_new_with_free_func (g_object_unref); + priv->all_devices = g_ptr_array_new_with_free_func (g_object_unref); - if (in_dispose) - priv->devices = NULL; - else { - priv->devices = g_ptr_array_new (); + if (all_devices && all_devices->len > 0) + devices = all_devices; + else if (devices && devices->len > 0) + devices = real_devices; + + if (real_devices && devices != real_devices) { + for (i = 0; i < real_devices->len; i++) { + NMDevice *d = real_devices->pdata[i]; - for (i = 0; i < devices->len; i++) { - device = devices->pdata[i]; - g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); + if (all_devices) { + for (j = 0; j < all_devices->len; j++) { + if (d == all_devices->pdata[j]) + goto next; + } + } + g_signal_emit (manager, signals[DEVICE_REMOVED], 0, d); +next: + ; } } - - g_ptr_array_unref (devices); + if (devices) { + for (i = 0; i < devices->len; i++) + g_signal_emit (manager, signals[DEVICE_REMOVED], 0, devices->pdata[i]); + } } static void @@ -1256,7 +1290,7 @@ nm_running_changed_cb (GObject *object, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); if (!nm_manager_get_nm_running (manager)) { - NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + nm_clear_g_cancellable (&priv->props_cancellable); priv->state = NM_STATE_UNKNOWN; priv->startup = FALSE; @@ -1282,7 +1316,7 @@ nm_running_changed_cb (GObject *object, } else { _nm_object_suppress_property_updates (NM_OBJECT (manager), FALSE); - NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + nm_clear_g_cancellable (&priv->props_cancellable); priv->props_cancellable = g_cancellable_new (); _nm_object_reload_properties_async (NM_OBJECT (manager), priv->props_cancellable, updated_properties, manager); @@ -1543,6 +1577,9 @@ get_property (GObject *object, case PROP_METERED: g_value_set_uint (value, priv->metered); break; + case PROP_ALL_DEVICES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_all_devices (self))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1680,7 +1717,7 @@ nm_manager_class_init (NMManagerClass *manager_class) * * Whether the connectivity is metered. * - * Since: 1.0.6 + * Since: 1.2 **/ g_object_class_install_property (object_class, PROP_METERED, @@ -1689,6 +1726,13 @@ nm_manager_class_init (NMManagerClass *manager_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_ALL_DEVICES, + g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /* signals */ signals[DEVICE_ADDED] = @@ -1707,6 +1751,22 @@ nm_manager_class_init (NMManagerClass *manager_class) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[ANY_DEVICE_ADDED] = + g_signal_new ("any-device-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[ANY_DEVICE_REMOVED] = + g_signal_new ("any-device-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); signals[ACTIVE_CONNECTION_ADDED] = g_signal_new ("active-connection-added", G_OBJECT_CLASS_TYPE (object_class), diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h index 8d04a060..f9e4cd0e 100644 --- a/libnm/nm-manager.h +++ b/libnm/nm-manager.h @@ -51,6 +51,7 @@ G_BEGIN_DECLS #define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection" #define NM_MANAGER_DEVICES "devices" #define NM_MANAGER_METERED "metered" +#define NM_MANAGER_ALL_DEVICES "all-devices" typedef struct { NMObject parent; @@ -67,6 +68,8 @@ typedef struct { void (*permission_changed) (NMManager *manager, NMClientPermission permission, NMClientPermissionResult result); + + /* Beware: no more slots. Cannot extend struct without breaking ABI. */ } NMManagerClass; GType nm_manager_get_type (void); @@ -121,6 +124,8 @@ NMConnectivityState nm_manager_check_connectivity_finish (NMManager *manager, /* Devices */ const GPtrArray *nm_manager_get_devices (NMManager *manager); +NM_AVAILABLE_IN_1_2 +const GPtrArray *nm_manager_get_all_devices(NMManager *manager); NMDevice *nm_manager_get_device_by_path (NMManager *manager, const char *object_path); NMDevice *nm_manager_get_device_by_iface (NMManager *manager, const char *iface); diff --git a/libnm/nm-object-cache.c b/libnm/nm-object-cache.c index 752c606a..82af1140 100644 --- a/libnm/nm-object-cache.c +++ b/libnm/nm-object-cache.c @@ -21,7 +21,7 @@ #include "config.h" #include -#include +#include "nm-default.h" #include "nm-object-cache.h" #include "nm-object.h" diff --git a/libnm/nm-object-cache.h b/libnm/nm-object-cache.h index ebadbaa8..c0f70f21 100644 --- a/libnm/nm-object-cache.h +++ b/libnm/nm-object-cache.h @@ -21,8 +21,7 @@ #ifndef __NM_OBJECT_CACHE_H__ #define __NM_OBJECT_CACHE_H__ -#include -#include +#include "nm-default.h" #include "nm-object.h" G_BEGIN_DECLS diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h index 0b13cbb6..7e8066f4 100644 --- a/libnm/nm-object-private.h +++ b/libnm/nm-object-private.h @@ -21,7 +21,7 @@ #ifndef __NM_OBJECT_PRIVATE_H__ #define __NM_OBJECT_PRIVATE_H__ -#include +#include "nm-default.h" #include "nm-object.h" typedef gboolean (*PropertyMarshalFunc) (NMObject *, GParamSpec *, GVariant *, gpointer); diff --git a/libnm/nm-object.c b/libnm/nm-object.c index fbdbc1f6..143931f1 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -22,18 +22,18 @@ #include "config.h" #include -#include -#include #include #include #include +#include "nm-default.h" #include "nm-dbus-interface.h" #include "nm-object.h" #include "nm-object-cache.h" #include "nm-object-private.h" -#include "nm-glib-compat.h" #include "nm-dbus-helpers.h" #include "nm-client.h" +#include "nm-core-internal.h" +#include "nm-macros-internal.h" static gboolean debug = FALSE; #define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); } @@ -85,6 +85,10 @@ typedef struct { NMObject *parent; gboolean suppress_property_updates; + gboolean inited; /* async init finished? */ + GSList *waiters; /* if async init did not finish, users of this object need + * to defer their notifications by adding themselves here. */ + GSList *notify_items; guint32 notify_id; @@ -201,6 +205,24 @@ deferred_notify_cb (gpointer data) if (priv->reload_remaining) return G_SOURCE_REMOVE; + /* If not all added object are finished yet, then defer the deferred + * notification. */ + for (iter = priv->notify_items; iter; iter = g_slist_next (iter)) { + NotifyItem *item = iter->data; + NMObjectPrivate *item_priv; + + if (!item->changed) + continue; + + item_priv = NM_OBJECT_GET_PRIVATE (item->changed); + if (!item_priv->inited) { + if (!g_slist_find (item_priv->waiters, object)) + item_priv->waiters = g_slist_prepend (item_priv->waiters, + g_object_ref (object)); + return G_SOURCE_REMOVE; + } + } + /* Clear priv->notify_items early so that an NMObject subclass that * listens to property changes can queue up other property changes * during the g_object_notify() call separately from the property @@ -426,6 +448,7 @@ _nm_object_create (GType type, GDBusConnection *connection, const char *path) * before any external code sees it. */ _nm_object_cache_add (NM_OBJECT (object)); + NM_OBJECT_GET_PRIVATE (object)->inited = TRUE; if (!g_initable_init (G_INITABLE (object), NULL, &error)) { dbgmsg ("Could not create object for %s: %s", path, error->message); g_error_free (error); @@ -460,6 +483,7 @@ create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data) NMObjectTypeAsyncData *async_data = user_data; GError *error = NULL; + NM_OBJECT_GET_PRIVATE (object)->inited = TRUE; if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) { dbgmsg ("Could not create object for %s: %s", nm_object_get_path (NM_OBJECT (object)), @@ -469,6 +493,19 @@ create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data) } create_async_complete (object, async_data); + + if (object) { + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + /* Re-queue notification checks for whoever was waiting for + * this object to initialize. */ + while (priv->waiters) { + NMObject *item = priv->waiters->data; + priv->waiters = g_slist_remove (priv->waiters, item); + _nm_object_defer_notify (item); + g_object_unref (item); + } + } } static void @@ -511,7 +548,8 @@ create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_d GError *error = NULL; GType type; - ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, + G_VARIANT_TYPE ("(v)"), &error); if (ret) { g_variant_get (ret, "(v)", &value); type = type_data->type_func (value); @@ -519,8 +557,8 @@ create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_d g_variant_unref (ret); } else { dbgmsg ("Could not fetch property '%s' of interface '%s' on %s: %s\n", - type_data->property, type_data->interface, async_data->path, - error->message); + type_data->property, type_data->interface, async_data->path, + error->message); g_clear_error (&error); type = G_TYPE_INVALID; } @@ -681,6 +719,8 @@ object_property_complete (ObjectCreatedData *odata) for (i = 0; i < odata->length; i++) add_to_object_array_unique (new, odata->objects[i]); + *((GPtrArray **) pi->field) = new; + if (pi->signal_prefix) { GPtrArray *added = g_ptr_array_sized_new (3); GPtrArray *removed = g_ptr_array_sized_new (3); @@ -691,8 +731,6 @@ object_property_complete (ObjectCreatedData *odata) /* Find objects in 'new' that do not exist in old */ array_diff (new, old, added); - *((GPtrArray **) pi->field) = new; - /* Emit added & removed */ for (i = 0; i < removed->len; i++) { queue_added_removed_signal (self, @@ -715,7 +753,6 @@ object_property_complete (ObjectCreatedData *odata) /* No added/removed signals to send, just replace the property with * the new values. */ - *((GPtrArray **) pi->field) = new; different = TRUE; } @@ -962,27 +999,20 @@ process_properties_changed (NMObject *self, GVariant *properties, gboolean synch } static void -property_proxy_signal (GDBusProxy *proxy, - const char *sender_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) +properties_changed (GDBusProxy *proxy, + GVariant *properties, + gpointer user_data) { - GVariant *properties; - - if (strcmp (signal_name, "PropertiesChanged") != 0) - return; - - g_variant_get (parameters, "(@a{sv})", &properties); process_properties_changed (NM_OBJECT (user_data), properties, FALSE); - g_variant_unref (properties); } #define HANDLE_TYPE(vtype, ctype, getter) \ G_STMT_START { \ if (g_variant_is_of_type (value, vtype)) { \ ctype *param = (ctype *) field; \ - *param = getter (value); \ + ctype newval = getter (value); \ + different = *param != newval; \ + *param = newval; \ } else { \ success = FALSE; \ goto done; \ @@ -996,20 +1026,29 @@ demarshal_generic (NMObject *object, gpointer field) { gboolean success = TRUE; + gboolean different = FALSE; if (pspec->value_type == G_TYPE_STRING) { if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { char **param = (char **) field; - g_free (*param); - *param = g_variant_dup_string (value, NULL); + const char *newval = g_variant_get_string (value, NULL); + + different = !!g_strcmp0 (*param, newval); + if (different) { + g_free (*param); + *param = g_strdup (newval); + } } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) { char **param = (char **) field; - g_free (*param); - *param = g_variant_dup_string (value, NULL); + const char *newval = g_variant_get_string (value, NULL); + /* Handle "NULL" object paths */ - if (g_strcmp0 (*param, "/") == 0) { + if (g_strcmp0 (newval, "/") == 0) + newval = NULL; + different = !!g_strcmp0 (*param, newval); + if (different) { g_free (*param); - *param = NULL; + *param = g_strdup (newval); } } else { success = FALSE; @@ -1017,50 +1056,78 @@ demarshal_generic (NMObject *object, } } else if (pspec->value_type == G_TYPE_STRV) { char ***param = (char ***)field; - if (*param) - g_strfreev (*param); - *param = g_variant_dup_strv (value, NULL); + const char **newval; + gsize i; + + newval = g_variant_get_strv (value, NULL); + if (!*param) + different = TRUE; + else { + if (!_nm_utils_strv_equal ((char **) newval, *param)) { + different = TRUE; + g_strfreev (*param); + } + } + if (different) { + for (i = 0; newval[i]; i++) + newval[i] = g_strdup (newval[i]); + *param = (char **) newval; + } else + g_free (newval); } else if (pspec->value_type == G_TYPE_BYTES) { GBytes **param = (GBytes **)field; - gconstpointer val; - gsize length; + gconstpointer val, old_val = NULL; + gsize length, old_length = 0; - if (*param) - g_bytes_unref (*param); val = g_variant_get_fixed_array (value, &length, 1); - if (length) - *param = g_bytes_new (val, length); - else - *param = NULL; + + if (*param) + old_val = g_bytes_get_data (*param, &old_length); + different = old_length != length + || ( length > 0 + && memcmp (old_val, val, length) != 0); + if (different) { + if (*param) + g_bytes_unref (*param); + *param = length > 0 ? g_bytes_new (val, length) : NULL; + } } else if (G_IS_PARAM_SPEC_ENUM (pspec)) { int *param = (int *) field; + int newval = 0; if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) - *param = g_variant_get_int32 (value); + newval = g_variant_get_int32 (value); else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)) - *param = g_variant_get_uint32 (value); + newval = g_variant_get_uint32 (value); else { success = FALSE; goto done; } + different = *param != newval; + *param = newval; } else if (G_IS_PARAM_SPEC_FLAGS (pspec)) { guint *param = (guint *) field; + guint newval = 0; if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) - *param = g_variant_get_int32 (value); + newval = g_variant_get_int32 (value); else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)) - *param = g_variant_get_uint32 (value); + newval = g_variant_get_uint32 (value); else { success = FALSE; goto done; } + different = *param != newval; + *param = newval; } else if (pspec->value_type == G_TYPE_BOOLEAN) HANDLE_TYPE (G_VARIANT_TYPE_BOOLEAN, gboolean, g_variant_get_boolean); else if (pspec->value_type == G_TYPE_UCHAR) HANDLE_TYPE (G_VARIANT_TYPE_BYTE, guchar, g_variant_get_byte); - else if (pspec->value_type == G_TYPE_DOUBLE) + else if (pspec->value_type == G_TYPE_DOUBLE) { + NM_PRAGMA_WARNING_DISABLE("-Wfloat-equal") HANDLE_TYPE (G_VARIANT_TYPE_DOUBLE, gdouble, g_variant_get_double); - else if (pspec->value_type == G_TYPE_INT) + NM_PRAGMA_WARNING_REENABLE + } else if (pspec->value_type == G_TYPE_INT) HANDLE_TYPE (G_VARIANT_TYPE_INT32, gint, g_variant_get_int32); else if (pspec->value_type == G_TYPE_UINT) HANDLE_TYPE (G_VARIANT_TYPE_UINT32, guint, g_variant_get_uint32); @@ -1083,7 +1150,8 @@ demarshal_generic (NMObject *object, done: if (success) { - _nm_object_queue_notify (object, pspec->name); + if (different) + _nm_object_queue_notify (object, pspec->name); } else { dbgmsg ("%s: %s:%s (type %s) couldn't be set from D-Bus type %s.", __func__, G_OBJECT_TYPE_NAME (object), pspec->name, @@ -1118,8 +1186,8 @@ _nm_object_register_properties (NMObject *object, proxy = _nm_object_get_proxy (object, interface); g_return_if_fail (proxy != NULL); - g_signal_connect (proxy, "g-signal", - G_CALLBACK (property_proxy_signal), object); + _nm_dbus_signal_connect (proxy, "PropertiesChanged", G_VARIANT_TYPE ("(a{sv})"), + G_CALLBACK (properties_changed), object); instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->property_tables = g_slist_prepend (priv->property_tables, instance); @@ -1157,11 +1225,12 @@ _nm_object_reload_properties (NMObject *object, GError **error) g_hash_table_iter_init (&iter, priv->proxies); while (g_hash_table_iter_next (&iter, (gpointer *) &interface, (gpointer *) &proxy)) { - ret = g_dbus_proxy_call_sync (priv->properties_proxy, - "GetAll", - g_variant_new ("(s)", interface), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, error); + ret = _nm_dbus_proxy_call_sync (priv->properties_proxy, + "GetAll", + g_variant_new ("(s)", interface), + G_VARIANT_TYPE ("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, error); if (!ret) { if (error && *error) g_dbus_error_strip_remote_error (*error); @@ -1204,11 +1273,12 @@ _nm_object_reload_property (NMObject *object, if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) return; - ret = g_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, - "Get", - g_variant_new ("(ss)", interface, prop_name), - G_DBUS_CALL_FLAGS_NONE, 15000, - NULL, &err); + ret = _nm_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, + "Get", + g_variant_new ("(ss)", interface, prop_name), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NONE, 15000, + NULL, &err); if (!ret) { dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n", __func__, @@ -1268,10 +1338,7 @@ reload_complete (NMObject *object, gboolean emit_now) GError *error; if (emit_now) { - if (priv->notify_id) { - g_source_remove (priv->notify_id); - priv->notify_id = 0; - } + nm_clear_g_source (&priv->notify_id); deferred_notify_cb (object); } else _nm_object_defer_notify (object); @@ -1306,7 +1373,9 @@ reload_got_properties (GObject *proxy, GVariant *ret, *props; GError *error = NULL; - ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, + G_VARIANT_TYPE ("(a{sv})"), + &error); if (ret) { g_variant_get (ret, "(@a{sv})", &props); process_properties_changed (object, props, FALSE); @@ -1679,14 +1748,12 @@ dispose (GObject *object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - if (priv->notify_id) { - g_source_remove (priv->notify_id); - priv->notify_id = 0; - } + nm_clear_g_source (&priv->notify_id); g_slist_free_full (priv->notify_items, (GDestroyNotify) notify_item_free); priv->notify_items = NULL; + g_slist_free_full (priv->waiters, g_object_unref); g_clear_pointer (&priv->proxies, g_hash_table_unref); g_clear_object (&priv->properties_proxy); diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml index abee2d73..c0f57b0b 100644 --- a/libnm/nm-property-docs.xml +++ b/libnm/nm-property-docs.xml @@ -63,6 +63,7 @@ + @@ -87,8 +88,9 @@ + - + @@ -97,7 +99,7 @@ - + @@ -122,6 +124,7 @@ + @@ -130,6 +133,8 @@ + + @@ -143,9 +148,12 @@ - + + + + @@ -158,15 +166,17 @@ + - + + - + @@ -174,6 +184,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -224,9 +256,18 @@ + + + + + + + + + - + @@ -238,12 +279,32 @@ + + + + + + + + + + + + + + + + + + + + - + - + @@ -269,9 +330,11 @@ + + diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c index 98924973..e2073784 100644 --- a/libnm/nm-remote-connection.c +++ b/libnm/nm-remote-connection.c @@ -22,16 +22,14 @@ #include "config.h" #include -#include -#include #include #include #include +#include "nm-default.h" #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" #include "nm-object-private.h" -#include "nm-glib-compat.h" #include "nm-dbus-helpers.h" #include "nmdbus-settings-connection.h" diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c index d37e3666..480d7c19 100644 --- a/libnm/nm-remote-settings.c +++ b/libnm/nm-remote-settings.c @@ -22,19 +22,19 @@ #include "config.h" #include -#include #include #include +#include "nm-default.h" #include "nm-remote-settings.h" #include "nm-client.h" #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" #include "nm-object-private.h" #include "nm-dbus-helpers.h" -#include "nm-glib-compat.h" #include "nm-object-private.h" #include "nm-core-internal.h" +#include "nm-macros-internal.h" #include "nmdbus-settings.h" @@ -627,7 +627,7 @@ nm_running_changed (GObject *object, GPtrArray *connections; int i; - NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + nm_clear_g_cancellable (&priv->props_cancellable); /* Clear connections */ connections = priv->all_connections; @@ -652,7 +652,7 @@ nm_running_changed (GObject *object, } else { _nm_object_suppress_property_updates (NM_OBJECT (self), FALSE); - NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + nm_clear_g_cancellable (&priv->props_cancellable); priv->props_cancellable = g_cancellable_new (); _nm_object_reload_properties_async (NM_OBJECT (self), priv->props_cancellable, updated_properties, self); } diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c index 6df54d43..97bb287e 100644 --- a/libnm/nm-secret-agent-old.c +++ b/libnm/nm-secret-agent-old.c @@ -22,7 +22,7 @@ #include -#include "nm-glib-compat.h" +#include "nm-default.h" #include "nm-dbus-interface.h" #include "nm-secret-agent-old.h" #include "nm-enum-types.h" diff --git a/libnm/nm-setting-docs-overrides.xml b/libnm/nm-setting-docs-overrides.xml index 3a52fd7c..2f788db8 100644 --- a/libnm/nm-setting-docs-overrides.xml +++ b/libnm/nm-setting-docs-overrides.xml @@ -35,6 +35,8 @@ bridge's interface name."/> + + @@ -102,6 +104,8 @@ will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes."/> + + @@ -119,6 +123,8 @@ also exist on some routes."/> be used for backward-compatibility with older daemons, to set the team's interface name."/> + + + + diff --git a/libnm/nm-setting-docs.xml b/libnm/nm-setting-docs.xml index 7e865c58..917edaab 100644 --- a/libnm/nm-setting-docs.xml +++ b/libnm/nm-setting-docs.xml @@ -65,6 +65,7 @@ + @@ -89,8 +90,9 @@ + - + @@ -99,7 +101,7 @@ - + @@ -124,6 +126,7 @@ + @@ -132,6 +135,8 @@ + + @@ -146,9 +151,12 @@ - + + + + @@ -162,16 +170,18 @@ + - + + - + @@ -180,6 +190,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -231,9 +263,18 @@ + + + + + + + + + - + @@ -246,12 +287,32 @@ + + + + + + + + + + + + + + + + + + + + - + - + @@ -277,9 +338,11 @@ + + diff --git a/libnm/nm-types.h b/libnm/nm-types.h index ee1ed643..be09daaf 100644 --- a/libnm/nm-types.h +++ b/libnm/nm-types.h @@ -37,10 +37,14 @@ typedef struct _NMDeviceBt NMDeviceBt; typedef struct _NMDeviceEthernet NMDeviceEthernet; typedef struct _NMDeviceGeneric NMDeviceGeneric; typedef struct _NMDeviceInfiniband NMDeviceInfiniband; +typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel; +typedef struct _NMDeviceMacvlan NMDeviceMacvlan; typedef struct _NMDeviceModem NMDeviceModem; typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh; typedef struct _NMDeviceTeam NMDeviceTeam; +typedef struct _NMDeviceTun NMDeviceTun; typedef struct _NMDeviceVlan NMDeviceVlan; +typedef struct _NMDeviceVxlan NMDeviceVxlan; typedef struct _NMDeviceWifi NMDeviceWifi; typedef struct _NMDeviceWimax NMDeviceWimax; typedef struct _NMDhcpConfig NMDhcpConfig; diff --git a/libnm/nm-vpn-editor-plugin.c b/libnm/nm-vpn-editor-plugin.c deleted file mode 100644 index 904a6be4..00000000 --- a/libnm/nm-vpn-editor-plugin.c +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- 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 - 2010 Red Hat, Inc. - * Copyright 2008 Novell, Inc. - */ - -#include "config.h" - -#include "nm-vpn-editor-plugin.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_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); - } - 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); - } - 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; -} - - -static void nm_vpn_editor_default_init (NMVpnEditorInterface *iface); - -G_DEFINE_INTERFACE (NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT) - -static void -nm_vpn_editor_default_init (NMVpnEditorInterface *iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (iface); - - /* Signals */ - g_signal_new ("changed", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMVpnEditorInterface, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -/** - * nm_vpn_editor_get_widget: - * - * Returns: (transfer none): - */ -GObject * -nm_vpn_editor_get_widget (NMVpnEditor *editor) -{ - g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL); - - return NM_VPN_EDITOR_GET_INTERFACE (editor)->get_widget (editor); -} - -gboolean -nm_vpn_editor_update_connection (NMVpnEditor *editor, - NMConnection *connection, - GError **error) -{ - g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), FALSE); - - if (error) - g_return_val_if_fail (*error == NULL, FALSE); - - return NM_VPN_EDITOR_GET_INTERFACE (editor)->update_connection (editor, connection, error); -} diff --git a/libnm/nm-vpn-editor-plugin.h b/libnm/nm-vpn-editor-plugin.h deleted file mode 100644 index 5910aa36..00000000 --- a/libnm/nm-vpn-editor-plugin.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- 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 - 2014 Red Hat, Inc. - * Copyright 2008 Novell, Inc. - */ - -#ifndef __NM_VPN_EDITOR_PLUGIN_H__ -#define __NM_VPN_EDITOR_PLUGIN_H__ - -#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include -#include - -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); - -/**************************************************/ -/* Editor interface */ -/**************************************************/ - -#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type ()) -#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor)) -#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR)) -#define NM_VPN_EDITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface)) - -/** - * NMVpnEditorInterface: - * @g_iface: the parent interface - * @get_widget: return the #GtkWidget for the VPN editor's UI - * @placeholder: not currently used - * @update_connection: called to save the user-entered options to the connection - * object. Should return %FALSE and set @error if the current options are - * invalid. @error should contain enough information for the plugin to - * determine which UI widget is invalid at a later point in time. For - * example, creating unique error codes for what error occurred and populating - * the message field of @error with the name of the invalid property. - * @changed: emitted when the value of a UI widget changes. May trigger a - * validity check via @update_connection to write values to the connection. - * - * Interface for editing a specific #NMConnection - */ -typedef struct { - GTypeInterface g_iface; - - GObject * (*get_widget) (NMVpnEditor *editor); - - void (*placeholder) (void); - - gboolean (*update_connection) (NMVpnEditor *editor, - NMConnection *connection, - GError **error); - - void (*changed) (NMVpnEditor *editor); -} NMVpnEditorInterface; - -GType nm_vpn_editor_get_type (void); - -GObject * nm_vpn_editor_get_widget (NMVpnEditor *editor); - -gboolean nm_vpn_editor_update_connection (NMVpnEditor *editor, - NMConnection *connection, - GError **error); - -G_END_DECLS - -#endif /* NM_VPN_EDITOR_PLUGIN_H */ diff --git a/libnm/nm-vpn-editor.c b/libnm/nm-vpn-editor.c new file mode 100644 index 00000000..ba6bd5e0 --- /dev/null +++ b/libnm/nm-vpn-editor.c @@ -0,0 +1,69 @@ +/* -*- 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 - 2010 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include "nm-vpn-editor.h" + +static void nm_vpn_editor_default_init (NMVpnEditorInterface *iface); + +G_DEFINE_INTERFACE (NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT) + +static void +nm_vpn_editor_default_init (NMVpnEditorInterface *iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (iface); + + /* Signals */ + g_signal_new ("changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnEditorInterface, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * nm_vpn_editor_get_widget: + * + * Returns: (transfer none): + */ +GObject * +nm_vpn_editor_get_widget (NMVpnEditor *editor) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL); + + return NM_VPN_EDITOR_GET_INTERFACE (editor)->get_widget (editor); +} + +gboolean +nm_vpn_editor_update_connection (NMVpnEditor *editor, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), FALSE); + + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + + return NM_VPN_EDITOR_GET_INTERFACE (editor)->update_connection (editor, connection, error); +} diff --git a/libnm/nm-vpn-editor.h b/libnm/nm-vpn-editor.h new file mode 100644 index 00000000..a11e9fd1 --- /dev/null +++ b/libnm/nm-vpn-editor.h @@ -0,0 +1,86 @@ +/* -*- 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_H__ +#define __NM_VPN_EDITOR_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +#include "nm-vpn-editor-plugin.h" + +G_BEGIN_DECLS + +/**************************************************/ +/* Editor interface */ +/**************************************************/ + +#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type ()) +#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor)) +#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR)) +#define NM_VPN_EDITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface)) + +/** + * NMVpnEditorInterface: + * @g_iface: the parent interface + * @get_widget: return the #GtkWidget for the VPN editor's UI + * @placeholder: not currently used + * @update_connection: called to save the user-entered options to the connection + * object. Should return %FALSE and set @error if the current options are + * invalid. @error should contain enough information for the plugin to + * determine which UI widget is invalid at a later point in time. For + * example, creating unique error codes for what error occurred and populating + * the message field of @error with the name of the invalid property. + * @changed: emitted when the value of a UI widget changes. May trigger a + * validity check via @update_connection to write values to the connection. + * + * Interface for editing a specific #NMConnection + */ +typedef struct { + GTypeInterface g_iface; + + GObject * (*get_widget) (NMVpnEditor *editor); + + void (*placeholder) (void); + + gboolean (*update_connection) (NMVpnEditor *editor, + NMConnection *connection, + GError **error); + + void (*changed) (NMVpnEditor *editor); +} NMVpnEditorInterface; + +GType nm_vpn_editor_get_type (void); + +GObject * nm_vpn_editor_get_widget (NMVpnEditor *editor); + +gboolean nm_vpn_editor_update_connection (NMVpnEditor *editor, + NMConnection *connection, + GError **error); + +G_END_DECLS + +#endif /* __NM_VPN_EDITOR_H__ */ diff --git a/libnm/nm-vpn-plugin-old.c b/libnm/nm-vpn-plugin-old.c index deaa07dd..cfc8c663 100644 --- a/libnm/nm-vpn-plugin-old.c +++ b/libnm/nm-vpn-plugin-old.c @@ -19,20 +19,13 @@ * Copyright 2007 - 2008 Red Hat, Inc. */ -/* This interface is expected to be deprecated in NM 1.2, at which point there - * will be a new "NMVpnPlugin" class to replace it. - */ - #include "config.h" #include #include #include -#include -#include - -#include "nm-glib-compat.h" +#include "nm-default.h" #include "nm-vpn-plugin-old.h" #include "nm-enum-types.h" #include "nm-utils.h" @@ -71,7 +64,7 @@ typedef struct { gboolean has_ip6, got_ip6; /* Config stuff copied from config to ip4config */ - char *banner, *tundev, *gateway, *mtu; + GVariant *banner, *tundev, *gateway, *mtu; } NMVpnPluginOldPrivate; #define NM_VPN_PLUGIN_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldPrivate)) @@ -110,13 +103,16 @@ nm_vpn_plugin_old_set_connection (NMVpnPluginOld *plugin, g_clear_object (&priv->connection); - priv->connection = g_object_ref (connection); + if (connection) + priv->connection = g_object_ref (connection); } /** * nm_vpn_plugin_old_get_connection: * * Returns: (transfer full): + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin */ GDBusConnection * nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin) @@ -300,14 +296,22 @@ nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, /* Record the items that need to also be inserted into the * ip4config, for compatibility with older daemons. */ - g_clear_pointer (&priv->banner, g_free); - (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &priv->banner); - g_clear_pointer (&priv->tundev, g_free); - (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &priv->tundev); - g_clear_pointer (&priv->gateway, g_free); - (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "&s", &priv->gateway); - g_clear_pointer (&priv->mtu, g_free); - (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU, "&s", &priv->mtu); + if (priv->banner) + g_variant_unref (priv->banner); + priv->banner = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_BANNER, + G_VARIANT_TYPE ("s")); + if (priv->tundev) + g_variant_unref (priv->tundev); + priv->tundev = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, + G_VARIANT_TYPE ("s")); + if (priv->gateway) + g_variant_unref (priv->gateway); + priv->gateway = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, + G_VARIANT_TYPE ("u")); + if (priv->mtu) + g_variant_unref (priv->mtu); + priv->mtu = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_MTU, + G_VARIANT_TYPE ("u")); g_signal_emit (plugin, signals[CONFIG], 0, config); } @@ -320,7 +324,8 @@ nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, GVariant *combined_config; GVariantBuilder builder; GVariantIter iter; - const char *key, *value; + const char *key; + GVariant *value; g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); g_return_if_fail (ip4_config != NULL); @@ -340,19 +345,21 @@ nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, * being emitted. So just copy all of that data into the ip4 * config too. */ - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); g_variant_iter_init (&iter, ip4_config); - while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) - g_variant_builder_add (&builder, "{ss}", key, value); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) { + g_variant_builder_add (&builder, "{sv}", key, value); + g_variant_unref (value); + } if (priv->banner) - g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); if (priv->tundev) - g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); if (priv->gateway) - g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway); + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway); if (priv->mtu) - g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); combined_config = g_variant_builder_end (&builder); g_variant_ref_sink (combined_config); @@ -373,9 +380,13 @@ nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); g_return_if_fail (ip6_config != NULL); + g_variant_ref_sink (ip6_config); + priv->got_ip6 = TRUE; g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config); + g_variant_unref (ip6_config); + if ( priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); @@ -483,7 +494,7 @@ impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin, gpointer user_data) { NMConnection *connection; - char *setting_name; + const char *setting_name; gboolean needed; GError *error = NULL; @@ -519,7 +530,6 @@ impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin, g_assert (setting_name); g_dbus_method_invocation_return_value (context, g_variant_new ("(s)", setting_name)); - g_free (setting_name); } else { /* No secrets required */ g_dbus_method_invocation_return_value (context, @@ -596,6 +606,8 @@ impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin, * request new secrets when the secrets originally provided by NetworkManager * are insufficient, or the VPN process indicates that it needs additional * information to complete the request. + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin */ void nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, @@ -648,6 +660,8 @@ free_secret (gpointer data) * an applet when the applet calls the authentication dialog of the VPN plugin. * * Returns: %TRUE if reading values was successful, %FALSE if not + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin **/ gboolean nm_vpn_plugin_old_read_vpn_details (int fd, @@ -749,6 +763,8 @@ nm_vpn_plugin_old_read_vpn_details (int fd, * * Returns: %TRUE if the flag data item was found and successfully converted * to flags, %FALSE if not + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin **/ gboolean nm_vpn_plugin_old_get_secret_flags (GHashTable *data, @@ -910,8 +926,8 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) ret = g_dbus_proxy_call_sync (proxy, "RequestName", - g_variant_new ("(s)", priv->dbus_service_name), - G_DBUS_CALL_FLAGS_NONE, 0, + g_variant_new ("(su)", priv->dbus_service_name, 0), + G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); g_object_unref (proxy); if (!ret) { @@ -1027,10 +1043,10 @@ finalize (GObject *object) nm_vpn_plugin_old_set_connection (plugin, NULL); g_free (priv->dbus_service_name); - g_clear_pointer (&priv->banner, g_free); - g_clear_pointer (&priv->tundev, g_free); - g_clear_pointer (&priv->gateway, g_free); - g_clear_pointer (&priv->mtu, g_free); + g_clear_pointer (&priv->banner, g_variant_unref); + g_clear_pointer (&priv->tundev, g_variant_unref); + g_clear_pointer (&priv->gateway, g_variant_unref); + g_clear_pointer (&priv->mtu, g_variant_unref); G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->finalize (object); } @@ -1078,6 +1094,8 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class) * NMVpnPluginOld:service-name: * * The D-Bus service name of this plugin. + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin */ g_object_class_install_property (object_class, PROP_DBUS_SERVICE_NAME, @@ -1091,6 +1109,8 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class) * NMVpnPluginOld:state: * * The state of the plugin. + * + * Deprecated: 1.2: replaced by NMVpnServicePlugin */ g_object_class_install_property (object_class, PROP_STATE, diff --git a/libnm/nm-vpn-plugin-old.h b/libnm/nm-vpn-plugin-old.h index 7fcc1c1c..59cf4600 100644 --- a/libnm/nm-vpn-plugin-old.h +++ b/libnm/nm-vpn-plugin-old.h @@ -16,7 +16,7 @@ * Boston, MA 02110-1301 USA. * * Copyright 2007 - 2008 Novell, Inc. - * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2015 Red Hat, Inc. */ #ifndef __NM_VPN_PLUGIN_OLD_H__ @@ -39,94 +39,122 @@ G_BEGIN_DECLS #define NM_VPN_PLUGIN_OLD_STATE "state" typedef struct { + NM_DEPRECATED_IN_1_2 GObject parent; -} NMVpnPluginOld; +} NMVpnPluginOld NM_DEPRECATED_IN_1_2; typedef struct { + NM_DEPRECATED_IN_1_2 GObjectClass parent; /* Signals */ + NM_DEPRECATED_IN_1_2 void (*state_changed) (NMVpnPluginOld *plugin, NMVpnServiceState state); + NM_DEPRECATED_IN_1_2 void (*ip4_config) (NMVpnPluginOld *plugin, GVariant *ip4_config); + NM_DEPRECATED_IN_1_2 void (*login_banner) (NMVpnPluginOld *plugin, const char *banner); + NM_DEPRECATED_IN_1_2 void (*failure) (NMVpnPluginOld *plugin, NMVpnPluginFailure reason); + NM_DEPRECATED_IN_1_2 void (*quit) (NMVpnPluginOld *plugin); + NM_DEPRECATED_IN_1_2 void (*config) (NMVpnPluginOld *plugin, GVariant *config); + NM_DEPRECATED_IN_1_2 void (*ip6_config) (NMVpnPluginOld *plugin, GVariant *config); /* virtual methods */ + NM_DEPRECATED_IN_1_2 gboolean (*connect) (NMVpnPluginOld *plugin, NMConnection *connection, GError **err); + NM_DEPRECATED_IN_1_2 gboolean (*need_secrets) (NMVpnPluginOld *plugin, NMConnection *connection, - char **setting_name, + const char **setting_name, GError **error); + NM_DEPRECATED_IN_1_2 gboolean (*disconnect) (NMVpnPluginOld *plugin, GError **err); + NM_DEPRECATED_IN_1_2 gboolean (*new_secrets) (NMVpnPluginOld *plugin, NMConnection *connection, GError **error); + NM_DEPRECATED_IN_1_2 gboolean (*connect_interactive) (NMVpnPluginOld *plugin, NMConnection *connection, GVariant *details, GError **error); /*< private >*/ + NM_DEPRECATED_IN_1_2 gpointer padding[8]; -} NMVpnPluginOldClass; +} NMVpnPluginOldClass NM_DEPRECATED_IN_1_2; +NM_DEPRECATED_IN_1_2 GType nm_vpn_plugin_old_get_type (void); +NM_DEPRECATED_IN_1_2 GDBusConnection *nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin); +NM_DEPRECATED_IN_1_2 NMVpnServiceState nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin, NMVpnServiceState state); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, const char *message, const char **hints); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin, const char *banner); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin, NMVpnPluginFailure reason); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, GVariant *config); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, GVariant *ip4_config); +NM_DEPRECATED_IN_1_2 void nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, GVariant *ip6_config); +NM_DEPRECATED_IN_1_2 gboolean nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, GError **err); /* Utility functions */ +NM_DEPRECATED_IN_1_2 gboolean nm_vpn_plugin_old_read_vpn_details (int fd, GHashTable **out_data, GHashTable **out_secrets); +NM_DEPRECATED_IN_1_2 gboolean nm_vpn_plugin_old_get_secret_flags (GHashTable *data, const char *secret_name, NMSettingSecretFlags *out_flags); diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c new file mode 100644 index 00000000..ae5af323 --- /dev/null +++ b/libnm/nm-vpn-service-plugin.c @@ -0,0 +1,1302 @@ +/* -*- 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 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-vpn-service-plugin.h" + +#include +#include +#include + +#include "nm-glib.h" +#include "nm-enum-types.h" +#include "nm-utils.h" +#include "nm-connection.h" +#include "nm-dbus-helpers.h" +#include "nm-core-internal.h" +#include "nm-simple-connection.h" +#include "nm-macros-internal.h" + +#include "nmdbus-vpn-plugin.h" + +#define NM_VPN_SERVICE_PLUGIN_QUIT_TIMER 180 + +static void nm_vpn_service_plugin_initable_iface_init (GInitableIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMVpnServicePlugin, nm_vpn_service_plugin, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_vpn_service_plugin_initable_iface_init); + ) + +typedef struct { + NMVpnServiceState state; + + /* DBUS-y stuff */ + GDBusConnection *connection; + NMDBusVpnPlugin *dbus_vpn_service_plugin; + char *dbus_service_name; + gboolean dbus_watch_peer; + + /* Temporary stuff */ + guint connect_timer; + guint quit_timer; + guint fail_stop_id; + guint peer_watch_id; + gboolean interactive; + + gboolean got_config; + gboolean has_ip4, got_ip4; + gboolean has_ip6, got_ip6; + + /* Config stuff copied from config to ip4config */ + GVariant *banner, *tundev, *gateway, *mtu; +} NMVpnServicePluginPrivate; + +#define NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginPrivate)) + +enum { + STATE_CHANGED, + CONFIG, + IP4_CONFIG, + IP6_CONFIG, + LOGIN_BANNER, + FAILURE, + QUIT, + SECRETS_REQUIRED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_DBUS_SERVICE_NAME, + PROP_DBUS_WATCH_PEER, + PROP_STATE, + + LAST_PROP +}; + +static GSList *active_plugins = NULL; + + +static void +nm_vpn_service_plugin_set_connection (NMVpnServicePlugin *plugin, + GDBusConnection *connection) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + g_clear_object (&priv->connection); + + if (connection) + priv->connection = g_object_ref (connection); +} + +/** + * nm_vpn_service_plugin_get_connection: + * + * Returns: (transfer full): + * + * Since: 1.2 + */ +GDBusConnection * +nm_vpn_service_plugin_get_connection (NMVpnServicePlugin *plugin) +{ + GDBusConnection *connection; + + g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), NULL); + + connection = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin)->connection; + + if (connection) + g_object_ref (connection); + + return connection; +} + +static NMVpnServiceState +nm_vpn_service_plugin_get_state (NMVpnServicePlugin *plugin) +{ + g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), NM_VPN_SERVICE_STATE_UNKNOWN); + + return NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin)->state; +} + +static void +nm_vpn_service_plugin_set_state (NMVpnServicePlugin *plugin, + NMVpnServiceState state) +{ + NMVpnServicePluginPrivate *priv; + + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + if (priv->state != state) { + priv->state = state; + g_signal_emit (plugin, signals[STATE_CHANGED], 0, state); + nmdbus_vpn_plugin_emit_state_changed (priv->dbus_vpn_service_plugin, state); + } +} + +void +nm_vpn_service_plugin_set_login_banner (NMVpnServicePlugin *plugin, + const char *banner) +{ + NMVpnServicePluginPrivate *priv; + + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + g_return_if_fail (banner != NULL); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner); + nmdbus_vpn_plugin_emit_login_banner (priv->dbus_vpn_service_plugin, banner); +} + +static void +_emit_failure (NMVpnServicePlugin *plugin, + NMVpnPluginFailure reason) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + g_signal_emit (plugin, signals[FAILURE], 0, reason); + nmdbus_vpn_plugin_emit_failure (priv->dbus_vpn_service_plugin, reason); +} + +void +nm_vpn_service_plugin_failure (NMVpnServicePlugin *plugin, + NMVpnPluginFailure reason) +{ + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + + _emit_failure (plugin, reason); + nm_vpn_service_plugin_disconnect (plugin, NULL); +} + +gboolean +nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin, GError **err) +{ + NMVpnServicePluginPrivate *priv; + gboolean ret = FALSE; + NMVpnServiceState state; + + g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), FALSE); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + state = nm_vpn_service_plugin_get_state (plugin); + switch (state) { + case NM_VPN_SERVICE_STATE_STOPPING: + g_set_error (err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, + "%s", + "Could not process the request because the VPN connection is already being stopped."); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + g_set_error (err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, + "%s", + "Could not process the request because no VPN connection was active."); + break; + case NM_VPN_SERVICE_STATE_STARTING: + _emit_failure (plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + /* fallthru */ + case NM_VPN_SERVICE_STATE_STARTED: + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING); + ret = NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err); + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED); + break; + case NM_VPN_SERVICE_STATE_INIT: + ret = TRUE; + break; + + default: + g_warning ("Unhandled VPN service state %d", state); + g_assert_not_reached (); + break; + } + + return ret; +} + +static void +nm_vpn_service_plugin_emit_quit (NMVpnServicePlugin *plugin) +{ + g_signal_emit (plugin, signals[QUIT], 0); +} + +static gboolean +connect_timer_expired (gpointer data) +{ + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN (data); + GError *err = NULL; + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin)->connect_timer = 0; + g_message ("Connect timer expired, disconnecting."); + nm_vpn_service_plugin_disconnect (plugin, &err); + if (err) { + g_warning ("Disconnect failed: %s", err->message); + g_error_free (err); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +quit_timer_expired (gpointer data) +{ + NMVpnServicePlugin *self = NM_VPN_SERVICE_PLUGIN (data); + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (self)->quit_timer = 0; + nm_vpn_service_plugin_emit_quit (self); + return G_SOURCE_REMOVE; +} + +static void +schedule_quit_timer (NMVpnServicePlugin *self) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (self); + + nm_clear_g_source (&priv->quit_timer); + priv->quit_timer = g_timeout_add_seconds (NM_VPN_SERVICE_PLUGIN_QUIT_TIMER, + quit_timer_expired, + self); +} + +static gboolean +fail_stop (gpointer data) +{ + NMVpnServicePlugin *self = NM_VPN_SERVICE_PLUGIN (data); + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (self)->fail_stop_id = 0; + nm_vpn_service_plugin_set_state (self, NM_VPN_SERVICE_STATE_STOPPED); + return G_SOURCE_REMOVE; +} + +static void +schedule_fail_stop (NMVpnServicePlugin *plugin) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + nm_clear_g_source (&priv->fail_stop_id); + priv->fail_stop_id = g_idle_add (fail_stop, plugin); +} + +void +nm_vpn_service_plugin_set_config (NMVpnServicePlugin *plugin, + GVariant *config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + g_return_if_fail (config != NULL); + + priv->got_config = TRUE; + + (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4); + (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6); + + g_warn_if_fail (priv->has_ip4 || priv->has_ip6); + + /* Record the items that need to also be inserted into the + * ip4config, for compatibility with older daemons. + */ + if (priv->banner) + g_variant_unref (priv->banner); + priv->banner = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_BANNER, + G_VARIANT_TYPE ("s")); + if (priv->tundev) + g_variant_unref (priv->tundev); + priv->tundev = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, + G_VARIANT_TYPE ("s")); + if (priv->gateway) + g_variant_unref (priv->gateway); + priv->gateway = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, + G_VARIANT_TYPE ("u")); + if (priv->mtu) + g_variant_unref (priv->mtu); + priv->mtu = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_MTU, + G_VARIANT_TYPE ("u")); + + g_signal_emit (plugin, signals[CONFIG], 0, config); + nmdbus_vpn_plugin_emit_config (priv->dbus_vpn_service_plugin, config); +} + +void +nm_vpn_service_plugin_set_ip4_config (NMVpnServicePlugin *plugin, + GVariant *ip4_config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + GVariant *combined_config; + GVariantBuilder builder; + GVariantIter iter; + const char *key; + GVariant *value; + + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + g_return_if_fail (ip4_config != NULL); + + priv->got_ip4 = TRUE; + + /* Old plugins won't send the "config" signal and thus can't send + * NM_VPN_SERVICE_PLUGIN_CONFIG_HAS_IP4 either. But since they don't support IPv6, + * we can safely assume that, if we don't receive a "config" signal but do + * receive an "ip4-config" signal, the old plugin supports IPv4. + */ + if (!priv->got_config) + priv->has_ip4 = TRUE; + + /* Older NetworkManager daemons expect all config info to be in + * the ip4 config, so they won't even notice the "config" signal + * being emitted. So just copy all of that data into the ip4 + * config too. + */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_iter_init (&iter, ip4_config); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) { + g_variant_builder_add (&builder, "{sv}", key, value); + g_variant_unref (value); + } + + if (priv->banner) + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, priv->banner); + if (priv->tundev) + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, priv->tundev); + if (priv->gateway) + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, priv->gateway); + if (priv->mtu) + g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, priv->mtu); + + combined_config = g_variant_builder_end (&builder); + g_variant_ref_sink (combined_config); + g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config); + nmdbus_vpn_plugin_emit_ip4_config (priv->dbus_vpn_service_plugin, combined_config); + g_variant_unref (combined_config); + + if ( priv->has_ip4 == priv->got_ip4 + && priv->has_ip6 == priv->got_ip6) + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +void +nm_vpn_service_plugin_set_ip6_config (NMVpnServicePlugin *plugin, + GVariant *ip6_config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin)); + g_return_if_fail (ip6_config != NULL); + + g_variant_ref_sink (ip6_config); + + priv->got_ip6 = TRUE; + g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config); + nmdbus_vpn_plugin_emit_ip6_config (priv->dbus_vpn_service_plugin, ip6_config); + + g_variant_unref (ip6_config); + + if ( priv->has_ip4 == priv->got_ip4 + && priv->has_ip6 == priv->got_ip6) + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +static void +connect_timer_start (NMVpnServicePlugin *plugin) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + nm_clear_g_source (&priv->connect_timer); + priv->connect_timer = g_timeout_add_seconds (60, connect_timer_expired, plugin); +} + +static void +peer_vanished (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + nm_vpn_service_plugin_disconnect (NM_VPN_SERVICE_PLUGIN (user_data), NULL); +} + +static guint +watch_peer (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context) +{ + GDBusConnection *connection = g_dbus_method_invocation_get_connection (context); + const gchar *peer = g_dbus_message_get_sender (g_dbus_method_invocation_get_message (context)); + + return g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameOwnerChanged", + "/org/freedesktop/DBus", + peer, + G_DBUS_SIGNAL_FLAGS_NONE, + peer_vanished, + plugin, + NULL); +} + +static void +_connect_generic (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + GVariant *details) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + NMVpnServicePluginClass *vpn_class = NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin); + NMConnection *connection; + gboolean success = FALSE; + GError *error = NULL; + + if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && + priv->state != NM_VPN_SERVICE_STATE_INIT) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return; + } + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); + return; + } + + priv->interactive = FALSE; + if (details && !vpn_class->connect_interactive) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return; + } + + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + + if (priv->dbus_watch_peer) + priv->peer_watch_id = watch_peer (plugin, context); + + if (details) { + priv->interactive = TRUE; + success = vpn_class->connect_interactive (plugin, connection, details, &error); + } else + success = vpn_class->connect (plugin, connection, &error); + + if (success) { + g_dbus_method_invocation_return_value (context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); + } else { + g_dbus_method_invocation_take_error (context, error); + + /* Stop the plugin from an idle handler so that the Connect + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); + } + + g_object_unref (connection); +} + +static void +impl_vpn_service_plugin_connect (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *connection, + gpointer user_data) +{ + _connect_generic (plugin, context, connection, NULL); +} + +static void +impl_vpn_service_plugin_connect_interactive (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *connection, + GVariant *details, + gpointer user_data) +{ + _connect_generic (plugin, context, connection, details); +} + +/***************************************************************/ + +static void +impl_vpn_service_plugin_need_secrets (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) +{ + NMConnection *connection; + const char *setting_name; + gboolean needed; + GError *error = NULL; + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + error->message); + g_error_free (error); + return; + } + + if (!NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->need_secrets) { + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); + return; + } + + needed = NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->need_secrets (plugin, connection, &setting_name, &error); + if (error) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + if (needed) { + /* Push back the quit timer so the VPN plugin doesn't quit in the + * middle of asking the user for secrets. + */ + schedule_quit_timer (plugin); + + g_assert (setting_name); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", setting_name)); + } else { + /* No secrets required */ + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); + } +} + +static void +impl_vpn_service_plugin_new_secrets (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + NMConnection *connection; + GError *error = NULL; + gboolean success; + + if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return; + } + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); + return; + } + + if (!NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->new_secrets) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); + g_object_unref (connection); + return; + } + + success = NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->new_secrets (plugin, connection, &error); + if (success) { + g_dbus_method_invocation_return_value (context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); + } else { + g_dbus_method_invocation_take_error (context, error); + + /* Stop the plugin from and idle handler so that the NewSecrets + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); + } + + g_object_unref (connection); +} + +/** + * nm_vpn_service_plugin_secrets_required: + * @plugin: the #NMVpnServicePlugin + * @message: an information message about why secrets are required, if any + * @hints: VPN specific secret names for required new secrets + * + * Called by VPN plugin implementations to signal to NetworkManager that secrets + * are required during the connection process. This signal may be used to + * request new secrets when the secrets originally provided by NetworkManager + * are insufficient, or the VPN process indicates that it needs additional + * information to complete the request. + * + * Since: 1.2 + */ +void +nm_vpn_service_plugin_secrets_required (NMVpnServicePlugin *plugin, + const char *message, + const char **hints) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + /* Plugin must be able to accept the new secrets if it calls this method */ + g_return_if_fail (NM_VPN_SERVICE_PLUGIN_GET_CLASS (plugin)->new_secrets); + + /* Plugin cannot call this method if NetworkManager didn't originally call + * ConnectInteractive(). + */ + g_return_if_fail (priv->interactive == TRUE); + + /* Cancel the connect timer since secrets might take a while. It'll + * get restarted when the secrets come back via NewSecrets(). + */ + nm_clear_g_source (&priv->connect_timer); + + g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints); + nmdbus_vpn_plugin_emit_secrets_required (priv->dbus_vpn_service_plugin, message, hints); +} + +/***************************************************************/ + +#define DATA_KEY_TAG "DATA_KEY=" +#define DATA_VAL_TAG "DATA_VAL=" +#define SECRET_KEY_TAG "SECRET_KEY=" +#define SECRET_VAL_TAG "SECRET_VAL=" + +static void +free_secret (gpointer data) +{ + char *secret = data; + + memset (secret, 0, strlen (secret)); + g_free (secret); +} + +/** + * nm_vpn_service_plugin_read_vpn_details: + * @fd: file descriptor to read from, usually stdin (0) + * @out_data: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairs of VPN data items + * @out_secrets: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairsof VPN secrets + * + * Parses key/value pairs from a file descriptor (normally stdin) passed by + * an applet when the applet calls the authentication dialog of the VPN plugin. + * + * Returns: %TRUE if reading values was successful, %FALSE if not + * + * Since: 1.2 + **/ +gboolean +nm_vpn_service_plugin_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets) +{ + GHashTable *data, *secrets; + gboolean success = FALSE; + char *key = NULL, *val = NULL; + GString *line; + gchar c; + + if (out_data) + g_return_val_if_fail (*out_data == NULL, FALSE); + if (out_secrets) + g_return_val_if_fail (*out_secrets == NULL, FALSE); + + data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_secret); + + line = g_string_new (NULL); + + /* Read stdin for data and secret items until we get a DONE */ + while (1) { + ssize_t nr; + GHashTable *hash = NULL; + + errno = 0; + nr = read (fd, &c, 1); + if (nr == -1) { + if (errno == EAGAIN) { + g_usleep (100); + continue; + } + break; + } + + if (c != '\n') { + g_string_append_c (line, c); + continue; + } + + /* Check for the finish marker */ + if (strcmp (line->str, "DONE") == 0) + break; + + /* Otherwise it's a data/secret item */ + if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) { + hash = data; + key = g_strdup (line->str + strlen (DATA_KEY_TAG)); + } else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) { + hash = data; + val = g_strdup (line->str + strlen (DATA_VAL_TAG)); + } else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) { + hash = secrets; + key = g_strdup (line->str + strlen (SECRET_KEY_TAG)); + } else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) { + hash = secrets; + val = g_strdup (line->str + strlen (SECRET_VAL_TAG)); + } + g_string_truncate (line, 0); + + if (key && val && hash) { + g_hash_table_insert (hash, key, val); + key = NULL; + val = NULL; + success = TRUE; /* Got at least one value */ + } + } + + if (success) { + if (out_data) + *out_data = data; + else + g_hash_table_destroy (data); + + if (out_secrets) + *out_secrets = secrets; + else + g_hash_table_destroy (secrets); + } else { + g_hash_table_destroy (data); + g_hash_table_destroy (secrets); + } + + g_string_free (line, TRUE); + return success; +} + +/** + * nm_vpn_service_plugin_get_secret_flags: + * @data: hash table containing VPN key/value pair data items + * @secret_name: VPN secret key name for which to retrieve flags for + * @out_flags: (out): on success, the flags associated with @secret_name + * + * Given a VPN secret key name, attempts to find the corresponding flags data + * item in @data. If found, converts the flags data item to + * #NMSettingSecretFlags and returns it. + * + * Returns: %TRUE if the flag data item was found and successfully converted + * to flags, %FALSE if not + * + * Since: 1.2 + **/ +gboolean +nm_vpn_service_plugin_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags) +{ + char *flag_name; + const char *val; + unsigned long tmp; + gboolean success = FALSE; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (out_flags != NULL, FALSE); + g_return_val_if_fail (*out_flags == NM_SETTING_SECRET_FLAG_NONE, FALSE); + + flag_name = g_strdup_printf ("%s-flags", secret_name); + + /* Try new flags value first */ + val = g_hash_table_lookup (data, flag_name); + if (val) { + errno = 0; + tmp = strtoul (val, NULL, 10); + if (errno == 0 && tmp <= NM_SETTING_SECRET_FLAGS_ALL) { + *out_flags = (NMSettingSecretFlags) tmp; + success = TRUE; + } + } + + g_free (flag_name); + return success; +} + +/***************************************************************/ + +static void +impl_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + gpointer user_data) +{ + GError *error = NULL; + + if (nm_vpn_service_plugin_disconnect (plugin, &error)) + g_dbus_method_invocation_return_value (context, NULL); + else + g_dbus_method_invocation_take_error (context, error); +} + +static void +impl_vpn_service_plugin_set_config (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_service_plugin_set_ip4_config (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_ip4_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_service_plugin_set_ip6_config (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_ip6_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_service_plugin_set_failure (NMVpnServicePlugin *plugin, + GDBusMethodInvocation *context, + char *reason, + gpointer user_data) +{ + nm_vpn_service_plugin_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG); + g_dbus_method_invocation_return_value (context, NULL); +} + +/*********************************************************************/ + +static void +sigterm_handler (int signum) +{ + g_slist_foreach (active_plugins, (GFunc) nm_vpn_service_plugin_emit_quit, NULL); +} + +static void +setup_unix_signal_handler (void) +{ + struct sigaction action; + sigset_t block_mask; + + action.sa_handler = sigterm_handler; + sigemptyset (&block_mask); + action.sa_mask = block_mask; + action.sa_flags = 0; + sigaction (SIGINT, &action, NULL); + sigaction (SIGTERM, &action, NULL); +} + +/*********************************************************************/ + +static void +one_plugin_destroyed (gpointer data, + GObject *object) +{ + active_plugins = g_slist_remove (active_plugins, object); +} + +static void +nm_vpn_service_plugin_init (NMVpnServicePlugin *plugin) +{ + active_plugins = g_slist_append (active_plugins, plugin); + g_object_weak_ref (G_OBJECT (plugin), + one_plugin_destroyed, + NULL); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN (initable); + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + GDBusConnection *connection = NULL; + GDBusProxy *proxy; + GVariant *ret; + gboolean success = FALSE; + + if (!priv->dbus_service_name) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("No service name specified")); + return FALSE; + } + + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); + if (!connection) + return FALSE; + + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + cancellable, error); + if (!proxy) + goto out; + + ret = g_dbus_proxy_call_sync (proxy, + "RequestName", + g_variant_new ("(su)", priv->dbus_service_name, 0), + G_DBUS_CALL_FLAGS_NONE, -1, + cancellable, error); + g_object_unref (proxy); + if (!ret) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + goto out; + } + g_variant_unref (ret); + + priv->dbus_vpn_service_plugin = nmdbus_vpn_plugin_skeleton_new (); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_service_plugin), + connection, + NM_VPN_DBUS_PLUGIN_PATH, + error)) + goto out; + + _nm_dbus_bind_properties (plugin, priv->dbus_vpn_service_plugin); + _nm_dbus_bind_methods (plugin, priv->dbus_vpn_service_plugin, + "Connect", impl_vpn_service_plugin_connect, + "ConnectInteractive", impl_vpn_service_plugin_connect_interactive, + "NeedSecrets", impl_vpn_service_plugin_need_secrets, + "NewSecrets", impl_vpn_service_plugin_new_secrets, + "Disconnect", impl_vpn_service_plugin_disconnect, + "SetConfig", impl_vpn_service_plugin_set_config, + "SetIp4Config", impl_vpn_service_plugin_set_ip4_config, + "SetIp6Config", impl_vpn_service_plugin_set_ip6_config, + "SetFailure", impl_vpn_service_plugin_set_failure, + NULL); + + nm_vpn_service_plugin_set_connection (plugin, connection); + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_INIT); + + success = TRUE; + + out: + g_clear_object (&connection); + + return success; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + /* Construct-only */ + priv->dbus_service_name = g_value_dup_string (value); + break; + case PROP_DBUS_WATCH_PEER: + /* Construct-only */ + priv->dbus_watch_peer = g_value_get_boolean (value); + break; + case PROP_STATE: + nm_vpn_service_plugin_set_state (NM_VPN_SERVICE_PLUGIN (object), + (NMVpnServiceState) g_value_get_enum (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) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + g_value_set_string (value, priv->dbus_service_name); + break; + case PROP_DBUS_WATCH_PEER: + g_value_set_boolean (value, priv->dbus_watch_peer); + break; + case PROP_STATE: + g_value_set_enum (value, nm_vpn_service_plugin_get_state (NM_VPN_SERVICE_PLUGIN (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN (object); + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + NMVpnServiceState state; + GError *err = NULL; + + nm_clear_g_source (&priv->fail_stop_id); + nm_clear_g_source (&priv->quit_timer); + nm_clear_g_source (&priv->connect_timer); + + state = nm_vpn_service_plugin_get_state (plugin); + + if (state == NM_VPN_SERVICE_STATE_STARTED || + state == NM_VPN_SERVICE_STATE_STARTING) + nm_vpn_service_plugin_disconnect (plugin, &err); + + if (err) { + g_warning ("Error disconnecting VPN connection: %s", err->message); + g_error_free (err); + } + + G_OBJECT_CLASS (nm_vpn_service_plugin_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN (object); + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + nm_vpn_service_plugin_set_connection (plugin, NULL); + g_free (priv->dbus_service_name); + + g_clear_pointer (&priv->banner, g_variant_unref); + g_clear_pointer (&priv->tundev, g_variant_unref); + g_clear_pointer (&priv->gateway, g_variant_unref); + g_clear_pointer (&priv->mtu, g_variant_unref); + + G_OBJECT_CLASS (nm_vpn_service_plugin_parent_class)->finalize (object); +} + +static void +state_changed (NMVpnServicePlugin *plugin, NMVpnServiceState state) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); + + switch (state) { + case NM_VPN_SERVICE_STATE_STARTING: + nm_clear_g_source (&priv->quit_timer); + nm_clear_g_source (&priv->fail_stop_id); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + if (priv->dbus_watch_peer) + nm_vpn_service_plugin_emit_quit (plugin); + else + schedule_quit_timer (plugin); + if (priv->peer_watch_id) { + g_dbus_connection_signal_unsubscribe (nm_vpn_service_plugin_get_connection (plugin), + priv->peer_watch_id); + priv->peer_watch_id = 0; + } + break; + default: + /* Clean up all timers we might have set up. */ + nm_clear_g_source (&priv->connect_timer); + nm_clear_g_source (&priv->quit_timer); + nm_clear_g_source (&priv->fail_stop_id); + break; + } +} + +static void +nm_vpn_service_plugin_class_init (NMVpnServicePluginClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (plugin_class); + + g_type_class_add_private (object_class, sizeof (NMVpnServicePluginPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + plugin_class->state_changed = state_changed; + + /* properties */ + + /** + * NMVpnServicePlugin:service-name: + * + * The D-Bus service name of this plugin. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_DBUS_SERVICE_NAME, + g_param_spec_string (NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnServicePlugin:watch-peer: + * + * Whether to watch for D-Bus peer's changes. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_DBUS_WATCH_PEER, + g_param_spec_boolean (NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + /** + * NMVpnServicePlugin:state: + * + * The state of the plugin. + * + * Since: 1.2 + */ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_VPN_SERVICE_PLUGIN_STATE, "", "", + NM_TYPE_VPN_SERVICE_STATE, + NM_VPN_SERVICE_STATE_INIT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, state_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + signals[SECRETS_REQUIRED] = + g_signal_new ("secrets-required", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRV); + + signals[CONFIG] = + g_signal_new ("config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[IP4_CONFIG] = + g_signal_new ("ip4-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, ip4_config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[IP6_CONFIG] = + g_signal_new ("ip6-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, ip6_config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[LOGIN_BANNER] = + g_signal_new ("login-banner", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, login_banner), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + signals[FAILURE] = + g_signal_new ("failure", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, failure), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + signals[QUIT] = + g_signal_new ("quit", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnServicePluginClass, quit), + NULL, NULL, + NULL, + G_TYPE_NONE, 0, + G_TYPE_NONE); + + setup_unix_signal_handler (); +} + +static void +nm_vpn_service_plugin_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} diff --git a/libnm/nm-vpn-service-plugin.h b/libnm/nm-vpn-service-plugin.h new file mode 100644 index 00000000..f8b4ff87 --- /dev/null +++ b/libnm/nm-vpn-service-plugin.h @@ -0,0 +1,160 @@ +/* -*- 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 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_SERVICE_PLUGIN_H__ +#define __NM_VPN_SERVICE_PLUGIN_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_SERVICE_PLUGIN (nm_vpn_service_plugin_get_type ()) +#define NM_VPN_SERVICE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePlugin)) +#define NM_VPN_SERVICE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass)) +#define NM_IS_VPN_SERVICE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE_PLUGIN)) +#define NM_IS_VPN_SERVICE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_SERVICE_PLUGIN)) +#define NM_VPN_SERVICE_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass)) + +#define NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME "service-name" +#define NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER "watch-peer" +#define NM_VPN_SERVICE_PLUGIN_STATE "state" + +typedef struct { + NM_AVAILABLE_IN_1_2 + GObject parent; +} NMVpnServicePlugin NM_AVAILABLE_IN_1_2; + +typedef struct { + NM_AVAILABLE_IN_1_2 + GObjectClass parent; + + /* Signals */ + NM_AVAILABLE_IN_1_2 + void (*state_changed) (NMVpnServicePlugin *plugin, + NMVpnServiceState state); + + NM_AVAILABLE_IN_1_2 + void (*ip4_config) (NMVpnServicePlugin *plugin, + GVariant *ip4_config); + + NM_AVAILABLE_IN_1_2 + void (*login_banner) (NMVpnServicePlugin *plugin, + const char *banner); + + NM_AVAILABLE_IN_1_2 + void (*failure) (NMVpnServicePlugin *plugin, + NMVpnPluginFailure reason); + + NM_AVAILABLE_IN_1_2 + void (*quit) (NMVpnServicePlugin *plugin); + + NM_AVAILABLE_IN_1_2 + void (*config) (NMVpnServicePlugin *plugin, + GVariant *config); + + NM_AVAILABLE_IN_1_2 + void (*ip6_config) (NMVpnServicePlugin *plugin, + GVariant *config); + + /* virtual methods */ + NM_AVAILABLE_IN_1_2 + gboolean (*connect) (NMVpnServicePlugin *plugin, + NMConnection *connection, + GError **err); + + NM_AVAILABLE_IN_1_2 + gboolean (*need_secrets) (NMVpnServicePlugin *plugin, + NMConnection *connection, + const char **setting_name, + GError **error); + + NM_AVAILABLE_IN_1_2 + gboolean (*disconnect) (NMVpnServicePlugin *plugin, + GError **err); + + NM_AVAILABLE_IN_1_2 + gboolean (*new_secrets) (NMVpnServicePlugin *plugin, + NMConnection *connection, + GError **error); + + NM_AVAILABLE_IN_1_2 + gboolean (*connect_interactive) (NMVpnServicePlugin *plugin, + NMConnection *connection, + GVariant *details, + GError **error); + + /*< private >*/ + NM_AVAILABLE_IN_1_2 + gpointer padding[8]; +} NMVpnServicePluginClass NM_AVAILABLE_IN_1_2; + +NM_AVAILABLE_IN_1_2 +GType nm_vpn_service_plugin_get_type (void); + +NM_AVAILABLE_IN_1_2 +GDBusConnection *nm_vpn_service_plugin_get_connection (NMVpnServicePlugin *plugin); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_secrets_required (NMVpnServicePlugin *plugin, + const char *message, + const char **hints); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_login_banner (NMVpnServicePlugin *plugin, + const char *banner); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_failure (NMVpnServicePlugin *plugin, + NMVpnPluginFailure reason); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_config (NMVpnServicePlugin *plugin, + GVariant *config); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_ip4_config (NMVpnServicePlugin *plugin, + GVariant *ip4_config); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_ip6_config (NMVpnServicePlugin *plugin, + GVariant *ip6_config); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin, + GError **err); + +/* Utility functions */ + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_service_plugin_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_service_plugin_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags); + +G_END_DECLS + +#endif /* __NM_VPN_SERVICE_PLUGIN_H__ */ diff --git a/libnm/nm-wimax-nsp.c b/libnm/nm-wimax-nsp.c index 0fed1c6e..9fbc6ea1 100644 --- a/libnm/nm-wimax-nsp.c +++ b/libnm/nm-wimax-nsp.c @@ -22,12 +22,11 @@ #include -#include "nm-glib-compat.h" - #include #include #include +#include "nm-default.h" #include "nm-wimax-nsp.h" #include "nm-dbus-interface.h" #include "nm-object-private.h" diff --git a/libnm/tests/Makefile.am b/libnm/tests/Makefile.am index 0acbae8f..ddcf50be 100644 --- a/libnm/tests/Makefile.am +++ b/libnm/tests/Makefile.am @@ -1,13 +1,13 @@ if ENABLE_TESTS AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ + -I$(top_srcdir)/shared \ + -I$(top_builddir)/shared \ -I$(top_srcdir)/libnm \ -I$(top_builddir)/libnm \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ - -DNETWORKMANAGER_COMPILATION \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ $(GLIB_CFLAGS) @@ -26,18 +26,18 @@ endif TESTS = test-nm-client test-remote-settings-client test-secret-agent test_nm_client_SOURCES = \ - common.c \ - common.h \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h \ test-nm-client.c test_remote_settings_client_SOURCES = \ - common.c \ - common.h \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h \ test-remote-settings-client.c test_secret_agent_SOURCES = \ - common.c \ - common.h \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h \ test-secret-agent.c endif diff --git a/libnm/tests/Makefile.in b/libnm/tests/Makefile.in index 0ced3864..0b553a78 100644 --- a/libnm/tests/Makefile.in +++ b/libnm/tests/Makefile.in @@ -118,8 +118,11 @@ CONFIG_CLEAN_VPATH_FILES = @ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-secret-agent$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) -am__test_nm_client_SOURCES_DIST = common.c common.h test-nm-client.c -@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = common.$(OBJEXT) \ +am__test_nm_client_SOURCES_DIST = \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h test-nm-client.c +@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ nm-test-utils-impl.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test-nm-client.$(OBJEXT) test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS) test_nm_client_LDADD = $(LDADD) @@ -131,10 +134,12 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am__test_remote_settings_client_SOURCES_DIST = common.c common.h \ +am__test_remote_settings_client_SOURCES_DIST = \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h \ test-remote-settings-client.c @ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = \ -@ENABLE_TESTS_TRUE@ common.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ nm-test-utils-impl.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.$(OBJEXT) test_remote_settings_client_OBJECTS = \ $(am_test_remote_settings_client_OBJECTS) @@ -142,9 +147,12 @@ test_remote_settings_client_LDADD = $(LDADD) @ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) -am__test_secret_agent_SOURCES_DIST = common.c common.h \ +am__test_secret_agent_SOURCES_DIST = \ + $(top_builddir)/shared/nm-test-utils-impl.c \ + $(top_builddir)/shared/nm-test-libnm-utils.h \ test-secret-agent.c -@ENABLE_TESTS_TRUE@am_test_secret_agent_OBJECTS = common.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@am_test_secret_agent_OBJECTS = \ +@ENABLE_TESTS_TRUE@ nm-test-utils-impl.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test-secret-agent.$(OBJEXT) test_secret_agent_OBJECTS = $(am_test_secret_agent_OBJECTS) test_secret_agent_LDADD = $(LDADD) @@ -437,7 +445,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@ @@ -449,8 +456,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@ @@ -460,6 +465,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@ @@ -514,16 +520,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@ @@ -560,6 +563,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@ @@ -588,7 +593,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@ @@ -603,6 +607,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@ @@ -663,6 +669,7 @@ mkdir_p = @mkdir_p@ nmbinary = @nmbinary@ nmconfdir = @nmconfdir@ nmdatadir = @nmdatadir@ +nmlibdir = @nmlibdir@ nmrundir = @nmrundir@ nmstatedir = @nmstatedir@ oldincludedir = @oldincludedir@ @@ -670,6 +677,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -686,13 +694,13 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/shared \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/shared \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ -@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) @@ -703,18 +711,18 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@@WITH_VALGRIND_FALSE@LOG_COMPILER = $(srcdir)/libnm-test-launch.sh @ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \ -@ENABLE_TESTS_TRUE@ common.c \ -@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-utils-impl.c \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-libnm-utils.h \ @ENABLE_TESTS_TRUE@ test-nm-client.c @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \ -@ENABLE_TESTS_TRUE@ common.c \ -@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-utils-impl.c \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-libnm-utils.h \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.c @ENABLE_TESTS_TRUE@test_secret_agent_SOURCES = \ -@ENABLE_TESTS_TRUE@ common.c \ -@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-utils-impl.c \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/shared/nm-test-libnm-utils.h \ @ENABLE_TESTS_TRUE@ test-secret-agent.c EXTRA_DIST = libnm-test-launch.sh @@ -779,7 +787,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-test-utils-impl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-secret-agent.Po@am__quote@ @@ -805,6 +813,20 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +nm-test-utils-impl.o: $(top_builddir)/shared/nm-test-utils-impl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-test-utils-impl.o -MD -MP -MF $(DEPDIR)/nm-test-utils-impl.Tpo -c -o nm-test-utils-impl.o `test -f '$(top_builddir)/shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`$(top_builddir)/shared/nm-test-utils-impl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-test-utils-impl.Tpo $(DEPDIR)/nm-test-utils-impl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/shared/nm-test-utils-impl.c' object='nm-test-utils-impl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-test-utils-impl.o `test -f '$(top_builddir)/shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`$(top_builddir)/shared/nm-test-utils-impl.c + +nm-test-utils-impl.obj: $(top_builddir)/shared/nm-test-utils-impl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-test-utils-impl.obj -MD -MP -MF $(DEPDIR)/nm-test-utils-impl.Tpo -c -o nm-test-utils-impl.obj `if test -f '$(top_builddir)/shared/nm-test-utils-impl.c'; then $(CYGPATH_W) '$(top_builddir)/shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/shared/nm-test-utils-impl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-test-utils-impl.Tpo $(DEPDIR)/nm-test-utils-impl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_builddir)/shared/nm-test-utils-impl.c' object='nm-test-utils-impl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-test-utils-impl.obj `if test -f '$(top_builddir)/shared/nm-test-utils-impl.c'; then $(CYGPATH_W) '$(top_builddir)/shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/shared/nm-test-utils-impl.c'; fi` + mostlyclean-libtool: -rm -f *.lo diff --git a/libnm/tests/common.c b/libnm/tests/common.c deleted file mode 100644 index 8c1b83a8..00000000 --- a/libnm/tests/common.c +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2010 - 2014 Red Hat, Inc. - * - */ - -#include "config.h" - -#include -#include - -#include "NetworkManager.h" - -#include "common.h" - -static gboolean -name_exists (GDBusConnection *c, const char *name) -{ - GVariant *reply; - gboolean exists = FALSE; - - reply = g_dbus_connection_call_sync (c, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "GetNameOwner", - g_variant_new ("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - NULL, - NULL); - if (reply != NULL) { - exists = TRUE; - g_variant_unref (reply); - } - - return exists; -} - -NMTestServiceInfo * -nm_test_service_init (void) -{ - NMTestServiceInfo *info; - const char *args[2] = { TEST_NM_SERVICE, NULL }; - GError *error = NULL; - int i; - - info = g_malloc0 (sizeof (*info)); - - info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - g_assert_no_error (error); - - /* Spawn the test service. info->keepalive_fd will be a pipe to the service's - * stdin; if it closes, the service will exit immediately. We use this to - * make sure the service exits if the test program crashes. - */ - g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL, - &info->pid, &info->keepalive_fd, NULL, NULL, &error); - g_assert_no_error (error); - - /* Wait until the service is registered on the bus */ - for (i = 1000; i > 0; i--) { - if (name_exists (info->bus, "org.freedesktop.NetworkManager")) - break; - g_usleep (G_USEC_PER_SEC / 50); - } - g_assert (i > 0); - - /* Grab a proxy to our fake NM service to trigger tests */ - info->proxy = g_dbus_proxy_new_sync (info->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - NM_DBUS_SERVICE, - NM_DBUS_PATH, - "org.freedesktop.NetworkManager.LibnmGlibTest", - NULL, &error); - g_assert_no_error (error); - - return info; -} - -void -nm_test_service_cleanup (NMTestServiceInfo *info) -{ - int i; - - g_object_unref (info->proxy); - kill (info->pid, SIGTERM); - - /* Wait until the bus notices the service is gone */ - for (i = 100; i > 0; i--) { - if (!name_exists (info->bus, "org.freedesktop.NetworkManager")) - break; - g_usleep (G_USEC_PER_SEC / 50); - } - g_assert (i > 0); - - g_object_unref (info->bus); - close (info->keepalive_fd); - - memset (info, 0, sizeof (*info)); - g_free (info); -} - -typedef struct { - GMainLoop *loop; - const char *ifname; - char *path; - NMDevice *device; -} AddDeviceInfo; - -static void -device_added_cb (NMClient *client, - NMDevice *device, - gpointer user_data) -{ - AddDeviceInfo *info = user_data; - - g_assert (device); - g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path); - g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname); - - info->device = device; - g_main_loop_quit (info->loop); -} - -static gboolean -timeout (gpointer user_data) -{ - g_assert_not_reached (); - return G_SOURCE_REMOVE; -} - -NMDevice * -nm_test_service_add_device (NMTestServiceInfo *sinfo, NMClient *client, - const char *method, const char *ifname) -{ - AddDeviceInfo info; - GError *error = NULL; - GVariant *ret; - guint timeout_id; - - ret = g_dbus_proxy_call_sync (sinfo->proxy, - method, - g_variant_new ("(s)", ifname), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 3000, - NULL, - &error); - g_assert_no_error (error); - g_assert (ret); - g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); - g_variant_get (ret, "(o)", &info.path); - g_variant_unref (ret); - - /* Wait for libnm to find the device */ - info.ifname = ifname; - info.loop = g_main_loop_new (NULL, FALSE); - g_signal_connect (client, "device-added", - G_CALLBACK (device_added_cb), &info); - timeout_id = g_timeout_add_seconds (5, timeout, NULL); - g_main_loop_run (info.loop); - - g_source_remove (timeout_id); - g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); - g_free (info.path); - g_main_loop_unref (info.loop); - - return info.device; -} diff --git a/libnm/tests/common.h b/libnm/tests/common.h deleted file mode 100644 index aa15167b..00000000 --- a/libnm/tests/common.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2014 Red Hat, Inc. - */ - -#include -#include - -typedef struct { - GDBusConnection *bus; - GDBusProxy *proxy; - GPid pid; - int keepalive_fd; -} NMTestServiceInfo; - -NMTestServiceInfo *nm_test_service_init (void); -void nm_test_service_cleanup (NMTestServiceInfo *info); - -NMDevice *nm_test_service_add_device (NMTestServiceInfo *info, - NMClient *client, - const char *method, - const char *ifname); diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c index 3541c741..5be69142 100644 --- a/libnm/tests/test-nm-client.c +++ b/libnm/tests/test-nm-client.c @@ -20,20 +20,14 @@ #include "config.h" -#include #include #include #include -#include -#include "nm-glib-compat.h" - -#include "common.h" - -#include "nm-test-utils.h" +#include "nm-test-libnm-utils.h" static GMainLoop *loop = NULL; -static NMTestServiceInfo *sinfo; +static NMTstcServiceInfo *sinfo; /*******************************************************************/ @@ -75,7 +69,7 @@ test_device_added (void) gboolean notified = FALSE; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -88,7 +82,7 @@ test_device_added (void) ¬ified); /* Tell the test service to add a new device */ - nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); /* coverity[loop_condition] */ while (!notified) @@ -109,7 +103,7 @@ test_device_added (void) g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_SOFTWARE); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } /*******************************************************************/ @@ -167,7 +161,7 @@ test_device_added_signal_after_init (void) guint result = 0; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -185,7 +179,7 @@ test_device_added_signal_after_init (void) &result); /* Tell the test service to add a new device */ - nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); /* Ensure the 'device-added' signal doesn't show up before * the 'Devices' property change notification */ @@ -208,7 +202,7 @@ test_device_added_signal_after_init (void) g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } /*******************************************************************/ @@ -315,13 +309,13 @@ test_wifi_ap_added_removed (void) GError *error = NULL; char *expected_path = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); /*************************************/ /* Add the wifi device */ - wifi = (NMDeviceWifi *) nm_test_service_add_device (sinfo, client, "AddWifiDevice", "wlan0"); + wifi = (NMDeviceWifi *) nmtstc_service_add_device (sinfo, client, "AddWifiDevice", "wlan0"); g_assert (NM_IS_DEVICE_WIFI (wifi)); /*************************************/ @@ -407,7 +401,7 @@ test_wifi_ap_added_removed (void) g_free (expected_path); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } /*******************************************************************/ @@ -514,13 +508,13 @@ test_wimax_nsp_added_removed (void) GError *error = NULL; char *expected_path = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); /*************************************/ /* Add the wimax device */ - wimax = (NMDeviceWimax *) nm_test_service_add_device (sinfo, client, "AddWimaxDevice", "wmx0"); + wimax = (NMDeviceWimax *) nmtstc_service_add_device (sinfo, client, "AddWimaxDevice", "wmx0"); g_assert (NM_IS_DEVICE_WIMAX (wimax)); /*************************************/ @@ -606,7 +600,7 @@ test_wimax_nsp_added_removed (void) g_free (expected_path); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } /*******************************************************************/ @@ -690,7 +684,7 @@ test_devices_array (void) GError *error = NULL; GVariant *ret; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); /* Make sure that we test the async codepath in at least one test... */ nm_client_new_async (NULL, new_client_cb, &client); @@ -699,9 +693,9 @@ test_devices_array (void) /*************************************/ /* Add some devices */ - wlan0 = nm_test_service_add_device (sinfo, client,"AddWifiDevice", "wlan0"); - eth0 = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); - eth1 = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth1"); + wlan0 = nmtstc_service_add_device (sinfo, client,"AddWifiDevice", "wlan0"); + eth0 = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + eth1 = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth1"); /* Ensure the devices now exist */ devices = nm_client_get_devices (client); @@ -766,7 +760,7 @@ test_devices_array (void) g_assert (device == eth1); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } static void @@ -805,7 +799,7 @@ test_client_nm_running (void) g_clear_error (&error); /* Now start the test service. */ - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client2 = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -824,7 +818,7 @@ test_client_nm_running (void) g_source_remove (quit_id); /* And kill it */ - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); g_assert (nm_client_get_nm_running (client1)); @@ -938,12 +932,12 @@ test_active_connections (void) TestACInfo info = { loop, NULL, 0 }; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); /* Tell the test service to add a new device */ - device = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + device = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); conn = nmtst_create_minimal_connection ("test-ac", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); nm_client_add_and_activate_connection_async (client, conn, device, NULL, @@ -980,7 +974,7 @@ test_active_connections (void) assert_ac_and_device (client); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } static void @@ -1068,11 +1062,11 @@ test_activate_virtual (void) TestConnectionInfo conn_info = { loop, NULL }; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); - nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); conn = nmtst_create_minimal_connection ("test-ac", NULL, NM_SETTING_VLAN_SETTING_NAME, &s_con); g_object_set (s_con, @@ -1113,7 +1107,7 @@ test_activate_virtual (void) g_object_unref (info.ac); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); } static void @@ -1141,11 +1135,11 @@ test_activate_failed (void) NMConnection *conn; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); - device = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + device = nmtstc_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); /* Note that test-networkmanager-service.py checks for this exact name */ conn = nmtst_create_minimal_connection ("object-creation-failed-test", NULL, @@ -1158,7 +1152,315 @@ test_activate_failed (void) g_object_unref (conn); g_object_unref (client); - g_clear_pointer (&sinfo, nm_test_service_cleanup); + g_clear_pointer (&sinfo, nmtstc_service_cleanup); +} + +static void +test_device_connection_compatibility (void) +{ + NMClient *client; + NMDevice *device1, *device2; + NMConnection *conn; + NMSettingWired *s_wired; + GError *error = NULL; + const char *subchannels[] = { "0.0.8000", "0.0.8001", "0.0.8002", NULL }; + const char *subchannels_2[] = { "0.0.8000", "0.0.8001", NULL }; + const char *subchannels_x[] = { "0.0.8000", "0.0.8001", "0.0.800X", NULL }; + const char *hw_addr1 = "52:54:00:ab:db:23"; + const char *hw_addr2 = "52:54:00:ab:db:24"; + + sinfo = nmtstc_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + /* Create two devices */ + device1 = nmtstc_service_add_wired_device (sinfo, client, "eth0", hw_addr1, subchannels); + device2 = nmtstc_service_add_wired_device (sinfo, client, "eth1", hw_addr2, NULL); + + g_assert_cmpstr (nm_device_get_hw_address (device1), ==, hw_addr1); + g_assert_cmpstr (nm_device_get_hw_address (device2), ==, hw_addr2); + + conn = nmtst_create_minimal_connection ("wired-matches", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + s_wired = nm_connection_get_setting_wired (conn); + nm_setting_wired_add_mac_blacklist_item (s_wired, "00:11:22:33:44:55"); + + /* device1 and conn are compatible */ + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, hw_addr1, + NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels, + NULL); + nm_device_connection_compatible (device1, conn, &error); + g_assert_no_error (error); + + /* device2 and conn differ in subchannels */ + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_x, NULL); + nm_device_connection_compatible (device2, conn, &error); + g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error (&error); + + /* device1 and conn differ in subchannels - 2 in connection, 3 in device */ + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_2, NULL); + nm_device_connection_compatible (device1, conn, &error); + g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error (&error); + + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, NULL, NULL); + + /* device2 and conn differ in MAC address */ + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "aa:bb:cc:dd:ee:ee", NULL); + nm_device_connection_compatible (device2, conn, &error); + g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error (&error); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, NULL, NULL); + + /* device1 is blacklisted in conn */ + nm_setting_wired_add_mac_blacklist_item (s_wired, hw_addr1); + nm_device_connection_compatible (device1, conn, &error); + g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error (&error); + + g_object_unref (conn); + g_object_unref (client); + + g_clear_pointer (&sinfo, nmtstc_service_cleanup); +} + +/*******************************************************************/ + +static gboolean +_test_connection_invalid_find_connections (gpointer element, gpointer needle, gpointer user_data) +{ + NMRemoteConnection *con = NM_REMOTE_CONNECTION (element); + const char *path = needle; + + g_assert (NM_IS_REMOTE_CONNECTION (con)); + g_assert (path && *path); + + return strcmp (path, nm_connection_get_path ((NMConnection *) con)) == 0; +} + +#define ASSERT_IDX(i) \ + g_assert_cmpint (idx[i], >=, 0); \ + g_assert (path##i && *path##i); \ + g_assert (NM_IS_REMOTE_CONNECTION (connections->pdata[idx[i]])); \ + g_assert_cmpstr (nm_connection_get_path (connections->pdata[idx[i]]), ==, path##i); + +static void +test_connection_invalid (void) +{ + NMTSTC_SERVICE_INFO_SETUP (my_sinfo) + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection *s_con; + gs_unref_object NMClient *client = NULL; + const GPtrArray *connections; + gs_free_error GError *error = NULL; + gs_free char *path0 = NULL; + gs_free char *path1 = NULL; + gs_free char *path2 = NULL; + gs_free char *uuid2 = NULL; + gsize n_found; + gssize idx[3]; + + /************************************************************************** + * Add two connection before starting libnm. One valid, one invalid. + *************************************************************************/ + + connection = nmtst_create_minimal_connection ("test-connection-invalid-0", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + nmtst_connection_normalize (connection); + g_object_set (s_con, + NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate (), + NULL); + nmtstc_service_add_connection (my_sinfo, + connection, + TRUE, + &path0); + + nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRED); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-1", + NM_SETTING_CONNECTION_TYPE, "invalid-type-1", + NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate (), + NULL); + nmtstc_service_add_connection (my_sinfo, + connection, + FALSE, + &path1); + + + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 2); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1 }), + 2, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 2); + ASSERT_IDX (0); + ASSERT_IDX (1); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + + /************************************************************************** + * After having the client up and running, add another invalid connection + *************************************************************************/ + + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-2", + NM_SETTING_CONNECTION_TYPE, "invalid-type-2", + NM_SETTING_CONNECTION_UUID, (uuid2 = g_strdup (nmtst_uuid_generate ())), + NULL); + nmtstc_service_add_connection (my_sinfo, + connection, + FALSE, + &path2); + + + nmtst_main_loop_run (loop, 100); + + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 3); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2 }), + 3, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 3); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (still invalid) + *************************************************************************/ + + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-2x", + NULL); + nmtstc_service_update_connection (my_sinfo, + path2, + connection, + FALSE); + + nmtst_main_loop_run (loop, 100); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 3); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2 }), + 3, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 3); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); + g_assert_cmpstr ("test-connection-invalid-2x", ==, nm_connection_get_id (connections->pdata[idx[2]])); + + /************************************************************************** + * Modify the invalid connection (now becomes valid) + *************************************************************************/ + + g_clear_object (&connection); + connection = nmtst_create_minimal_connection ("test-connection-invalid-2", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + nmtst_connection_normalize (connection); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-2z", + NM_SETTING_CONNECTION_TYPE, "802-3-ethernet", + NM_SETTING_CONNECTION_UUID, uuid2, + NULL); + + nmtstc_service_update_connection (my_sinfo, + path2, + connection, + FALSE); + + nmtst_main_loop_run (loop, 100); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 3); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2 }), + 3, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 3); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[2]]); + g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[2]])); + + /************************************************************************** + * Modify the invalid connection and make it valid + *************************************************************************/ + + g_clear_object (&connection); + connection = nmtst_create_minimal_connection ("test-connection-invalid-1", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + nmtst_connection_normalize (connection); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-1x", + NM_SETTING_CONNECTION_TYPE, "802-3-ethernet", + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connections->pdata[idx[1]]), + NULL); + + nmtstc_service_update_connection (my_sinfo, + path1, + connection, + FALSE); + + nmtst_main_loop_run (loop, 100); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 3); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2 }), + 3, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 3); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[1]]); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[2]]); + g_assert_cmpstr ("test-connection-invalid-1x", ==, nm_connection_get_id (connections->pdata[idx[1]])); + g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[2]])); + +#undef ASSERT_IDX } /*******************************************************************/ @@ -1170,10 +1472,6 @@ main (int argc, char **argv) { g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - nmtst_init (&argc, &argv, TRUE); loop = g_main_loop_new (NULL, FALSE); @@ -1187,6 +1485,8 @@ main (int argc, char **argv) g_test_add_func ("/libnm/active-connections", test_active_connections); g_test_add_func ("/libnm/activate-virtual", test_activate_virtual); g_test_add_func ("/libnm/activate-failed", test_activate_failed); + g_test_add_func ("/libnm/device-connection-compatibility", test_device_connection_compatibility); + g_test_add_func ("/libnm/connection/invalid", test_connection_invalid); return g_test_run (); } diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c index 15590fac..1a3c7988 100644 --- a/libnm/tests/test-remote-settings-client.c +++ b/libnm/tests/test-remote-settings-client.c @@ -20,18 +20,13 @@ #include "config.h" -#include #include #include #include -#include +#include "nm-test-libnm-utils.h" -#include "common.h" - -#include "nm-test-utils.h" - -static NMTestServiceInfo *sinfo; +static NMTstcServiceInfo *sinfo; static NMClient *client = NULL; GDBusConnection *bus = NULL; NMRemoteConnection *remote = NULL; @@ -502,6 +497,8 @@ test_save_hostname (void) /*******************************************************************/ +NMTST_DEFINE (); + int main (int argc, char **argv) { @@ -510,16 +507,12 @@ main (int argc, char **argv) g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_test_init (&argc, &argv, NULL); + nmtst_init (&argc, &argv, TRUE); bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); g_assert_no_error (error); - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); client = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -538,7 +531,7 @@ main (int argc, char **argv) ret = g_test_run (); - nm_test_service_cleanup (sinfo); + nmtstc_service_cleanup (sinfo); g_object_unref (client); g_object_unref (bus); diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c index 037b5a81..f8aedd23 100644 --- a/libnm/tests/test-secret-agent.c +++ b/libnm/tests/test-secret-agent.c @@ -20,17 +20,13 @@ #include "config.h" -#include #include #include #include -#include #include -#include "nm-glib-compat.h" -#include "nm-test-utils.h" -#include "common.h" +#include "nm-test-libnm-utils.h" /*******************************************************************/ @@ -183,7 +179,7 @@ test_secret_agent_new (void) /*******************************************************************/ typedef struct { - NMTestServiceInfo *sinfo; + NMTstcServiceInfo *sinfo; NMClient *client; NMSecretAgentOld *agent; @@ -250,7 +246,7 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data) NMSetting *s_wsec; GError *error = NULL; - sadata->sinfo = nm_test_service_init (); + sadata->sinfo = nmtstc_service_init (); sadata->client = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -262,8 +258,8 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data) counter++; /* Create the device */ - sadata->device = nm_test_service_add_device (sadata->sinfo, sadata->client, - "AddWifiDevice", sadata->ifname); + sadata->device = nmtstc_service_add_device (sadata->sinfo, sadata->client, + "AddWifiDevice", sadata->ifname); /* Create the connection */ connection = nmtst_create_minimal_connection (sadata->con_id, NULL, NM_SETTING_WIRELESS_SETTING_NAME, &s_con); @@ -336,7 +332,7 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) g_object_unref (sadata->connection); g_object_unref (sadata->client); - nm_test_service_cleanup (sadata->sinfo); + nmtstc_service_cleanup (sadata->sinfo); g_source_remove (sadata->timeout_id); g_main_loop_unref (sadata->loop); @@ -583,12 +579,12 @@ registered_changed (GObject *object, GParamSpec *pspec, gpointer user_data) static void test_secret_agent_auto_register (void) { - NMTestServiceInfo *sinfo; + NMTstcServiceInfo *sinfo; NMSecretAgentOld *agent; GMainLoop *loop; GError *error = NULL; - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); loop = g_main_loop_new (NULL, FALSE); agent = test_secret_agent_new (); @@ -604,17 +600,17 @@ test_secret_agent_auto_register (void) g_assert (nm_secret_agent_old_get_registered (agent)); /* Shut down test service */ - nm_test_service_cleanup (sinfo); + nmtstc_service_cleanup (sinfo); g_main_loop_run (loop); g_assert (!nm_secret_agent_old_get_registered (agent)); /* Restart test service */ - sinfo = nm_test_service_init (); + sinfo = nmtstc_service_init (); g_main_loop_run (loop); g_assert (nm_secret_agent_old_get_registered (agent)); /* Shut down test service again */ - nm_test_service_cleanup (sinfo); + nmtstc_service_cleanup (sinfo); g_main_loop_run (loop); g_assert (!nm_secret_agent_old_get_registered (agent)); @@ -624,6 +620,8 @@ test_secret_agent_auto_register (void) /*******************************************************************/ +NMTST_DEFINE (); + int main (int argc, char **argv) { @@ -631,11 +629,7 @@ main (int argc, char **argv) g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_test_init (&argc, &argv, NULL); + nmtst_init (&argc, &argv, TRUE); g_test_add ("/libnm/secret-agent/none", TestSecretAgentData, NULL, test_setup, test_secret_agent_none, test_cleanup); -- cgit 1.3.0-6-gf8a5