diff options
| author | Michael Biebl <biebl@debian.org> | 2016-01-20 16:26:51 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-01-20 16:26:51 +0100 |
| commit | 494f296a3baab08522617b24b1f126d8f9a17502 (patch) | |
| tree | c8ef32fb0dd1c4ff35a0b38e787abb58692de0cd /libnm | |
| parent | 54f6333410ffd570e62717d9e77c5c987175e397 (diff) | |
Imported Upstream version 1.1.90 upstream/1.1.90
Diffstat (limited to 'libnm')
72 files changed, 6334 insertions, 1189 deletions
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 <nm-setting-gsm.h> #include <nm-setting-infiniband.h> #include <nm-setting-ip-config.h> +#include <nm-setting-ip-tunnel.h> #include <nm-setting-ip4-config.h> #include <nm-setting-ip6-config.h> +#include <nm-setting-macvlan.h> #include <nm-setting-olpc-mesh.h> #include <nm-setting-ppp.h> #include <nm-setting-pppoe.h> #include <nm-setting-serial.h> #include <nm-setting-team-port.h> #include <nm-setting-team.h> +#include <nm-setting-tun.h> #include <nm-setting-vlan.h> #include <nm-setting-vpn.h> +#include <nm-setting-vxlan.h> #include <nm-setting-wimax.h> #include <nm-setting-wired.h> #include <nm-setting-wireless-security.h> @@ -81,7 +85,9 @@ #include <nm-version.h> #include <nm-vpn-connection.h> #include <nm-vpn-dbus-interface.h> +#include <nm-vpn-editor.h> #include <nm-vpn-editor-plugin.h> +#include <nm-vpn-plugin-info.h> #include <nm-wimax-nsp.h> #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 <string.h> -#include "nm-glib-compat.h" - #include <nm-connection.h> #include <nm-setting-connection.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> #include <nm-utils.h> +#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 <string.h> +#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 <string.h> #include <nm-utils.h> +#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, @@ -720,6 +723,34 @@ nm_client_get_devices (NMClient *client) } /** + * 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 * @object_path: the object path to search for @@ -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, @@ -1669,6 +1701,22 @@ manager_device_removed (NMManager *manager, } 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, NMClientPermissionResult result, @@ -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 **/ @@ -2104,6 +2157,21 @@ nm_client_class_init (NMClientClass *client_class) 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: * * The list of configured connections that are available to the user. (Note @@ -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, @@ -2194,6 +2264,40 @@ nm_client_class_init (NMClientClass *client_class) 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 * @permission: a permission from #NMClientPermission 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 <string.h> -#include <gio/gio.h> -#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 <gio/gio.h> - -/* 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 <string.h> -#include <glib/gi18n-lib.h> 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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-bond.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-bridge.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-bluetooth.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-wired.h> #include <nm-setting-pppoe.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> #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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-infiniband.h> #include <nm-utils.h> +#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 <string.h> + +#include <nm-setting-connection.h> +#include <nm-setting-ip-tunnel.h> +#include <nm-utils.h> + +#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 <NetworkManager.h> can be included directly." +#endif + +#include <nm-device.h> + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type ()) +#define NM_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) +#define NM_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) +#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 <string.h> + +#include <nm-setting-connection.h> +#include <nm-setting-macvlan.h> +#include <nm-setting-wired.h> +#include <nm-utils.h> + +#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 <NetworkManager.h> can be included directly." +#endif + +#include <nm-device.h> + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type ()) +#define NM_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) +#define NM_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-gsm.h> #include <nm-setting-cdma.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-olpc-mesh.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-team.h> #include <nm-utils.h> +#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 <string.h> +#include <arpa/inet.h> + +#include <nm-setting-connection.h> +#include <nm-setting-tun.h> +#include <nm-utils.h> + +#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 <NetworkManager.h> can be included directly." +#endif + +#include <nm-device.h> + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type ()) +#define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) +#define NM_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-vlan.h> #include <nm-setting-wired.h> #include <nm-utils.h> +#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 <string.h> + +#include <nm-setting-connection.h> +#include <nm-setting-vxlan.h> +#include <nm-utils.h> + +#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 <NetworkManager.h> can be included directly." +#endif + +#include <nm-device.h> + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type ()) +#define NM_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) +#define NM_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> - -#include "nm-glib-compat.h" #include <nm-setting-connection.h> #include <nm-setting-wimax.h> #include <nm-utils.h> +#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 <string.h> -#include <glib/gi18n-lib.h> #include <gudev/gudev.h> +#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) @@ -615,6 +692,22 @@ nm_device_class_init (NMDeviceClass *device_class) 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: * * Whether the device is managed by NetworkManager. @@ -652,6 +745,21 @@ nm_device_class_init (NMDeviceClass *device_class) 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: * * The #NMIP4Config of the device. @@ -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 */ /** @@ -1074,6 +1194,30 @@ nm_device_get_managed (NMDevice *device) } /** + * 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 * @@ -1128,6 +1272,24 @@ nm_device_get_firmware_missing (NMDevice *device) } /** + * 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 #NMLldpNeighbor<!-- -->s. 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 @@ -1938,6 +2165,134 @@ nm_device_is_software (NMDevice *device) } /** + * 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 * @cancellable: a #GCancellable, or %NULL @@ -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."/> <property name="hello-time" variable="BRIDGING_OPTS: hello_time=" format="" values="1 - 10" default="2" example="" description="STP hello time."/> <property name="max-age" variable="BRIDGING_OPTS: max_age=" format="" values="6 - 40" default="20" example="" description="STP maximum message age."/> <property name="ageing-time" variable="BRIDGING_OPTS: ageing_time=" format="" values="0 - 1000000" default="300" example="" description="Ethernet MAC ageing time."/> +<property name="multicast-snooping" variable="BRIDGING_OPTS: multicast_snooping=" format="" values="0 or 1" default="1" example="" description="IGMP snooping support."/> </setting> <setting name="cdma"> </setting> @@ -93,6 +94,7 @@ together with this connection."/> <property name="gateway-ping-timeout" variable="GATEWAY_PING_TIMEOUT(+)" format="" values="" default="0" example="GATEWAY_PING_TIMEOUT=5" description="If greater than zero, the IP connectivity will be checked by pinging the gateway and waiting for the specified timeout (in seconds)."/> <property name="metered" variable="CONNECTION_METERED" format="" values="yes,no,unknown" default="" example="CONNECTION_METERED=yes" description="Whether the device is metered"/> +<property name="lldp" variable="LLDP" format="" values="boolean value or 'rx'" default="missing variable means global default" example="LLDP=no" description="whether LLDP is enabled for the connection"/> </setting> <setting name="dcb"> <property name="app-fcoe-flags" variable="DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING" format="" values="" default="no" example="DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes" description="FCOE flags."/> @@ -132,6 +134,8 @@ When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified."/> </setting> <setting name=""> </setting> +<setting name="ip-tunnel"> +</setting> <setting name="ipv4"> <property name="method" variable="BOOTPROTO" format="string" values="none, dhcp (bootp), static, ibft, autoip, shared" default="none" example="" description="Method used for IPv4 protocol configuration."/> <property name="dns" variable="DNS1, DNS2, ..." format="string" values="" default="" example="DNS1=1.2.3.4 DNS2=10.0.0.254 DNS3=8.8.8.8" description="List of DNS servers. Even if NetworkManager supports many DNS @@ -144,7 +148,8 @@ but in route-* file instead."/> <property name="ignore-auto-routes" variable="PEERROUTES(+)" format="" values="" default="yes" example="" description="PEERROUTES has the opposite meaning as 'ignore-auto-routes' property."/> <property name="ignore-auto-dns" variable="PEERDNS" format="" values="" default="yes" example="" description="PEERDNS has the opposite meaning as 'ignore-auto-dns' property."/> <property name="dhcp-send-hostname" variable="DHCP_SEND_HOSTNAME(+)" format="" values="" default="yes" example="" description="Whether DHCP_HOSTNAME should be sent to the DHCP server."/> -<property name="dhcp-hostname" variable="DHCP_HOSTNAME" format="" values="" default="" example="" description="Hostname to send to the DHCP server."/> +<property name="dhcp-hostname" variable="DHCP_HOSTNAME" format="" values="" default="" example="" description="Hostname to send to the DHCP server. When both DHCP_HOSTNAME and +DHCP_FQDN are specified only the latter is used."/> <property name="never-default" variable="DEFROUTE (GATEWAYDEV in /etc/sysconfig/network)" format="" values="" default="yes" example="" description="DEFROUTE=no tells NetworkManager that this connection should not be assigned the default route. DEFROUTE has the opposite meaning as 'never-default' property."/> @@ -152,6 +157,9 @@ meaning as 'never-default' property."/> <property name="route-metric" variable="IPV4_ROUTE_METRIC(+)" format="" values="" default="-1" example="" description="IPV4_ROUTE_METRIC is the default IPv4 metric for routes on this connection. If set to -1, a default metric based on the device type is used."/> <property name="dhcp-client-id" variable="DHCP_CLIENT_ID(+)" format="" values="" default="" example="DHCP_CLIENT_ID=ax-srv-1" description="A string sent to the DHCP server to identify the local machine."/> +<property name="dhcp-timeout" variable="DHCP_TIMEOUT(+)" format="" values="" default="" example="DHCP_TIMEOUT=10" description="A timeout after which the DHCP transaction fails in case of no response."/> +<property name="dhcp-fqdn" variable="DHCP_FQDN" format="" values="" default="" example="DHCP_FQDN=foo.bar.com" description="FQDN to send to the DHCP server. When both DHCP_HOSTNAME and +DHCP_FQDN are specified only the latter is used."/> </setting> <setting name="ipv6"> <property name="method" variable="IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C" format="" values="" default="IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no" example="" description="Method used for IPv6 protocol configuration. @@ -175,6 +183,9 @@ meaning as 'never-default' property."/> If set to -1, a default metric based on the device type is used."/> <property name="ip6-privacy" variable="IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+)" format="" values="IPV6_PRIVACY: no, yes (rfc3041 or rfc4941); IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no" default="no" example="IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes" description="Configure IPv6 Privacy Extensions for SLAAC (RFC4941)."/> +<property name="addr-gen-mode" variable="IPV6_ADDR_GEN_MODE" format="" values="IPV6_ADDR_GEN_MODE: eui64, stable-privacy" default="eui64" example="IPV6_ADDR_GEN_MODE=stable-privacy" description="Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217)."/> +</setting> +<setting name="macvlan"> </setting> <setting name="802-11-olpc-mesh"> </setting> @@ -190,10 +201,12 @@ IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no" default="no" example="IPV6_PRIVACY=rfc30 <setting name="team"> <property name="config" variable="TEAM_CONFIG" format="" values="" default="" example="" description="Team configuration in JSON. See man teamd.conf for details."/> </setting> +<setting name="tun"> +</setting> <setting name="vlan"> <property name="parent" variable="DEVICE or PHYSDEV" format="" values="" default="" example="" description="Parent interface of the VLAN."/> <property name="id" variable="VLAN_ID or DEVICE" format="" values="" default="" example="" description="VLAN identifier."/> -<property name="flags" variable="VLAN_FLAGS, REORDER_HDR" format="" values=""GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDR" default="" example="" description="VLAN flags."/> +<property name="flags" variable="REORDER_HDR, GVRP, MVRP, VLAN_FLAGS" format="" values=""yes or "no" for REORDER_HDR, GVRP and MVRP; "LOOSE_BINDING" for VLAN_FLAGS" default="" example="" description="VLAN flags."/> <property name="ingress-priority-map" variable="VLAN_INGRESS_PRIORITY_MAP" format="" values="" default="" example="VLAN_INGRESS_PRIORITY_MAP=4:2,3:5" description="Ingress priority mapping."/> <property name="egress-priority-map" variable="VLAN_EGRESS_PRIORITY_MAP" format="" values="" default="" example="VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7" description="Egress priority mapping."/> <property name="interface-name" variable="PHYSDEV and VLAN_ID, or DEVICE" format="" values="" default="" example="PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12" description="VLAN interface name. @@ -202,6 +215,8 @@ but VLAN id from DEVICE takes precedence over VLAN_ID."/> </setting> <setting name="vpn"> </setting> +<setting name="vxlan"> +</setting> <setting name="wimax"> </setting> <setting name="802-3-ethernet"> @@ -265,6 +280,8 @@ is listed."/> <property name="seen-bssids" variable="(none)" format="" values="" default="" example="" description="This property is not handled by ifcfg-rh plugin."/> <property name="mtu" variable="MTU" format="" values="" default="" example="" description="MTU of the wireless interface."/> <property name="hidden" variable="SSID_HIDDEN(+)" format="" values="" default="" example="" description="Whether the network hides the SSID."/> +<property name="powersave" variable="POWERSAVE(+)" format="" values="" default="no" example="POWERSAVE=yes" description="Enables or disables Wi-Fi power saving."/> +<property name="mac-address-randomization" variable="MAC_ADDRESS_RANDOMIZATION(+)" format="" values="0 (default), (1) never, (2) always" default="1" example="MAC_ADDRESS_RANDOMIZATION=2" description="Enables or disables Wi-Fi MAC address randomization."/> <property name="security" variable="(none)" format="" values="" default="" example="" description="This property is deprecated and not handled by ifcfg-rh-plugin."/> </setting> </nm-ifcfg-rh-docs> \ 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 #NMIPAddress<!-- -->es. 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)"/> </setting> <setting name=""> </setting> +<setting name="ip-tunnel"> +</setting> <setting name="ipv4"> <property name="dns" variable="dns" format="list of DNS IP addresses" values="" default="" example="dns=1.2.3.4;8.8.8.8;8.8.4.4;" description="List of DNS servers."/> <property name="addresses" variable="address1, address2, ..." format="address/plen" values="" default="" example="address1=192.168.100.100/24 address2=10.1.1.5/24" description="List of static IP addresses."/> @@ -47,6 +49,8 @@ route2=7.7.0.0/16" description="List of IP routes."/> <property name="gateway" variable="gateway" format="string" values="" default="" example="gateway=abbe::1" description="Gateway IP addresses as a string."/> <property name="routes" variable="route1, route2, ..." format="route/plen[,gateway,metric]" values="" default="" example="route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403" description="List of IP routes."/> </setting> +<setting name="macvlan"> +</setting> <setting name="802-11-olpc-mesh"> </setting> <setting name="ppp"> @@ -62,6 +66,8 @@ versions of NetworkManager stored this as an integer: 69 ('E') for eve </setting> <setting name="team"> </setting> +<setting name="tun"> +</setting> <setting name="vlan"> </setting> <setting name="vpn"> @@ -70,6 +76,8 @@ under [vpn] section."/> <property name="secrets" variable="separate variables named after keys of the dictionary" format="" values="" default="" example="password=Popocatepetl" description="The keys of the secrets dictionary are used as variable names directly under [vpn-secrets] section."/> </setting> +<setting name="vxlan"> +</setting> <setting name="wimax"> </setting> <setting name="802-3-ethernet"> 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 <string.h> -#include <glib/gi18n-lib.h> #include <nm-utils.h> +#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 <string.h> -#include <glib.h> +#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 <glib.h> -#include <glib-object.h> +#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 <gio/gio.h> +#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 <string.h> -#include <gio/gio.h> -#include <glib/gi18n-lib.h> #include <stdlib.h> #include <stdio.h> #include <nm-utils.h> +#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 @@ <property name="hello-time" type="uint32" default="2" description="The Spanning Tree Protocol (STP) hello time, in seconds." /> <property name="mac-address" type="byte array" description="If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. When matching an existing (outside NetworkManager created) bridge, this MAC address must match." /> <property name="max-age" type="uint32" default="20" description="The Spanning Tree Protocol (STP) maximum message age, in seconds." /> + <property name="multicast-snooping" type="boolean" default="TRUE" description="Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved." /> <property name="name" type="string" default="bridge" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="priority" type="uint32" default="32768" description="Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are "better"; the lowest priority bridge will be elected the root bridge." /> <property name="stp" type="boolean" default="TRUE" description="Controls whether Spanning Tree Protocol (STP) is enabled for this bridge." /> @@ -87,8 +88,9 @@ <property name="gateway-ping-timeout" type="uint32" default="0" description="If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping." /> <property name="id" type="string" description="A human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G"." /> <property name="interface-name" type="string" description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface." /> + <property name="lldp" type="int32" default="-1" description="Whether LLDP is enabled for the connection." /> <property name="master" type="string" description="Interface name of the master device or UUID of the master connection." /> - <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered." /> + <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately." /> <property name="name" type="string" default="connection" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="permissions" type="array of string" default="[]" description="An array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection. Otherwise a user is allowed to access this connection if and only if they are in this list. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". At this time only the "user" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the ":" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8." /> <property name="read-only" type="boolean" default="FALSE" description="FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified." /> @@ -97,7 +99,7 @@ <property name="timestamp" type="uint64" default="0" description="The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved)." /> <property name="type" type="string" description="Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc)." /> <property name="uuid" type="string" description="A universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or "type" property changes. The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-")." /> - <property name="zone" type="string" description="The trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall." /> + <property name="zone" type="string" description="The trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. When updating this property on a currently activated connection, the change takes effect immediately." /> </setting> <setting name="dcb"> <property name="app-fcoe-flags" type="NMSettingDcbFlags (uint32)" description="Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)." /> @@ -122,6 +124,7 @@ </setting> <setting name="gsm"> <property name="apn" type="string" description="The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9." /> + <property name="device-id" type="string" description="The device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device." /> <property name="home-only" type="boolean" default="FALSE" description="When TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made." /> <property name="name" type="string" default="gsm" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="network-id" type="string" description="The Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible." /> @@ -130,6 +133,8 @@ <property name="password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "password" property." /> <property name="pin" type="string" description="If the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device." /> <property name="pin-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "pin" property." /> + <property name="sim-id" type="string" description="The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" which contains a SIM card matching the given identifier." /> + <property name="sim-operator-id" type="string" description="A MCC/MNC string like "310260" or "21601" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" and "sim-id" which contains a SIM card provisioined by the given operator." /> <property name="username" type="string" description="The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here." /> </setting> <setting name="infiniband"> @@ -143,9 +148,12 @@ <setting name="ipv4"> <property name="addresses" type="array of array of uint32" default="[]" description="Array of IP addresses." /> <property name="dhcp-client-id" type="string" description="A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options." /> - <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease." /> + <property name="dhcp-fqdn" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time." /> + <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." /> <property name="dhcp-send-hostname" type="boolean" default="TRUE" description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." /> + <property name="dhcp-timeout" type="uint32" default="0" description="A timeout for a DHCP transaction in seconds." /> <property name="dns" type="array of uint32" default="[]" description="Array of IP addresses of DNS servers." /> + <property name="dns-options" type="array of string" default="[]" description="Array of DNS options. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties." /> <property name="dns-search" type="array of string" default="[]" description="Array of DNS search domains." /> <property name="gateway" type="string" description="The gateway associated with this configuration. This is only meaningful if "addresses" is also set." /> <property name="ignore-auto-dns" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used." /> @@ -158,15 +166,17 @@ <property name="routes" type="array of array of uint32" default="[]" description="Array of IP routes." /> </setting> <setting name="ipv6"> + <property name="addr-gen-mode" type="int32" default="1" description="Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: "eui64", "stable-privacy" or unset. If the property is set to "eui64", the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of "stable-privacy" enables use of cryptographically secure hash of a secret host-specific key along with the connection identification and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. Leaving this unset causes a default that could be subject to change in future versions to be used. Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses configured with this option." /> <property name="addresses" type="array of legacy IPv6 address struct" default="[]" description="Array of IP addresses." /> - <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease." /> + <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." /> <property name="dhcp-send-hostname" type="boolean" default="TRUE" description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." /> <property name="dns" type="array of byte array" default="[]" description="Array of IP addresses of DNS servers." /> + <property name="dns-options" type="array of string" default="[]" description="Array of DNS options. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties." /> <property name="dns-search" type="array of string" default="[]" description="Array of DNS search domains." /> <property name="gateway" type="string" description="The gateway associated with this configuration. This is only meaningful if "addresses" is also set." /> <property name="ignore-auto-dns" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used." /> <property name="ignore-auto-routes" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used." /> - <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr"." /> + <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the "addr-gen-mode" property's "stable-privacy" setting as another way of avoiding host tracking with IPv6 addresses." /> <property name="may-fail" type="boolean" default="TRUE" description="If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully." /> <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> <property name="name" type="string" default="ipv6" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> @@ -174,6 +184,28 @@ <property name="route-metric" type="int64" default="-1" description="The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric." /> <property name="routes" type="array of legacy IPv6 route struct" default="[]" description="Array of IP routes." /> </setting> + <setting name="ip-tunnel"> + <property name="encapsulation-limit" type="uint32" default="0" description="How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels." /> + <property name="flow-label" type="uint32" default="0" description="The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels." /> + <property name="input-key" type="string" description="The key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used." /> + <property name="local" type="string" description="The local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address." /> + <property name="mode" type="uint32" default="0" description="The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2)." /> + <property name="mtu" type="uint32" default="0" description="None" /> + <property name="name" type="string" default="ip-tunnel" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="output-key" type="string" description="The key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface." /> + <property name="path-mtu-discovery" type="boolean" default="TRUE" description="Whether to enable Path MTU Discovery on this tunnel." /> + <property name="remote" type="string" description="The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address." /> + <property name="tos" type="uint32" default="0" description="The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets." /> + <property name="ttl" type="uint32" default="0" description="The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value." /> + </setting> + <setting name="macvlan"> + <property name="mode" type="uint32" default="0" description="The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device." /> + <property name="name" type="string" default="macvlan" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property." /> + <property name="promiscuous" type="boolean" default="TRUE" description="Whether the interface should be put in promiscuous mode." /> + <property name="tap" type="boolean" default="FALSE" description="Whether the interface should be a MACVTAP." /> + </setting> <setting name="802-11-olpc-mesh"> <property name="channel" type="uint32" default="0" description="Channel on which the mesh network to join is located." /> <property name="dhcp-anycast-address" type="byte array" description="Anycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request." /> @@ -224,9 +256,18 @@ <property name="config" type="string" description="The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details." /> <property name="name" type="string" default="team-port" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> </setting> + <setting name="tun"> + <property name="group" type="string" description="The group ID which will own the device. If set to NULL everyone will be able to use the device." /> + <property name="mode" type="uint32" default="1" description="The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one." /> + <property name="multi-queue" type="boolean" default="FALSE" description="If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue." /> + <property name="name" type="string" default="tun" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="owner" type="string" description="The user ID which will own the device. If set to NULL everyone will be able to use the device." /> + <property name="pi" type="boolean" default="FALSE" description="If TRUE the interface will prepend a 4 byte header describing the physical interface to the packets." /> + <property name="vnet-hdr" type="boolean" default="FALSE" description="If TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header." /> + </setting> <setting name="vlan"> <property name="egress-priority-map" type="array of string" default="[]" description="For outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"." /> - <property name="flags" type="NMVlanFlags (uint32)" description="One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state)." /> + <property name="flags" type="NMVlanFlags (uint32)" description="One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0." /> <property name="id" type="uint32" default="0" description="The VLAN identifier that the interface created by this connection should be assigned." /> <property name="ingress-priority-map" type="array of string" default="[]" description="For incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"." /> <property name="name" type="string" default="vlan" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> @@ -238,12 +279,32 @@ <property name="persistent" type="boolean" default="FALSE" description="If the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected." /> <property name="secrets" type="dict of string to string" default="{}" description="Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings." /> <property name="service-type" type="string" description="D-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin." /> + <property name="timeout" type="uint32" default="0" description="Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overriden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds." /> <property name="user-name" type="string" description="If the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection." /> </setting> + <setting name="vxlan"> + <property name="ageing" type="uint32" default="0" description="Specifies the lifetime in seconds of FDB entries learnt by the kernel." /> + <property name="destination-port" type="uint32" default="8472" description="Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="id" type="uint32" default="0" description="Specifies the VXLAN Network Identifer (or VXLAN Segment Identifier) to use." /> + <property name="l2-miss" type="boolean" default="FALSE" description="Specifies whether netlink LL ADDR miss notifications are generated." /> + <property name="l3-miss" type="boolean" default="FALSE" description="Specifies whether netlink IP ADDR miss notifications are generated." /> + <property name="learning" type="boolean" default="TRUE" description="Specifies whether unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database." /> + <property name="limit" type="uint32" default="0" description="Specifies the maximum number of FDB entries. A value of zero means that the kernel will store unlimited entries." /> + <property name="local" type="string" description="If given, specifies the source IP address to use in outgoing packets." /> + <property name="name" type="string" default="vxlan" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID." /> + <property name="proxy" type="boolean" default="FALSE" description="Specifies whether ARP proxy is turned on." /> + <property name="remote" type="string" description="Specifies the unicast destination IP address to use in outgoing packets when the destination link layer address is not known in the VXLAN device forwarding database, or the multicast IP address to join." /> + <property name="rsc" type="boolean" default="FALSE" description="Specifies whether route short circuit is turned on." /> + <property name="source-port-max" type="uint32" default="0" description="Specifies the maximum UDP source port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="source-port-min" type="uint32" default="0" description="Specifies the minimum UDP source port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="tos" type="uint32" default="0" description="Specifies the TOS value to use in outgoing packets." /> + <property name="ttl" type="uint32" default="0" description="Specifies the time-to-live value to use in outgoing packets." /> + </setting> <setting name="wimax"> - <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing)." /> + <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1" /> <property name="name" type="string" default="wimax" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> - <property name="network-name" type="string" description="Network Service Provider (NSP) name of the WiMAX network this connection should use." /> + <property name="network-name" type="string" description="Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1" /> </setting> <setting name="802-3-ethernet"> <property name="auto-negotiate" type="boolean" default="TRUE" description="If TRUE, allow auto-negotiation of port speed and duplex mode. If FALSE, do not allow auto-negotiation, in which case the "speed" and "duplex" properties should be set." /> @@ -269,9 +330,11 @@ <property name="hidden" type="boolean" default="FALSE" description="If TRUE, indicates this network is a non-broadcasting network that hides its SSID. In this case various workarounds may take place, such as probe-scanning the SSID for more reliable network discovery. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution." /> <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing)." /> <property name="mac-address-blacklist" type="array of string" default="[]" description="A list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg "00:11:22:33:44:55")." /> + <property name="mac-address-randomization" type="uint32" default="0" description="One of NM_SETTING_MAC_RANDOMIZATION_DEFAULT (0) (never randomize unless the user has set a global default to randomize and the supplicant supports randomization), NM_SETTING_MAC_RANDOMIZATION_NEVER (1) (never randomize the MAC address), or NM_SETTING_MAC_RANDOMIZATION_ALWAYS (2) (always randomize the MAC address)." /> <property name="mode" type="string" description="Wi-Fi network mode; one of "infrastructure", "adhoc" or "ap". If blank, infrastructure is assumed." /> <property name="mtu" type="uint32" default="0" description="If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames." /> <property name="name" type="string" default="802-11-wireless" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="powersave" type="uint32" default="0" description="If set to FALSE, Wi-Fi power saving behavior is disabled. If set to TRUE, Wi-Fi power saving behavior is enabled. All other values are reserved. Note that even though only boolean values are allowed, the property type is an unsigned integer to allow for future expansion." /> <property name="rate" type="uint32" default="0" description="If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate." /> <property name="seen-bssids" type="array of string" default="[]" description="A list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved." /> <property name="ssid" type="byte array" description="SSID of the Wi-Fi network. Must be specified." /> 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 <string.h> -#include <gio/gio.h> -#include <glib/gi18n-lib.h> #include <nm-dbus-interface.h> #include <nm-utils.h> #include <nm-setting-connection.h> +#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 <string.h> -#include <glib/gi18n-lib.h> #include <nm-dbus-interface.h> #include <nm-connection.h> +#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 <string.h> -#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."/> </setting> <setting name=""> </setting> +<setting name="ip-tunnel"> +</setting> <setting name="ipv4"> <property name="dns" variable="dns" format="array of uint32" values="" default="" example="" description="Array of IP addresses of DNS servers (as network-byte-order integers)"/> @@ -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."/> </setting> +<setting name="macvlan"> +</setting> <setting name="802-11-olpc-mesh"> </setting> <setting name="ppp"> @@ -119,6 +123,8 @@ also exist on some routes."/> be used for backward-compatibility with older daemons, to set the team's interface name."/> </setting> +<setting name="tun"> +</setting> <setting name="vlan"> <property name="interface-name" variable="interface-name" format="string" values="" default="" example="" description="Deprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the @@ -126,6 +132,8 @@ vlan's interface name."/> </setting> <setting name="vpn"> </setting> +<setting name="vxlan"> +</setting> <setting name="wimax"> </setting> <setting name="802-3-ethernet"> 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 @@ <property name="interface-name" type="string" description="Deprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bridge's interface name." /> <property name="mac-address" type="byte array" description="If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. When matching an existing (outside NetworkManager created) bridge, this MAC address must match." /> <property name="max-age" type="uint32" default="20" description="The Spanning Tree Protocol (STP) maximum message age, in seconds." /> + <property name="multicast-snooping" type="boolean" default="TRUE" description="Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved." /> <property name="name" type="string" default="bridge" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="priority" type="uint32" default="32768" description="Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are "better"; the lowest priority bridge will be elected the root bridge." /> <property name="stp" type="boolean" default="TRUE" description="Controls whether Spanning Tree Protocol (STP) is enabled for this bridge." /> @@ -89,8 +90,9 @@ <property name="gateway-ping-timeout" type="uint32" default="0" description="If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping." /> <property name="id" type="string" description="A human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G"." /> <property name="interface-name" type="string" description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface." /> + <property name="lldp" type="int32" default="-1" description="Whether LLDP is enabled for the connection." /> <property name="master" type="string" description="Interface name of the master device or UUID of the master connection." /> - <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered." /> + <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately." /> <property name="name" type="string" default="connection" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="permissions" type="array of string" default="[]" description="An array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection. Otherwise a user is allowed to access this connection if and only if they are in this list. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". At this time only the "user" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the ":" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8." /> <property name="read-only" type="boolean" default="FALSE" description="FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified." /> @@ -99,7 +101,7 @@ <property name="timestamp" type="uint64" default="0" description="The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved)." /> <property name="type" type="string" description="Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc)." /> <property name="uuid" type="string" description="A universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or "type" property changes. The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-")." /> - <property name="zone" type="string" description="The trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall." /> + <property name="zone" type="string" description="The trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. When updating this property on a currently activated connection, the change takes effect immediately." /> </setting> <setting name="dcb"> <property name="app-fcoe-flags" type="NMSettingDcbFlags (uint32)" description="Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)." /> @@ -124,6 +126,7 @@ </setting> <setting name="gsm"> <property name="apn" type="string" description="The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9." /> + <property name="device-id" type="string" description="The device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device." /> <property name="home-only" type="boolean" default="FALSE" description="When TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made." /> <property name="name" type="string" default="gsm" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="network-id" type="string" description="The Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible." /> @@ -132,6 +135,8 @@ <property name="password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "password" property." /> <property name="pin" type="string" description="If the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device." /> <property name="pin-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "pin" property." /> + <property name="sim-id" type="string" description="The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" which contains a SIM card matching the given identifier." /> + <property name="sim-operator-id" type="string" description="A MCC/MNC string like "310260" or "21601" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" and "sim-id" which contains a SIM card provisioined by the given operator." /> <property name="username" type="string" description="The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here." /> </setting> <setting name="infiniband"> @@ -146,9 +151,12 @@ <property name="address-data" type="array of vardict" description="Array of IPv4 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses." /> <property name="addresses" type="array of array of uint32" default="[]" description="Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv4 address structures. Each IPv4 address structure is composed of 3 32-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 - 32), and last the IPv4 gateway (network byte order). The gateway may be left as 0 if no gateway exists for that subnet." /> <property name="dhcp-client-id" type="string" description="A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options." /> - <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease." /> + <property name="dhcp-fqdn" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time." /> + <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." /> <property name="dhcp-send-hostname" type="boolean" default="TRUE" description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." /> + <property name="dhcp-timeout" type="uint32" default="0" description="A timeout for a DHCP transaction in seconds." /> <property name="dns" type="array of uint32" default="[]" description="Array of IP addresses of DNS servers (as network-byte-order integers)" /> + <property name="dns-options" type="array of string" default="[]" description="Array of DNS options. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties." /> <property name="dns-search" type="array of string" default="[]" description="Array of DNS search domains." /> <property name="gateway" type="string" description="The gateway associated with this configuration. This is only meaningful if "addresses" is also set." /> <property name="ignore-auto-dns" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used." /> @@ -162,16 +170,18 @@ <property name="routes" type="array of array of uint32" default="[]" description="Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv4 route structures. Each IPv4 route structure is composed of 4 32-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 - 32), the third being the next-hop (network byte order) if any, and the fourth being the route metric. If the metric is 0, NM will choose an appropriate default metric for the device. (There is no way to explicitly specify an actual metric of 0 with this property.)" /> </setting> <setting name="ipv6"> + <property name="addr-gen-mode" type="int32" default="1" description="Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: "eui64", "stable-privacy" or unset. If the property is set to "eui64", the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of "stable-privacy" enables use of cryptographically secure hash of a secret host-specific key along with the connection identification and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. Leaving this unset causes a default that could be subject to change in future versions to be used. Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses configured with this option." /> <property name="address-data" type="array of vardict" description="Array of IPv6 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses." /> <property name="addresses" type="array of legacy IPv6 address struct (a(ayuay))" default="[]" description="Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv6 address structures. Each IPv6 address structure is composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 gateway address. The gateway may be zeroed out if no gateway exists for that subnet." /> - <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease." /> + <property name="dhcp-hostname" type="string" description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." /> <property name="dhcp-send-hostname" type="boolean" default="TRUE" description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." /> <property name="dns" type="array of byte array" default="[]" description="Array of IP addresses of DNS servers (in network byte order)" /> + <property name="dns-options" type="array of string" default="[]" description="Array of DNS options. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties." /> <property name="dns-search" type="array of string" default="[]" description="Array of DNS search domains." /> <property name="gateway" type="string" description="The gateway associated with this configuration. This is only meaningful if "addresses" is also set." /> <property name="ignore-auto-dns" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used." /> <property name="ignore-auto-routes" type="boolean" default="FALSE" description="When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used." /> - <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr"." /> + <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the "addr-gen-mode" property's "stable-privacy" setting as another way of avoiding host tracking with IPv6 addresses." /> <property name="may-fail" type="boolean" default="TRUE" description="If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully." /> <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> <property name="name" type="string" default="ipv6" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> @@ -180,6 +190,28 @@ <property name="route-metric" type="int64" default="-1" description="The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric." /> <property name="routes" type="array of legacy IPv6 route struct (a(ayuayu))" default="[]" description="Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv6 route structures. Each IPv6 route structure is composed of an IPv6 address, a prefix length (1 - 128), an IPv6 next hop address (which may be zeroed out if there is no next hop), and a metric. If the metric is 0, NM will choose an appropriate default metric for the device." /> </setting> + <setting name="ip-tunnel"> + <property name="encapsulation-limit" type="uint32" default="0" description="How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels." /> + <property name="flow-label" type="uint32" default="0" description="The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels." /> + <property name="input-key" type="string" description="The key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used." /> + <property name="local" type="string" description="The local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address." /> + <property name="mode" type="uint32" default="0" description="The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2)." /> + <property name="mtu" type="uint32" default="0" description="None" /> + <property name="name" type="string" default="ip-tunnel" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="output-key" type="string" description="The key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface." /> + <property name="path-mtu-discovery" type="boolean" default="TRUE" description="Whether to enable Path MTU Discovery on this tunnel." /> + <property name="remote" type="string" description="The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address." /> + <property name="tos" type="uint32" default="0" description="The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets." /> + <property name="ttl" type="uint32" default="0" description="The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value." /> + </setting> + <setting name="macvlan"> + <property name="mode" type="uint32" default="0" description="The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device." /> + <property name="name" type="string" default="macvlan" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property." /> + <property name="promiscuous" type="boolean" default="TRUE" description="Whether the interface should be put in promiscuous mode." /> + <property name="tap" type="boolean" default="FALSE" description="Whether the interface should be a MACVTAP." /> + </setting> <setting name="802-11-olpc-mesh"> <property name="channel" type="uint32" default="0" description="Channel on which the mesh network to join is located." /> <property name="dhcp-anycast-address" type="byte array" description="Anycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request." /> @@ -231,9 +263,18 @@ <property name="config" type="string" description="The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details." /> <property name="name" type="string" default="team-port" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> </setting> + <setting name="tun"> + <property name="group" type="string" description="The group ID which will own the device. If set to NULL everyone will be able to use the device." /> + <property name="mode" type="uint32" default="1" description="The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one." /> + <property name="multi-queue" type="boolean" default="FALSE" description="If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue." /> + <property name="name" type="string" default="tun" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="owner" type="string" description="The user ID which will own the device. If set to NULL everyone will be able to use the device." /> + <property name="pi" type="boolean" default="FALSE" description="If TRUE the interface will prepend a 4 byte header describing the physical interface to the packets." /> + <property name="vnet-hdr" type="boolean" default="FALSE" description="If TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header." /> + </setting> <setting name="vlan"> <property name="egress-priority-map" type="array of string" default="[]" description="For outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"." /> - <property name="flags" type="NMVlanFlags (uint32)" description="One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state)." /> + <property name="flags" type="NMVlanFlags (uint32)" description="One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0." /> <property name="id" type="uint32" default="0" description="The VLAN identifier that the interface created by this connection should be assigned." /> <property name="ingress-priority-map" type="array of string" default="[]" description="For incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"." /> <property name="interface-name" type="string" description="Deprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the vlan's interface name." /> @@ -246,12 +287,32 @@ <property name="persistent" type="boolean" default="FALSE" description="If the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected." /> <property name="secrets" type="dict of string to string" default="{}" description="Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings." /> <property name="service-type" type="string" description="D-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin." /> + <property name="timeout" type="uint32" default="0" description="Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overriden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds." /> <property name="user-name" type="string" description="If the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection." /> </setting> + <setting name="vxlan"> + <property name="ageing" type="uint32" default="0" description="Specifies the lifetime in seconds of FDB entries learnt by the kernel." /> + <property name="destination-port" type="uint32" default="8472" description="Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="id" type="uint32" default="0" description="Specifies the VXLAN Network Identifer (or VXLAN Segment Identifier) to use." /> + <property name="l2-miss" type="boolean" default="FALSE" description="Specifies whether netlink LL ADDR miss notifications are generated." /> + <property name="l3-miss" type="boolean" default="FALSE" description="Specifies whether netlink IP ADDR miss notifications are generated." /> + <property name="learning" type="boolean" default="TRUE" description="Specifies whether unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database." /> + <property name="limit" type="uint32" default="0" description="Specifies the maximum number of FDB entries. A value of zero means that the kernel will store unlimited entries." /> + <property name="local" type="string" description="If given, specifies the source IP address to use in outgoing packets." /> + <property name="name" type="string" default="vxlan" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="parent" type="string" description="If given, specifies the parent interface name or parent connection UUID." /> + <property name="proxy" type="boolean" default="FALSE" description="Specifies whether ARP proxy is turned on." /> + <property name="remote" type="string" description="Specifies the unicast destination IP address to use in outgoing packets when the destination link layer address is not known in the VXLAN device forwarding database, or the multicast IP address to join." /> + <property name="rsc" type="boolean" default="FALSE" description="Specifies whether route short circuit is turned on." /> + <property name="source-port-max" type="uint32" default="0" description="Specifies the maximum UDP source port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="source-port-min" type="uint32" default="0" description="Specifies the minimum UDP source port to communicate to the remote VXLAN tunnel endpoint." /> + <property name="tos" type="uint32" default="0" description="Specifies the TOS value to use in outgoing packets." /> + <property name="ttl" type="uint32" default="0" description="Specifies the time-to-live value to use in outgoing packets." /> + </setting> <setting name="wimax"> - <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing)." /> + <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1" /> <property name="name" type="string" default="wimax" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> - <property name="network-name" type="string" description="Network Service Provider (NSP) name of the WiMAX network this connection should use." /> + <property name="network-name" type="string" description="Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1" /> </setting> <setting name="802-3-ethernet"> <property name="auto-negotiate" type="boolean" default="TRUE" description="If TRUE, allow auto-negotiation of port speed and duplex mode. If FALSE, do not allow auto-negotiation, in which case the "speed" and "duplex" properties should be set." /> @@ -277,9 +338,11 @@ <property name="hidden" type="boolean" default="FALSE" description="If TRUE, indicates this network is a non-broadcasting network that hides its SSID. In this case various workarounds may take place, such as probe-scanning the SSID for more reliable network discovery. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution." /> <property name="mac-address" type="byte array" description="If specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing)." /> <property name="mac-address-blacklist" type="array of string" default="[]" description="A list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg "00:11:22:33:44:55")." /> + <property name="mac-address-randomization" type="uint32" default="0" description="One of NM_SETTING_MAC_RANDOMIZATION_DEFAULT (0) (never randomize unless the user has set a global default to randomize and the supplicant supports randomization), NM_SETTING_MAC_RANDOMIZATION_NEVER (1) (never randomize the MAC address), or NM_SETTING_MAC_RANDOMIZATION_ALWAYS (2) (always randomize the MAC address)." /> <property name="mode" type="string" description="Wi-Fi network mode; one of "infrastructure", "adhoc" or "ap". If blank, infrastructure is assumed." /> <property name="mtu" type="uint32" default="0" description="If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames." /> <property name="name" type="string" default="802-11-wireless" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> + <property name="powersave" type="uint32" default="0" description="If set to FALSE, Wi-Fi power saving behavior is disabled. If set to TRUE, Wi-Fi power saving behavior is enabled. All other values are reserved. Note that even though only boolean values are allowed, the property type is an unsigned integer to allow for future expansion." /> <property name="rate" type="uint32" default="0" description="If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate." /> <property name="security" type="None" description="This property is deprecated, but can be set to the value '802-11-wireless-security' when a wireless security setting is also present in the connection dictionary, for compatibility with very old NetworkManager daemons." /> <property name="seen-bssids" type="array of string" default="[]" description="A list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved." /> 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 <NetworkManager.h> can be included directly." -#endif - -#include <glib.h> -#include <glib-object.h> -#include <nm-types.h> - -G_BEGIN_DECLS - -typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin; -typedef struct _NMVpnEditor NMVpnEditor; - -/* Plugin's factory function that returns a GObject that implements - * NMVpnEditorPlugin. - */ -#ifndef __GI_SCANNER__ -typedef NMVpnEditorPlugin * (*NMVpnEditorPluginFactory) (GError **error); -NMVpnEditorPlugin *nm_vpn_editor_plugin_factory (GError **error); -#endif - - -/**************************************************/ -/* Editor plugin interface */ -/**************************************************/ - -#define NM_TYPE_VPN_EDITOR_PLUGIN (nm_vpn_editor_plugin_get_type ()) -#define NM_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPlugin)) -#define NM_IS_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN)) -#define NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPluginInterface)) - -/** - * NMVpnEditorPluginCapability: - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: unknown or no capability - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: the plugin can import new connections - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: the plugin can export connections - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: the plugin supports IPv6 addressing - * - * Flags that indicate certain capabilities of the plugin to editor programs. - **/ -typedef enum /*< flags >*/ { - NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04 -} NMVpnEditorPluginCapability; - -/* Short display name of the VPN plugin */ -#define NM_VPN_EDITOR_PLUGIN_NAME "name" - -/* Longer description of the VPN plugin */ -#define NM_VPN_EDITOR_PLUGIN_DESCRIPTION "description" - -/* D-Bus service name of the plugin's VPN service */ -#define NM_VPN_EDITOR_PLUGIN_SERVICE "service" - -/** - * NMVpnEditorPluginInterface: - * @g_iface: the parent interface - * @get_editor: returns an #NMVpnEditor, pre-filled with values from @connection - * if non-%NULL. - * @get_capabilities: returns a bitmask of capabilities. - * @import_from_file: Try to import a connection from the specified path. On - * success, return a partial #NMConnection object. On error, return %NULL and - * set @error with additional information. Note that @error can be %NULL, in - * which case no additional error information should be provided. - * @export_to_file: Export the given connection to the specified path. Return - * %TRUE on success. On error, return %FALSE and set @error with additional - * error information. Note that @error can be %NULL, in which case no - * additional error information should be provided. - * @get_suggested_filename: For a given connection, return a suggested file - * name. Returned value will be %NULL or a suggested file name to be freed by - * the caller. - * - * Interface for VPN editor plugins. - */ -typedef struct { - GTypeInterface g_iface; - - NMVpnEditor * (*get_editor) (NMVpnEditorPlugin *plugin, - NMConnection *connection, - GError **error); - - NMVpnEditorPluginCapability (*get_capabilities) (NMVpnEditorPlugin *plugin); - - NMConnection * (*import_from_file) (NMVpnEditorPlugin *plugin, - const char *path, - GError **error); - - gboolean (*export_to_file) (NMVpnEditorPlugin *plugin, - const char *path, - NMConnection *connection, - GError **error); - - char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection); -} NMVpnEditorPluginInterface; - -GType nm_vpn_editor_plugin_get_type (void); - -NMVpnEditor *nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin, - NMConnection *connection, - GError **error); - -NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin); - -NMConnection *nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin, - const char *path, - GError **error); -gboolean nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin, - const char *path, - NMConnection *connection, - GError **error); -char *nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin, - NMConnection *connection); - -/**************************************************/ -/* 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 <NetworkManager.h> can be included directly." +#endif + +#include <glib.h> +#include <glib-object.h> +#include <nm-types.h> + +#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 <errno.h> #include <signal.h> #include <stdlib.h> -#include <glib/gi18n-lib.h> -#include <gio/gio.h> - -#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 <errno.h> +#include <signal.h> +#include <stdlib.h> + +#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 <gio/gio.h> +#include <nm-vpn-dbus-interface.h> +#include <nm-connection.h> + +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 <string.h> -#include "nm-glib-compat.h" - #include <nm-connection.h> #include <nm-setting-connection.h> #include <nm-setting-wimax.h> +#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 <glib.h> -#include <string.h> - -#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 <gio/gio.h> -#include <NetworkManager.h> - -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 <glib.h> #include <string.h> #include <sys/types.h> #include <signal.h> -#include <NetworkManager.h> -#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 <glib.h> #include <string.h> #include <sys/types.h> #include <signal.h> -#include <NetworkManager.h> +#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 <glib.h> #include <string.h> #include <sys/types.h> #include <signal.h> -#include <NetworkManager.h> #include <nm-secret-agent-old.h> -#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); |