diff options
Diffstat (limited to 'src')
234 files changed, 22296 insertions, 7928 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index cbcfdc62..f46fbab3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,5 @@ SUBDIRS= \ + generated \ logging \ dns-manager \ vpn-manager \ @@ -10,6 +11,8 @@ SUBDIRS= \ dnsmasq-manager \ modem-manager \ bluez-manager \ + firewall-manager \ + wifi \ settings if WITH_WIMAX @@ -20,7 +23,9 @@ SUBDIRS += . tests INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/dns-manager \ -I${top_srcdir}/src/vpn-manager \ @@ -30,14 +35,13 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/src/dnsmasq-manager \ -I${top_srcdir}/src/modem-manager \ -I$(top_srcdir)/src/bluez-manager \ + -I$(top_srcdir)/src/firewall-manager \ -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/src/wifi \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/callouts -if WITH_WIMAX -INCLUDES += -I$(top_srcdir)/src/wimax -endif - ########################################### # Test libraries ########################################### @@ -63,7 +67,7 @@ libtest_dhcp_la_CPPFLAGS = \ $(LIBNL_CFLAGS) libtest_dhcp_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) \ @@ -113,19 +117,25 @@ NetworkManager_SOURCES = \ nm-call-store.h \ nm-device.c \ nm-device.h \ - nm-device-interface.c \ - nm-device-interface.h \ nm-device-private.h \ nm-device-ethernet.c \ nm-device-ethernet.h \ nm-device-wifi.c \ nm-device-wifi.h \ + nm-device-wired.c \ + nm-device-wired.h \ nm-device-olpc-mesh.c \ nm-device-olpc-mesh.h \ nm-device-bt.c \ nm-device-bt.h \ nm-device-modem.h \ nm-device-modem.c \ + nm-device-infiniband.c \ + nm-device-infiniband.h \ + nm-device-bond.c \ + nm-device-bond.h \ + nm-device-vlan.c \ + nm-device-vlan.h \ nm-wifi-ap.c \ nm-wifi-ap.h \ nm-wifi-ap-utils.c \ @@ -134,6 +144,7 @@ NetworkManager_SOURCES = \ nm-dbus-manager.c \ nm-udev-manager.c \ nm-udev-manager.h \ + nm-device-factory.h \ nm-hostname-provider.c \ nm-hostname-provider.h \ nm-ip4-config.c \ @@ -169,15 +180,28 @@ NetworkManager_SOURCES = \ nm-activation-request.h \ nm-properties-changed-signal.c \ nm-properties-changed-signal.h \ - wpa.c \ - wpa.h \ nm-dhcp4-config.c \ nm-dhcp4-config.h \ nm-dhcp6-config.c \ nm-dhcp6-config.h \ nm-rfkill.h \ - nm-session-monitor.c \ - nm-session-monitor.h + nm-session-monitor.h \ + nm-session-utils.c \ + nm-session-utils.h + +if WITH_CONCHECK +NetworkManager_SOURCES += nm-connectivity.c nm-connectivity.h +endif + +if SESSION_TRACKING_SYSTEMD +NetworkManager_SOURCES += nm-session-monitor-systemd.c +else +if SESSION_TRACKING_CK +NetworkManager_SOURCES += nm-session-monitor-ck.c +else +NetworkManager_SOURCES += nm-session-monitor-null.c +endif +endif nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $< @@ -191,6 +215,9 @@ nm-device-interface-glue.h: $(top_srcdir)/introspection/nm-device.xml nm-device-ethernet-glue.h: $(top_srcdir)/introspection/nm-device-ethernet.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_ethernet --mode=glib-server --output=$@ $< +nm-device-infiniband-glue.h: $(top_srcdir)/introspection/nm-device-infiniband.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_infiniband --mode=glib-server --output=$@ $< + nm-device-wifi-glue.h: $(top_srcdir)/introspection/nm-device-wifi.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_wifi --mode=glib-server --output=$@ $< @@ -200,6 +227,12 @@ nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml nm-device-olpc-mesh-glue.h: $(top_srcdir)/introspection/nm-device-olpc-mesh.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_olpc_mesh --mode=glib-server --output=$@ $< +nm-device-bond-glue.h: $(top_srcdir)/introspection/nm-device-bond.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_bond --mode=glib-server --output=$@ $< + +nm-device-vlan-glue.h: $(top_srcdir)/introspection/nm-device-vlan.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_vlan --mode=glib-server --output=$@ $< + nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $< @@ -223,6 +256,9 @@ BUILT_SOURCES = \ nm-manager-glue.h \ nm-device-interface-glue.h \ nm-device-ethernet-glue.h \ + nm-device-infiniband-glue.h \ + nm-device-bond-glue.h \ + nm-device-vlan-glue.h \ nm-device-wifi-glue.h \ nm-device-olpc-mesh-glue.h \ nm-device-bt-glue.h \ @@ -240,6 +276,7 @@ NetworkManager_CPPFLAGS = \ $(LIBNL_CFLAGS) \ $(GMODULE_CFLAGS) \ $(POLKIT_CFLAGS) \ + $(SYSTEMD_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DBINDIR=\"$(bindir)\" \ -DSBINDIR=\"$(sbindir)\" \ @@ -249,16 +286,15 @@ NetworkManager_CPPFLAGS = \ -DLOCALSTATEDIR=\"$(localstatedir)\" \ -DNM_RUN_DIR=\"$(rundir)\" \ -DNMLOCALEDIR=\"$(datadir)/locale\" \ + -DNMPLUGINDIR=\"$(pkglibdir)\" -DARP_DEBUG - -WIMAX_LIBS= -if WITH_WIMAX -WIMAX_LIBS += ./wimax/libwimax.la +if WITH_CONCHECK +NetworkManager_CPPFLAGS += $(LIBSOUP_CFLAGS) endif NetworkManager_LDADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + ./generated/libnm-generated.la \ ./logging/libnm-logging.la \ ./dns-manager/libdns-manager.la \ ./vpn-manager/libvpn-manager.la \ @@ -269,8 +305,9 @@ NetworkManager_LDADD = \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ ./bluez-manager/libbluez-manager.la \ + ./wifi/libwifi-utils.la \ + ./firewall-manager/libfirewall-manager.la \ ./settings/libsettings.la \ - $(WIMAX_LIBS) \ ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ @@ -279,9 +316,14 @@ NetworkManager_LDADD = \ $(LIBNL_LIBS) \ $(GMODULE_LIBS) \ $(POLKIT_LIBS) \ + $(SYSTEMD_LIBS) \ $(LIBM) \ $(LIBDL) +if WITH_CONCHECK +NetworkManager_LDADD += $(LIBSOUP_LIBS) +endif + NetworkManager_LDFLAGS = -rdynamic libexec_PROGRAMS = nm-crash-logger @@ -301,7 +343,7 @@ NetworkManagerdir = $(datadir)/NetworkManager NetworkManager_DATA = gdb-cmd dbusservicedir = $(DBUS_SYS_DIR) -dbusservice_DATA = NetworkManager.conf +dbusservice_DATA = org.freedesktop.NetworkManager.conf EXTRA_DIST = \ $(dbusservice_DATA) \ diff --git a/src/Makefile.in b/src/Makefile.in index 5a388235..715658e8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -37,9 +37,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_WIMAX_TRUE@am__append_1 = wimax -@WITH_WIMAX_TRUE@am__append_2 = -I$(top_srcdir)/src/wimax sbin_PROGRAMS = NetworkManager$(EXEEXT) -@WITH_WIMAX_TRUE@am__append_3 = ./wimax/libwimax.la +@WITH_CONCHECK_TRUE@am__append_2 = nm-connectivity.c nm-connectivity.h +@SESSION_TRACKING_SYSTEMD_TRUE@am__append_3 = nm-session-monitor-systemd.c +@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_4 = nm-session-monitor-ck.c +@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_5 = nm-session-monitor-null.c +@WITH_CONCHECK_TRUE@am__append_6 = $(LIBSOUP_CFLAGS) +@WITH_CONCHECK_TRUE@am__append_7 = $(LIBSOUP_LIBS) libexec_PROGRAMS = nm-crash-logger$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in @@ -64,7 +68,7 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libtest_dhcp_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libtest_dhcp_la_OBJECTS = libtest_dhcp_la-nm-ip4-config.lo \ @@ -91,14 +95,50 @@ libtest_wifi_ap_utils_la_OBJECTS = \ am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \ "$(DESTDIR)$(NetworkManagerdir)" "$(DESTDIR)$(dbusservicedir)" PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS) +am__NetworkManager_SOURCES_DIST = nm-call-store.c nm-call-store.h \ + nm-device.c nm-device.h nm-device-private.h \ + nm-device-ethernet.c nm-device-ethernet.h nm-device-wifi.c \ + nm-device-wifi.h nm-device-wired.c nm-device-wired.h \ + nm-device-olpc-mesh.c nm-device-olpc-mesh.h nm-device-bt.c \ + nm-device-bt.h nm-device-modem.h nm-device-modem.c \ + nm-device-infiniband.c nm-device-infiniband.h nm-device-bond.c \ + nm-device-bond.h nm-device-vlan.c nm-device-vlan.h \ + nm-wifi-ap.c nm-wifi-ap.h nm-wifi-ap-utils.c \ + nm-wifi-ap-utils.h nm-dbus-manager.h nm-dbus-manager.c \ + nm-udev-manager.c nm-udev-manager.h nm-device-factory.h \ + nm-hostname-provider.c nm-hostname-provider.h nm-ip4-config.c \ + nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h \ + nm-active-connection.h nm-active-connection.c nm-config.h \ + nm-config.c main.c nm-policy.c nm-policy.h nm-policy-hosts.c \ + nm-policy-hosts.h nm-policy-hostname.c nm-policy-hostname.h \ + NetworkManagerUtils.c NetworkManagerUtils.h nm-system.c \ + nm-system.h nm-manager.c nm-manager.h nm-manager-auth.c \ + nm-manager-auth.h nm-netlink-monitor.c nm-netlink-monitor.h \ + nm-netlink-utils.c nm-netlink-utils.h nm-netlink-compat.h \ + nm-netlink-compat.c nm-activation-request.c \ + nm-activation-request.h nm-properties-changed-signal.c \ + nm-properties-changed-signal.h nm-dhcp4-config.c \ + nm-dhcp4-config.h nm-dhcp6-config.c nm-dhcp6-config.h \ + nm-rfkill.h nm-session-monitor.h nm-session-utils.c \ + nm-session-utils.h nm-connectivity.c nm-connectivity.h \ + nm-session-monitor-systemd.c nm-session-monitor-ck.c \ + nm-session-monitor-null.c +@WITH_CONCHECK_TRUE@am__objects_1 = \ +@WITH_CONCHECK_TRUE@ NetworkManager-nm-connectivity.$(OBJEXT) +@SESSION_TRACKING_SYSTEMD_TRUE@am__objects_2 = NetworkManager-nm-session-monitor-systemd.$(OBJEXT) +@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_3 = NetworkManager-nm-session-monitor-ck.$(OBJEXT) +@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_4 = NetworkManager-nm-session-monitor-null.$(OBJEXT) am_NetworkManager_OBJECTS = NetworkManager-nm-call-store.$(OBJEXT) \ NetworkManager-nm-device.$(OBJEXT) \ - NetworkManager-nm-device-interface.$(OBJEXT) \ NetworkManager-nm-device-ethernet.$(OBJEXT) \ NetworkManager-nm-device-wifi.$(OBJEXT) \ + NetworkManager-nm-device-wired.$(OBJEXT) \ NetworkManager-nm-device-olpc-mesh.$(OBJEXT) \ NetworkManager-nm-device-bt.$(OBJEXT) \ NetworkManager-nm-device-modem.$(OBJEXT) \ + NetworkManager-nm-device-infiniband.$(OBJEXT) \ + NetworkManager-nm-device-bond.$(OBJEXT) \ + NetworkManager-nm-device-vlan.$(OBJEXT) \ NetworkManager-nm-wifi-ap.$(OBJEXT) \ NetworkManager-nm-wifi-ap-utils.$(OBJEXT) \ NetworkManager-nm-dbus-manager.$(OBJEXT) \ @@ -121,13 +161,13 @@ am_NetworkManager_OBJECTS = NetworkManager-nm-call-store.$(OBJEXT) \ NetworkManager-nm-netlink-compat.$(OBJEXT) \ NetworkManager-nm-activation-request.$(OBJEXT) \ NetworkManager-nm-properties-changed-signal.$(OBJEXT) \ - NetworkManager-wpa.$(OBJEXT) \ NetworkManager-nm-dhcp4-config.$(OBJEXT) \ NetworkManager-nm-dhcp6-config.$(OBJEXT) \ - NetworkManager-nm-session-monitor.$(OBJEXT) + NetworkManager-nm-session-utils.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) NetworkManager_OBJECTS = $(am_NetworkManager_OBJECTS) -NetworkManager_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ +@WITH_CONCHECK_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +NetworkManager_DEPENDENCIES = ./generated/libnm-generated.la \ ./logging/libnm-logging.la ./dns-manager/libdns-manager.la \ ./vpn-manager/libvpn-manager.la \ ./dhcp-manager/libdhcp-manager.la \ @@ -136,13 +176,15 @@ NetworkManager_DEPENDENCIES = \ ./dnsmasq-manager/libdnsmasq-manager.la \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ - ./bluez-manager/libbluez-manager.la ./settings/libsettings.la \ - $(WIMAX_LIBS) ./backends/libnmbackend.la \ + ./bluez-manager/libbluez-manager.la ./wifi/libwifi-utils.la \ + ./firewall-manager/libfirewall-manager.la \ + ./settings/libsettings.la ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) NetworkManager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(NetworkManager_LDFLAGS) $(LDFLAGS) -o \ @@ -183,8 +225,8 @@ SOURCES = $(libtest_dhcp_la_SOURCES) \ $(nm_crash_logger_SOURCES) DIST_SOURCES = $(libtest_dhcp_la_SOURCES) \ $(libtest_policy_hosts_la_SOURCES) \ - $(libtest_wifi_ap_utils_la_SOURCES) $(NetworkManager_SOURCES) \ - $(nm_crash_logger_SOURCES) + $(libtest_wifi_ap_utils_la_SOURCES) \ + $(am__NetworkManager_SOURCES_DIST) $(nm_crash_logger_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ @@ -221,10 +263,10 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ distdir ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = logging dns-manager vpn-manager dhcp-manager \ +DIST_SUBDIRS = generated logging dns-manager vpn-manager dhcp-manager \ ip6-manager supplicant-manager ppp-manager backends \ - dnsmasq-manager modem-manager bluez-manager settings wimax . \ - tests + dnsmasq-manager modem-manager bluez-manager firewall-manager \ + wifi settings wimax . tests DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -296,6 +338,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -350,11 +394,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -365,6 +413,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -404,6 +453,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -467,21 +518,31 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = logging dns-manager vpn-manager dhcp-manager ip6-manager \ - supplicant-manager ppp-manager backends dnsmasq-manager \ - modem-manager bluez-manager settings $(am__append_1) . tests -INCLUDES = -I${top_srcdir} -I${top_srcdir}/include \ - -I${top_builddir}/marshallers -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src/dns-manager \ - -I${top_srcdir}/src/vpn-manager \ - -I${top_srcdir}/src/dhcp-manager \ - -I${top_srcdir}/src/ip6-manager \ - -I${top_srcdir}/src/supplicant-manager \ - -I${top_srcdir}/src/dnsmasq-manager \ - -I${top_srcdir}/src/modem-manager \ - -I$(top_srcdir)/src/bluez-manager -I$(top_srcdir)/src/settings \ - -I${top_srcdir}/libnm-util -I${top_srcdir}/callouts \ - $(am__append_2) +SUBDIRS = generated logging dns-manager vpn-manager dhcp-manager \ + ip6-manager supplicant-manager ppp-manager backends \ + dnsmasq-manager modem-manager bluez-manager firewall-manager \ + wifi settings $(am__append_1) . tests +INCLUDES = -I${top_srcdir} \ + -I${top_srcdir}/include \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/dns-manager \ + -I${top_srcdir}/src/vpn-manager \ + -I${top_srcdir}/src/dhcp-manager \ + -I${top_srcdir}/src/ip6-manager \ + -I${top_srcdir}/src/supplicant-manager \ + -I${top_srcdir}/src/dnsmasq-manager \ + -I${top_srcdir}/src/modem-manager \ + -I$(top_srcdir)/src/bluez-manager \ + -I$(top_srcdir)/src/firewall-manager \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/src/wifi \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/callouts + ########################################### # Test libraries @@ -507,7 +568,7 @@ libtest_dhcp_la_CPPFLAGS = \ $(LIBNL_CFLAGS) libtest_dhcp_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) \ @@ -544,82 +605,41 @@ libtest_wifi_ap_utils_la_LIBADD = \ ${top_builddir}/libnm-util/libnm-util.la \ $(GLIB_LIBS) -NetworkManager_SOURCES = \ - nm-call-store.c \ - nm-call-store.h \ - nm-device.c \ - nm-device.h \ - nm-device-interface.c \ - nm-device-interface.h \ - nm-device-private.h \ - nm-device-ethernet.c \ - nm-device-ethernet.h \ - nm-device-wifi.c \ - nm-device-wifi.h \ - nm-device-olpc-mesh.c \ - nm-device-olpc-mesh.h \ - nm-device-bt.c \ - nm-device-bt.h \ - nm-device-modem.h \ - nm-device-modem.c \ - nm-wifi-ap.c \ - nm-wifi-ap.h \ - nm-wifi-ap-utils.c \ - nm-wifi-ap-utils.h \ - nm-dbus-manager.h \ - nm-dbus-manager.c \ - nm-udev-manager.c \ - nm-udev-manager.h \ - nm-hostname-provider.c \ - nm-hostname-provider.h \ - nm-ip4-config.c \ - nm-ip4-config.h \ - nm-ip6-config.c \ - nm-ip6-config.h \ - nm-active-connection.h \ - nm-active-connection.c \ - nm-config.h \ - nm-config.c \ - main.c \ - nm-policy.c \ - nm-policy.h \ - nm-policy-hosts.c \ - nm-policy-hosts.h \ - nm-policy-hostname.c \ - nm-policy-hostname.h \ - NetworkManagerUtils.c \ - NetworkManagerUtils.h \ - nm-system.c \ - nm-system.h \ - nm-manager.c \ - nm-manager.h \ - nm-manager-auth.c \ - nm-manager-auth.h \ - nm-netlink-monitor.c \ - nm-netlink-monitor.h \ - nm-netlink-utils.c \ - nm-netlink-utils.h \ - nm-netlink-compat.h \ - nm-netlink-compat.c \ - nm-activation-request.c \ - nm-activation-request.h \ - nm-properties-changed-signal.c \ - nm-properties-changed-signal.h \ - wpa.c \ - wpa.h \ - nm-dhcp4-config.c \ - nm-dhcp4-config.h \ - nm-dhcp6-config.c \ - nm-dhcp6-config.h \ - nm-rfkill.h \ - nm-session-monitor.c \ - nm-session-monitor.h - +NetworkManager_SOURCES = nm-call-store.c nm-call-store.h nm-device.c \ + nm-device.h nm-device-private.h nm-device-ethernet.c \ + nm-device-ethernet.h nm-device-wifi.c nm-device-wifi.h \ + nm-device-wired.c nm-device-wired.h nm-device-olpc-mesh.c \ + nm-device-olpc-mesh.h nm-device-bt.c nm-device-bt.h \ + nm-device-modem.h nm-device-modem.c nm-device-infiniband.c \ + nm-device-infiniband.h nm-device-bond.c nm-device-bond.h \ + nm-device-vlan.c nm-device-vlan.h nm-wifi-ap.c nm-wifi-ap.h \ + nm-wifi-ap-utils.c nm-wifi-ap-utils.h nm-dbus-manager.h \ + nm-dbus-manager.c nm-udev-manager.c nm-udev-manager.h \ + nm-device-factory.h nm-hostname-provider.c \ + nm-hostname-provider.h nm-ip4-config.c nm-ip4-config.h \ + nm-ip6-config.c nm-ip6-config.h nm-active-connection.h \ + nm-active-connection.c nm-config.h nm-config.c main.c \ + nm-policy.c nm-policy.h nm-policy-hosts.c nm-policy-hosts.h \ + nm-policy-hostname.c nm-policy-hostname.h \ + NetworkManagerUtils.c NetworkManagerUtils.h nm-system.c \ + nm-system.h nm-manager.c nm-manager.h nm-manager-auth.c \ + nm-manager-auth.h nm-netlink-monitor.c nm-netlink-monitor.h \ + nm-netlink-utils.c nm-netlink-utils.h nm-netlink-compat.h \ + nm-netlink-compat.c nm-activation-request.c \ + nm-activation-request.h nm-properties-changed-signal.c \ + nm-properties-changed-signal.h nm-dhcp4-config.c \ + nm-dhcp4-config.h nm-dhcp6-config.c nm-dhcp6-config.h \ + nm-rfkill.h nm-session-monitor.h nm-session-utils.c \ + nm-session-utils.h $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) BUILT_SOURCES = \ nm-access-point-glue.h \ nm-manager-glue.h \ nm-device-interface-glue.h \ nm-device-ethernet-glue.h \ + nm-device-infiniband-glue.h \ + nm-device-bond-glue.h \ + nm-device-vlan-glue.h \ nm-device-wifi-glue.h \ nm-device-olpc-mesh-glue.h \ nm-device-bt-glue.h \ @@ -630,29 +650,17 @@ BUILT_SOURCES = \ nm-dhcp4-config-glue.h \ nm-dhcp6-config-glue.h -NetworkManager_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GUDEV_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GMODULE_CFLAGS) \ - $(POLKIT_CFLAGS) \ - -DG_DISABLE_DEPRECATED \ - -DBINDIR=\"$(bindir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DDATADIR=\"$(datadir)\" \ +NetworkManager_CPPFLAGS = $(DBUS_CFLAGS) $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) $(LIBNL_CFLAGS) $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) $(SYSTEMD_CFLAGS) -DG_DISABLE_DEPRECATED \ + -DBINDIR=\"$(bindir)\" -DSBINDIR=\"$(sbindir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" -DDATADIR=\"$(datadir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DNM_RUN_DIR=\"$(rundir)\" \ - -DNMLOCALEDIR=\"$(datadir)/locale\" \ - -DARP_DEBUG - -WIMAX_LIBS = $(am__append_3) -NetworkManager_LDADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ - ./logging/libnm-logging.la \ - ./dns-manager/libdns-manager.la \ + -DNM_RUN_DIR=\"$(rundir)\" -DNMLOCALEDIR=\"$(datadir)/locale\" \ + -DNMPLUGINDIR=\"$(pkglibdir)\" $(am__append_6) +NetworkManager_LDADD = ./generated/libnm-generated.la \ + ./logging/libnm-logging.la ./dns-manager/libdns-manager.la \ ./vpn-manager/libvpn-manager.la \ ./dhcp-manager/libdhcp-manager.la \ ./ip6-manager/libip6-manager.la \ @@ -660,20 +668,13 @@ NetworkManager_LDADD = \ ./dnsmasq-manager/libdnsmasq-manager.la \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ - ./bluez-manager/libbluez-manager.la \ - ./settings/libsettings.la \ - $(WIMAX_LIBS) \ - ./backends/libnmbackend.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) \ - $(LIBNL_LIBS) \ - $(GMODULE_LIBS) \ - $(POLKIT_LIBS) \ - $(LIBM) \ - $(LIBDL) - + ./bluez-manager/libbluez-manager.la ./wifi/libwifi-utils.la \ + ./firewall-manager/libfirewall-manager.la \ + ./settings/libsettings.la ./backends/libnmbackend.la \ + $(top_builddir)/libnm-util/libnm-util.la $(DBUS_LIBS) \ + $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(GMODULE_LIBS) \ + $(POLKIT_LIBS) $(SYSTEMD_LIBS) $(LIBM) $(LIBDL) \ + $(am__append_7) NetworkManager_LDFLAGS = -rdynamic nm_crash_logger_SOURCES = nm-crash-logger.c nm_crash_logger_CPPFLAGS = \ @@ -689,7 +690,7 @@ nm_crash_logger_LDADD = $(GLIB_LIBS) NetworkManagerdir = $(datadir)/NetworkManager NetworkManager_DATA = gdb-cmd dbusservicedir = $(DBUS_SYS_DIR) -dbusservice_DATA = NetworkManager.conf +dbusservice_DATA = org.freedesktop.NetworkManager.conf EXTRA_DIST = \ $(dbusservice_DATA) \ $(NetworkManager_DATA) @@ -852,13 +853,17 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-active-connection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-call-store.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-config.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-connectivity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-dbus-manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-bond.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-bt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-ethernet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-interface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-infiniband.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-modem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-olpc-mesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-vlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-wifi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-wired.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-dhcp4-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-dhcp6-config.Po@am__quote@ @@ -874,12 +879,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy-hosts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-properties-changed-signal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-monitor-ck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-monitor-null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-system.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-udev-manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-wifi-ap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-wpa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-dbus-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-hostname-provider.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-ip4-config.Plo@am__quote@ @@ -995,22 +1002,6 @@ NetworkManager-nm-device.obj: nm-device.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device.obj `if test -f 'nm-device.c'; then $(CYGPATH_W) 'nm-device.c'; else $(CYGPATH_W) '$(srcdir)/nm-device.c'; fi` -NetworkManager-nm-device-interface.o: nm-device-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-interface.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-interface.Tpo -c -o NetworkManager-nm-device-interface.o `test -f 'nm-device-interface.c' || echo '$(srcdir)/'`nm-device-interface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-interface.Tpo $(DEPDIR)/NetworkManager-nm-device-interface.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-interface.c' object='NetworkManager-nm-device-interface.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-interface.o `test -f 'nm-device-interface.c' || echo '$(srcdir)/'`nm-device-interface.c - -NetworkManager-nm-device-interface.obj: nm-device-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-interface.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-interface.Tpo -c -o NetworkManager-nm-device-interface.obj `if test -f 'nm-device-interface.c'; then $(CYGPATH_W) 'nm-device-interface.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-interface.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-interface.Tpo $(DEPDIR)/NetworkManager-nm-device-interface.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-interface.c' object='NetworkManager-nm-device-interface.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-interface.obj `if test -f 'nm-device-interface.c'; then $(CYGPATH_W) 'nm-device-interface.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-interface.c'; fi` - NetworkManager-nm-device-ethernet.o: nm-device-ethernet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-ethernet.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-ethernet.Tpo -c -o NetworkManager-nm-device-ethernet.o `test -f 'nm-device-ethernet.c' || echo '$(srcdir)/'`nm-device-ethernet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-ethernet.Tpo $(DEPDIR)/NetworkManager-nm-device-ethernet.Po @@ -1043,6 +1034,22 @@ NetworkManager-nm-device-wifi.obj: nm-device-wifi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-wifi.obj `if test -f 'nm-device-wifi.c'; then $(CYGPATH_W) 'nm-device-wifi.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-wifi.c'; fi` +NetworkManager-nm-device-wired.o: nm-device-wired.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-wired.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-wired.Tpo -c -o NetworkManager-nm-device-wired.o `test -f 'nm-device-wired.c' || echo '$(srcdir)/'`nm-device-wired.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-wired.Tpo $(DEPDIR)/NetworkManager-nm-device-wired.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-wired.c' object='NetworkManager-nm-device-wired.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-wired.o `test -f 'nm-device-wired.c' || echo '$(srcdir)/'`nm-device-wired.c + +NetworkManager-nm-device-wired.obj: nm-device-wired.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-wired.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-wired.Tpo -c -o NetworkManager-nm-device-wired.obj `if test -f 'nm-device-wired.c'; then $(CYGPATH_W) 'nm-device-wired.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-wired.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-wired.Tpo $(DEPDIR)/NetworkManager-nm-device-wired.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-wired.c' object='NetworkManager-nm-device-wired.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-wired.obj `if test -f 'nm-device-wired.c'; then $(CYGPATH_W) 'nm-device-wired.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-wired.c'; fi` + NetworkManager-nm-device-olpc-mesh.o: nm-device-olpc-mesh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-olpc-mesh.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-olpc-mesh.Tpo -c -o NetworkManager-nm-device-olpc-mesh.o `test -f 'nm-device-olpc-mesh.c' || echo '$(srcdir)/'`nm-device-olpc-mesh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-olpc-mesh.Tpo $(DEPDIR)/NetworkManager-nm-device-olpc-mesh.Po @@ -1091,6 +1098,54 @@ NetworkManager-nm-device-modem.obj: nm-device-modem.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-modem.obj `if test -f 'nm-device-modem.c'; then $(CYGPATH_W) 'nm-device-modem.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-modem.c'; fi` +NetworkManager-nm-device-infiniband.o: nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-infiniband.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-infiniband.Tpo -c -o NetworkManager-nm-device-infiniband.o `test -f 'nm-device-infiniband.c' || echo '$(srcdir)/'`nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-infiniband.Tpo $(DEPDIR)/NetworkManager-nm-device-infiniband.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-infiniband.c' object='NetworkManager-nm-device-infiniband.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-infiniband.o `test -f 'nm-device-infiniband.c' || echo '$(srcdir)/'`nm-device-infiniband.c + +NetworkManager-nm-device-infiniband.obj: nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-infiniband.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-infiniband.Tpo -c -o NetworkManager-nm-device-infiniband.obj `if test -f 'nm-device-infiniband.c'; then $(CYGPATH_W) 'nm-device-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-infiniband.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-infiniband.Tpo $(DEPDIR)/NetworkManager-nm-device-infiniband.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-infiniband.c' object='NetworkManager-nm-device-infiniband.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-infiniband.obj `if test -f 'nm-device-infiniband.c'; then $(CYGPATH_W) 'nm-device-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-infiniband.c'; fi` + +NetworkManager-nm-device-bond.o: nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-bond.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-bond.Tpo -c -o NetworkManager-nm-device-bond.o `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-bond.Tpo $(DEPDIR)/NetworkManager-nm-device-bond.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-bond.c' object='NetworkManager-nm-device-bond.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-bond.o `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c + +NetworkManager-nm-device-bond.obj: nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-bond.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-bond.Tpo -c -o NetworkManager-nm-device-bond.obj `if test -f 'nm-device-bond.c'; then $(CYGPATH_W) 'nm-device-bond.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-bond.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-bond.Tpo $(DEPDIR)/NetworkManager-nm-device-bond.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-bond.c' object='NetworkManager-nm-device-bond.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-bond.obj `if test -f 'nm-device-bond.c'; then $(CYGPATH_W) 'nm-device-bond.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-bond.c'; fi` + +NetworkManager-nm-device-vlan.o: nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-vlan.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-vlan.Tpo -c -o NetworkManager-nm-device-vlan.o `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-vlan.Tpo $(DEPDIR)/NetworkManager-nm-device-vlan.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-vlan.c' object='NetworkManager-nm-device-vlan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-vlan.o `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c + +NetworkManager-nm-device-vlan.obj: nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-vlan.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-vlan.Tpo -c -o NetworkManager-nm-device-vlan.obj `if test -f 'nm-device-vlan.c'; then $(CYGPATH_W) 'nm-device-vlan.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-vlan.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-vlan.Tpo $(DEPDIR)/NetworkManager-nm-device-vlan.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-vlan.c' object='NetworkManager-nm-device-vlan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-vlan.obj `if test -f 'nm-device-vlan.c'; then $(CYGPATH_W) 'nm-device-vlan.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-vlan.c'; fi` + NetworkManager-nm-wifi-ap.o: nm-wifi-ap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-wifi-ap.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-wifi-ap.Tpo -c -o NetworkManager-nm-wifi-ap.o `test -f 'nm-wifi-ap.c' || echo '$(srcdir)/'`nm-wifi-ap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-wifi-ap.Tpo $(DEPDIR)/NetworkManager-nm-wifi-ap.Po @@ -1443,22 +1498,6 @@ NetworkManager-nm-properties-changed-signal.obj: nm-properties-changed-signal.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-properties-changed-signal.obj `if test -f 'nm-properties-changed-signal.c'; then $(CYGPATH_W) 'nm-properties-changed-signal.c'; else $(CYGPATH_W) '$(srcdir)/nm-properties-changed-signal.c'; fi` -NetworkManager-wpa.o: wpa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-wpa.o -MD -MP -MF $(DEPDIR)/NetworkManager-wpa.Tpo -c -o NetworkManager-wpa.o `test -f 'wpa.c' || echo '$(srcdir)/'`wpa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-wpa.Tpo $(DEPDIR)/NetworkManager-wpa.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wpa.c' object='NetworkManager-wpa.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-wpa.o `test -f 'wpa.c' || echo '$(srcdir)/'`wpa.c - -NetworkManager-wpa.obj: wpa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-wpa.obj -MD -MP -MF $(DEPDIR)/NetworkManager-wpa.Tpo -c -o NetworkManager-wpa.obj `if test -f 'wpa.c'; then $(CYGPATH_W) 'wpa.c'; else $(CYGPATH_W) '$(srcdir)/wpa.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-wpa.Tpo $(DEPDIR)/NetworkManager-wpa.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wpa.c' object='NetworkManager-wpa.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-wpa.obj `if test -f 'wpa.c'; then $(CYGPATH_W) 'wpa.c'; else $(CYGPATH_W) '$(srcdir)/wpa.c'; fi` - NetworkManager-nm-dhcp4-config.o: nm-dhcp4-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-dhcp4-config.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-dhcp4-config.Tpo -c -o NetworkManager-nm-dhcp4-config.o `test -f 'nm-dhcp4-config.c' || echo '$(srcdir)/'`nm-dhcp4-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-dhcp4-config.Tpo $(DEPDIR)/NetworkManager-nm-dhcp4-config.Po @@ -1491,21 +1530,85 @@ NetworkManager-nm-dhcp6-config.obj: nm-dhcp6-config.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-dhcp6-config.obj `if test -f 'nm-dhcp6-config.c'; then $(CYGPATH_W) 'nm-dhcp6-config.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp6-config.c'; fi` -NetworkManager-nm-session-monitor.o: nm-session-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo -c -o NetworkManager-nm-session-monitor.o `test -f 'nm-session-monitor.c' || echo '$(srcdir)/'`nm-session-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor.Po +NetworkManager-nm-session-utils.o: nm-session-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-utils.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-utils.Tpo -c -o NetworkManager-nm-session-utils.o `test -f 'nm-session-utils.c' || echo '$(srcdir)/'`nm-session-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-utils.Tpo $(DEPDIR)/NetworkManager-nm-session-utils.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-utils.c' object='NetworkManager-nm-session-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-utils.o `test -f 'nm-session-utils.c' || echo '$(srcdir)/'`nm-session-utils.c + +NetworkManager-nm-session-utils.obj: nm-session-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-utils.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-utils.Tpo -c -o NetworkManager-nm-session-utils.obj `if test -f 'nm-session-utils.c'; then $(CYGPATH_W) 'nm-session-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-utils.Tpo $(DEPDIR)/NetworkManager-nm-session-utils.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-utils.c' object='NetworkManager-nm-session-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-utils.obj `if test -f 'nm-session-utils.c'; then $(CYGPATH_W) 'nm-session-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-utils.c'; fi` + +NetworkManager-nm-connectivity.o: nm-connectivity.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-connectivity.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-connectivity.Tpo -c -o NetworkManager-nm-connectivity.o `test -f 'nm-connectivity.c' || echo '$(srcdir)/'`nm-connectivity.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-connectivity.Tpo $(DEPDIR)/NetworkManager-nm-connectivity.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-connectivity.c' object='NetworkManager-nm-connectivity.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-connectivity.o `test -f 'nm-connectivity.c' || echo '$(srcdir)/'`nm-connectivity.c + +NetworkManager-nm-connectivity.obj: nm-connectivity.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-connectivity.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-connectivity.Tpo -c -o NetworkManager-nm-connectivity.obj `if test -f 'nm-connectivity.c'; then $(CYGPATH_W) 'nm-connectivity.c'; else $(CYGPATH_W) '$(srcdir)/nm-connectivity.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-connectivity.Tpo $(DEPDIR)/NetworkManager-nm-connectivity.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-connectivity.c' object='NetworkManager-nm-connectivity.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-connectivity.obj `if test -f 'nm-connectivity.c'; then $(CYGPATH_W) 'nm-connectivity.c'; else $(CYGPATH_W) '$(srcdir)/nm-connectivity.c'; fi` + +NetworkManager-nm-session-monitor-systemd.o: nm-session-monitor-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-systemd.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Tpo -c -o NetworkManager-nm-session-monitor-systemd.o `test -f 'nm-session-monitor-systemd.c' || echo '$(srcdir)/'`nm-session-monitor-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-systemd.c' object='NetworkManager-nm-session-monitor-systemd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-systemd.o `test -f 'nm-session-monitor-systemd.c' || echo '$(srcdir)/'`nm-session-monitor-systemd.c + +NetworkManager-nm-session-monitor-systemd.obj: nm-session-monitor-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-systemd.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Tpo -c -o NetworkManager-nm-session-monitor-systemd.obj `if test -f 'nm-session-monitor-systemd.c'; then $(CYGPATH_W) 'nm-session-monitor-systemd.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-systemd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-systemd.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-systemd.c' object='NetworkManager-nm-session-monitor-systemd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-systemd.obj `if test -f 'nm-session-monitor-systemd.c'; then $(CYGPATH_W) 'nm-session-monitor-systemd.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-systemd.c'; fi` + +NetworkManager-nm-session-monitor-ck.o: nm-session-monitor-ck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-ck.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Tpo -c -o NetworkManager-nm-session-monitor-ck.o `test -f 'nm-session-monitor-ck.c' || echo '$(srcdir)/'`nm-session-monitor-ck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor.c' object='NetworkManager-nm-session-monitor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-ck.c' object='NetworkManager-nm-session-monitor-ck.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor.o `test -f 'nm-session-monitor.c' || echo '$(srcdir)/'`nm-session-monitor.c +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-ck.o `test -f 'nm-session-monitor-ck.c' || echo '$(srcdir)/'`nm-session-monitor-ck.c -NetworkManager-nm-session-monitor.obj: nm-session-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo -c -o NetworkManager-nm-session-monitor.obj `if test -f 'nm-session-monitor.c'; then $(CYGPATH_W) 'nm-session-monitor.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor.Po +NetworkManager-nm-session-monitor-ck.obj: nm-session-monitor-ck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-ck.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Tpo -c -o NetworkManager-nm-session-monitor-ck.obj `if test -f 'nm-session-monitor-ck.c'; then $(CYGPATH_W) 'nm-session-monitor-ck.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-ck.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-ck.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor.c' object='NetworkManager-nm-session-monitor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-ck.c' object='NetworkManager-nm-session-monitor-ck.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor.obj `if test -f 'nm-session-monitor.c'; then $(CYGPATH_W) 'nm-session-monitor.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor.c'; fi` +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-ck.obj `if test -f 'nm-session-monitor-ck.c'; then $(CYGPATH_W) 'nm-session-monitor-ck.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-ck.c'; fi` + +NetworkManager-nm-session-monitor-null.o: nm-session-monitor-null.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-null.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-null.Tpo -c -o NetworkManager-nm-session-monitor-null.o `test -f 'nm-session-monitor-null.c' || echo '$(srcdir)/'`nm-session-monitor-null.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-null.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-null.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-null.c' object='NetworkManager-nm-session-monitor-null.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-null.o `test -f 'nm-session-monitor-null.c' || echo '$(srcdir)/'`nm-session-monitor-null.c + +NetworkManager-nm-session-monitor-null.obj: nm-session-monitor-null.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor-null.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor-null.Tpo -c -o NetworkManager-nm-session-monitor-null.obj `if test -f 'nm-session-monitor-null.c'; then $(CYGPATH_W) 'nm-session-monitor-null.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-null.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor-null.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor-null.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor-null.c' object='NetworkManager-nm-session-monitor-null.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor-null.obj `if test -f 'nm-session-monitor-null.c'; then $(CYGPATH_W) 'nm-session-monitor-null.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor-null.c'; fi` nm_crash_logger-nm-crash-logger.o: nm-crash-logger.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_crash_logger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_crash_logger-nm-crash-logger.o -MD -MP -MF $(DEPDIR)/nm_crash_logger-nm-crash-logger.Tpo -c -o nm_crash_logger-nm-crash-logger.o `test -f 'nm-crash-logger.c' || echo '$(srcdir)/'`nm-crash-logger.c @@ -1909,6 +2012,9 @@ nm-device-interface-glue.h: $(top_srcdir)/introspection/nm-device.xml nm-device-ethernet-glue.h: $(top_srcdir)/introspection/nm-device-ethernet.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_ethernet --mode=glib-server --output=$@ $< +nm-device-infiniband-glue.h: $(top_srcdir)/introspection/nm-device-infiniband.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_infiniband --mode=glib-server --output=$@ $< + nm-device-wifi-glue.h: $(top_srcdir)/introspection/nm-device-wifi.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_wifi --mode=glib-server --output=$@ $< @@ -1918,6 +2024,12 @@ nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml nm-device-olpc-mesh-glue.h: $(top_srcdir)/introspection/nm-device-olpc-mesh.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_olpc_mesh --mode=glib-server --output=$@ $< +nm-device-bond-glue.h: $(top_srcdir)/introspection/nm-device-bond.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_bond --mode=glib-server --output=$@ $< + +nm-device-vlan-glue.h: $(top_srcdir)/introspection/nm-device-vlan.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_vlan --mode=glib-server --output=$@ $< + nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $< @@ -1935,6 +2047,7 @@ nm-dhcp6-config-glue.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml nm-device-modem-glue.h: $(top_srcdir)/introspection/nm-device-modem.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_modem --mode=glib-server --output=$@ $< + -DARP_DEBUG install-data-hook: $(mkinstalldirs) -m 0700 $(DESTDIR)$(rundir) $(mkinstalldirs) -m 0700 $(DESTDIR)$(statedir) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 451de6d0..6c2c0446 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -32,8 +32,6 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-device.h" -#include "nm-device-wifi.h" -#include "nm-device-ethernet.h" #include "nm-dbus-manager.h" #include "nm-dispatcher-action.h" #include "nm-dbus-glib-types.h" @@ -159,22 +157,11 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix) return (guint32) htonl (netmask); } -char * -nm_ether_ntop (const struct ether_addr *mac) -{ - /* we like leading zeros and all-caps, instead - * of what glibc's ether_ntop() gives us - */ - return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", - mac->ether_addr_octet[0], mac->ether_addr_octet[1], - mac->ether_addr_octet[2], mac->ether_addr_octet[3], - mac->ether_addr_octet[4], mac->ether_addr_octet[5]); -} - void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) { int i, j; + gboolean setting_never_default; if (!setting) return; /* Defaults are just fine */ @@ -264,8 +251,14 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) nm_ip4_config_add_route (ip4_config, setting_route); } - if (nm_setting_ip4_config_get_never_default (setting)) - nm_ip4_config_set_never_default (ip4_config, TRUE); + setting_never_default = nm_setting_ip4_config_get_never_default (setting); + + if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) + nm_ip4_config_set_never_default (ip4_config, setting_never_default); + else { + if (setting_never_default) + nm_ip4_config_set_never_default (ip4_config, TRUE); + } } static inline gboolean @@ -862,7 +855,7 @@ nm_utils_do_sysctl (const char *path, const char *value) gboolean nm_utils_get_proc_sys_net_value (const char *path, const char *iface, - guint32 *out_value) + gint32 *out_value) { GError *error = NULL; char *contents = NULL; @@ -878,8 +871,8 @@ nm_utils_get_proc_sys_net_value (const char *path, } else { errno = 0; tmp = strtol (contents, NULL, 10); - if ((errno == 0) && (tmp == 0 || tmp == 1)) { - *out_value = (guint32) tmp; + if (errno == 0) { + *out_value = (gint32) tmp; success = TRUE; } g_free (contents); @@ -888,6 +881,28 @@ nm_utils_get_proc_sys_net_value (const char *path, return success; } +gboolean +nm_utils_get_proc_sys_net_value_with_bounds (const char *path, + const char *iface, + gint32 *out_value, + gint32 valid_min, + gint32 valid_max) +{ + gboolean result; + gint32 val; + + result = nm_utils_get_proc_sys_net_value (path, iface, &val); + + if (result) { + if (val >= valid_min && val <= valid_max) + *out_value = val; + else + result = FALSE; + } + + return result; +} + static char * get_new_connection_name (const GSList *existing, const char *format, @@ -955,7 +970,7 @@ nm_utils_complete_generic (NMConnection *connection, const char *method; char *id, *uuid; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if (!s_con) { s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, NM_SETTING (s_con)); @@ -976,7 +991,7 @@ nm_utils_complete_generic (NMConnection *connection, } /* Add an 'auto' IPv4 connection if present */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) { s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); @@ -989,7 +1004,7 @@ nm_utils_complete_generic (NMConnection *connection, } /* Add an 'auto' IPv6 setting if allowed and not preset */ - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!s_ip6 && default_enable_ipv6) { s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); @@ -1002,3 +1017,26 @@ nm_utils_complete_generic (NMConnection *connection, } } +gboolean +nm_utils_is_uuid (const char *str) +{ + const char *p = str; + int num_dashes = 0; + + while (*p) { + if (*p == '-') + num_dashes++; + else if (!isxdigit (*p)) + return FALSE; + p++; + } + + return (num_dashes == 4) && (p - str == 36); +} + +char * +nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id) +{ + return g_strdup_printf ("%s.%d", parent_iface, vlan_id); +} + diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 1bf741ed..2474f654 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2010 Red Hat, Inc. + * Copyright (C) 2004 - 2011 Red Hat, Inc. * Copyright (C) 2005 - 2008 Novell, Inc. */ @@ -37,8 +37,6 @@ gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr); int nm_spawn_process (const char *args); -char *nm_ether_ntop (const struct ether_addr *mac); - void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting); void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting); @@ -85,7 +83,13 @@ gboolean nm_utils_do_sysctl (const char *path, const char *value); gboolean nm_utils_get_proc_sys_net_value (const char *path, const char *iface, - guint32 *out_value); + gint32 *out_value); + +gboolean nm_utils_get_proc_sys_net_value_with_bounds (const char *path, + const char *iface, + gint32 *out_value, + gint32 valid_min, + gint32 valid_max); void nm_utils_complete_generic (NMConnection *connection, const char *ctype, @@ -94,4 +98,8 @@ void nm_utils_complete_generic (NMConnection *connection, const char *preferred, gboolean default_enable_ipv6); +gboolean nm_utils_is_uuid (const char *str); + +char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id); + #endif /* NETWORK_MANAGER_UTILS_H */ diff --git a/src/backends/Makefile.am b/src/backends/Makefile.am index c0780d0b..11a154a0 100644 --- a/src/backends/Makefile.am +++ b/src/backends/Makefile.am @@ -2,13 +2,16 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/src \ -I${top_srcdir}/libnm-util noinst_LTLIBRARIES = libnmbackend.la -libnmbackend_la_SOURCES = NetworkManagerGeneric.c \ - NetworkManagerGeneric.h +libnmbackend_la_SOURCES = \ + NetworkManagerGeneric.c \ + NetworkManagerGeneric.h \ + nm-backend.h libnmbackend_la_LIBADD = diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in index 87d3df4e..9c6f7d0c 100644 --- a/src/backends/Makefile.in +++ b/src/backends/Makefile.in @@ -74,7 +74,7 @@ libnmbackend_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__libnmbackend_la_SOURCES_DIST = NetworkManagerGeneric.c \ - NetworkManagerGeneric.h NetworkManagerRedHat.c \ + NetworkManagerGeneric.h nm-backend.h NetworkManagerRedHat.c \ NetworkManagerSuSE.c NetworkManagerGentoo.c \ NetworkManagerDebian.c NetworkManagerSlackware.c \ NetworkManagerArch.c NetworkManagerPaldo.c \ @@ -187,6 +187,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -241,11 +243,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -256,6 +262,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -295,6 +302,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -362,16 +371,17 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/src \ -I${top_srcdir}/libnm-util noinst_LTLIBRARIES = libnmbackend.la libnmbackend_la_SOURCES = NetworkManagerGeneric.c \ - NetworkManagerGeneric.h $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) \ - $(am__append_6) $(am__append_7) $(am__append_8) \ - $(am__append_10) $(am__append_11) $(am__append_12) \ - $(am__append_13) + NetworkManagerGeneric.h nm-backend.h $(am__append_1) \ + $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_5) $(am__append_6) $(am__append_7) \ + $(am__append_8) $(am__append_10) $(am__append_11) \ + $(am__append_12) $(am__append_13) libnmbackend_la_LIBADD = $(am__append_9) \ $(top_builddir)/src/logging/libnm-logging.la $(LIBNL_LIBS) \ $(DBUS_LIBS) $(GLIB_LIBS) diff --git a/src/backends/NetworkManagerArch.c b/src/backends/NetworkManagerArch.c index c70e2459..7e25ee37 100644 --- a/src/backends/NetworkManagerArch.c +++ b/src/backends/NetworkManagerArch.c @@ -28,43 +28,33 @@ * * (C) Copyright 2004 Tom Parker * (C) Copyright 2004 Matthew Garrett - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { - /* Check if the daemon was already running - do not start a new instance */ + /* Make glibc/nscd aware of any changes to the resolv.conf file by + * restarting nscd; check if the daemon was already running - do not + * start a new instance + */ if (g_file_test("/var/run/daemons/nscd", G_FILE_TEST_EXISTS)) nm_spawn_process ("/etc/rc.d/nscd restart"); } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerDebian.c b/src/backends/NetworkManagerDebian.c index 37eb6457..ed29dd3a 100644 --- a/src/backends/NetworkManagerDebian.c +++ b/src/backends/NetworkManagerDebian.c @@ -21,29 +21,18 @@ * * (C) Copyright 2004 Tom Parker * (C) Copyright 2004 Matthew Garrett - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { /* ifupdown isn't always installed (bgo #625427) */ if (g_file_test ("/sbin/ifup", G_FILE_TEST_EXISTS)) @@ -52,18 +41,17 @@ void nm_system_enable_loopback (void) nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Invalidate the nscd host cache since we changed resolv.conf */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerExherbo.c b/src/backends/NetworkManagerExherbo.c index d7e24cf6..d0277896 100644 --- a/src/backends/NetworkManagerExherbo.c +++ b/src/backends/NetworkManagerExherbo.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2004 Dan Willemsen * (C) Copyright 2004 Robert Paskowitz */ @@ -27,38 +27,28 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. Only restart if already running. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Make glibc/nscd aware of any changes to the resolv.conf file by + * restarting nscd. Only restart if already running. + */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerFrugalware.c b/src/backends/NetworkManagerFrugalware.c index dfe62921..301751e9 100644 --- a/src/backends/NetworkManagerFrugalware.c +++ b/src/backends/NetworkManagerFrugalware.c @@ -23,36 +23,21 @@ * (C) Copyright 2006 Alex Smith */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "nm-system.h" - /* Provided by the frugalwareutils package on Frugalware */ #include <libfwnetconfig.h> -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { fwnet_loup (); } - -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { /* I'm not running nscd */ } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 89b8a46d..eae6f733 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 - 2010 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2006 Timothee Lecomte <timothee.lecomte@ens.fr> */ @@ -113,3 +113,65 @@ void nm_generic_update_dns (void) { } +/* + * nm_generic_ipv6_use_tempaddr + * + * Get net.ipv6.conf.default.use_tempaddr value from /etc/sysctl.conf or + * /lib/sysctl.d/sysctl.conf + * + */ +int nm_generic_ipv6_use_tempaddr (void) +{ + char *contents = NULL; + gsize len = 0; + const char *group_name = "[forged_group]\n"; + char *sysctl_data = NULL; + GKeyFile *keyfile; + GError *error = NULL; + int tmp, ret = -1; + + /* Read file contents to a string. */ + if (!g_file_get_contents ("/etc/sysctl.conf", &contents, &len, NULL)) + if (!g_file_get_contents ("/lib/sysctl.d/sysctl.conf", &contents, &len, NULL)) + return -1; + + /* Prepend a group so that we can use GKeyFile parser. */ + sysctl_data = g_strdup_printf ("%s%s", group_name, contents); + + keyfile = g_key_file_new (); + if (keyfile == NULL) + goto done; + + if (!g_key_file_load_from_data (keyfile, sysctl_data, len + strlen (group_name), G_KEY_FILE_NONE, NULL)) + goto done; + + tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error); + if (error == NULL) + ret = tmp; + +done: + g_free (contents); + g_free (sysctl_data); + g_clear_error (&error); + g_key_file_free (keyfile); + + return ret; +} + +#ifdef TARGET_GENERIC +void nm_backend_enable_loopback (void) +{ + nm_generic_enable_loopback (); +} + +void nm_backend_update_dns (void) +{ + nm_generic_update_dns (); +} + +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} +#endif + diff --git a/src/backends/NetworkManagerGeneric.h b/src/backends/NetworkManagerGeneric.h index 0a0a88a2..3d4017e4 100644 --- a/src/backends/NetworkManagerGeneric.h +++ b/src/backends/NetworkManagerGeneric.h @@ -18,13 +18,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. */ -#ifndef NETWORK_MANAGER_GENERIC_H -#define NETWORK_MANAGER_GENERIC_H +#ifndef NM_GENERIC_H +#define NM_GENERIC_H -void nm_generic_enable_loopback (void); -void nm_generic_update_dns (void); +#include "nm-backend.h" -#endif +void nm_generic_enable_loopback (void); +void nm_generic_update_dns (void); +int nm_generic_ipv6_use_tempaddr (void); + +#endif /* NM_GENERIC_H */ diff --git a/src/backends/NetworkManagerGentoo.c b/src/backends/NetworkManagerGentoo.c index e5b09384..7370645a 100644 --- a/src/backends/NetworkManagerGentoo.c +++ b/src/backends/NetworkManagerGentoo.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2004 Dan Willemsen * (C) Copyright 2004 Robert Paskowitz */ @@ -27,18 +27,12 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <gio/gio.h> +#include <glib.h> #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -#define BUFFER_SIZE 512 - static void openrc_start_lo_if_necessary() { /* No need to run net.lo if it is already running */ @@ -46,18 +40,11 @@ static void openrc_start_lo_if_necessary() nm_spawn_process ("/etc/init.d/net.lo start"); } -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { gchar *comm; - /* If anything goes wrong trying to open /proc/1/comm, we will assume - OpenRC. */ + /* If anything goes wrong trying to open /proc/1/comm, we will assume OpenRC */ if (!g_file_get_contents ("/proc/1/comm", &comm, NULL, NULL)) { nm_log_info (LOGD_CORE, "NetworkManager is running with OpenRC..."); openrc_start_lo_if_necessary (); @@ -77,18 +64,19 @@ void nm_system_enable_loopback (void) g_free (comm); } -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. Only restart if already running. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Make glibc/nscd aware of any changes to the resolv.conf file by + * restarting nscd. Only restart if already running. + */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerLinexa.c b/src/backends/NetworkManagerLinexa.c index 015aa17c..34fed3bb 100644 --- a/src/backends/NetworkManagerLinexa.c +++ b/src/backends/NetworkManagerLinexa.c @@ -21,46 +21,33 @@ * * (C) Copyright 2004 Tom Parker * (C) Copyright 2004 Matthew Garrett - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Invalidate the nscd host cache, if it exists, since we changed resolv.conf */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} diff --git a/src/backends/NetworkManagerMandriva.c b/src/backends/NetworkManagerMandriva.c index 8209ff4f..f059beb6 100644 --- a/src/backends/NetworkManagerMandriva.c +++ b/src/backends/NetworkManagerMandriva.c @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2008 Per Øyvind Karlsen */ @@ -25,37 +25,25 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Invalidate the nscd host cache, if it exists, since we changed resolv.conf */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE | G_FILE_TEST_IS_REGULAR)) { nm_spawn_process ("/etc/init.d/nscd condrestart"); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerPaldo.c b/src/backends/NetworkManagerPaldo.c index 0c67e5bd..2d01d857 100644 --- a/src/backends/NetworkManagerPaldo.c +++ b/src/backends/NetworkManagerPaldo.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2006 Jürg Billeter */ @@ -26,36 +26,26 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) +{ + /* Invalidate the nscd host cache, if it exists, since we changed resolv.conf */ + if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { + nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); + nm_spawn_process ("/usr/sbin/nscd -i hosts"); + } +} + +int nm_backend_ipv6_use_tempaddr (void) { - nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); - nm_spawn_process ("/usr/sbin/nscd -i hosts"); + return nm_generic_ipv6_use_tempaddr (); } diff --git a/src/backends/NetworkManagerPardus.c b/src/backends/NetworkManagerPardus.c index d952cf36..acfeaed3 100644 --- a/src/backends/NetworkManagerPardus.c +++ b/src/backends/NetworkManagerPardus.c @@ -16,7 +16,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 RedHat, Inc. + * (C) Copyright 2004 - 2012 RedHat, Inc. * (C) Copyright 2009 TUBITAK/UEKAE */ @@ -24,34 +24,19 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } +void nm_backend_update_dns (void) +{ +} -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. - * - */ -void nm_system_update_dns (void) +int nm_backend_ipv6_use_tempaddr (void) { - /* I'm not running nscd */ + return nm_generic_ipv6_use_tempaddr (); } diff --git a/src/backends/NetworkManagerRedHat.c b/src/backends/NetworkManagerRedHat.c index 954e58a8..c14eb837 100644 --- a/src/backends/NetworkManagerRedHat.c +++ b/src/backends/NetworkManagerRedHat.c @@ -16,44 +16,32 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) { + /* Invalidate the nscd host cache since we changed resolv.conf */ if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE | G_FILE_TEST_IS_REGULAR)) { nm_spawn_process ("/etc/init.d/nscd condrestart"); nm_spawn_process ("/usr/sbin/nscd -i hosts"); } } +int nm_backend_ipv6_use_tempaddr (void) +{ + return nm_generic_ipv6_use_tempaddr (); +} + diff --git a/src/backends/NetworkManagerSlackware.c b/src/backends/NetworkManagerSlackware.c index a35e1bb6..cdd2dfb0 100644 --- a/src/backends/NetworkManagerSlackware.c +++ b/src/backends/NetworkManagerSlackware.c @@ -16,7 +16,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 RedHat, Inc. + * (C) Copyright 2004 - 2012 RedHat, Inc. * (C) Copyright 2004 Narayan Newton */ @@ -24,34 +24,19 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } +void nm_backend_update_dns (void) +{ +} -/* - * nm_system_update_dns - * - * Make glibc/nscd aware of any changes to the resolv.conf file by - * restarting nscd. - * - */ -void nm_system_update_dns (void) +int nm_backend_ipv6_use_tempaddr (void) { - /* I'm not running nscd */ + return nm_generic_ipv6_use_tempaddr (); } diff --git a/src/backends/NetworkManagerSuSE.c b/src/backends/NetworkManagerSuSE.c index 6c8ec1a5..12618532 100644 --- a/src/backends/NetworkManagerSuSE.c +++ b/src/backends/NetworkManagerSuSE.c @@ -19,7 +19,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2004 - 2012 Red Hat, Inc. * (C) Copyright 2005-2006 SuSE GmbH */ @@ -27,36 +27,26 @@ #include <config.h> #endif -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - #include "NetworkManagerGeneric.h" -#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" -/* - * nm_system_enable_loopback - * - * Bring up the loopback interface - * - */ -void nm_system_enable_loopback (void) +void nm_backend_enable_loopback (void) { nm_generic_enable_loopback (); } -/* - * nm_system_update_dns - * - * Invalidate the nscd host cache, if it exists, since - * we changed resolv.conf. - * - */ -void nm_system_update_dns (void) +void nm_backend_update_dns (void) +{ + /* Invalidate the nscd host cache, if it exists, since we changed resolv.conf */ + if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) { + nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); + nm_spawn_process ("/usr/sbin/nscd -i hosts"); + } +} + +int nm_backend_ipv6_use_tempaddr (void) { - nm_log_info (LOGD_DNS, "Clearing nscd hosts cache."); - nm_spawn_process ("/usr/sbin/nscd -i hosts"); + return nm_generic_ipv6_use_tempaddr (); } diff --git a/src/backends/nm-backend.h b/src/backends/nm-backend.h new file mode 100644 index 00000000..17d1ff64 --- /dev/null +++ b/src/backends/nm-backend.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 - 2012 Red Hat, Inc. + */ + +#ifndef NM_BACKEND_H +#define NM_BACKEND_H + +/* Random disto-specific stuff */ + +void nm_backend_enable_loopback (void); +void nm_backend_update_dns (void); +int nm_backend_ipv6_use_tempaddr (void); + +#endif /* NM_BACKEND_H */ diff --git a/src/bluez-manager/Makefile.am b/src/bluez-manager/Makefile.am index 623c1060..10b32d25 100644 --- a/src/bluez-manager/Makefile.am +++ b/src/bluez-manager/Makefile.am @@ -1,10 +1,13 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ + -I${top_srcdir}/src/logging noinst_LTLIBRARIES = libbluez-manager.la @@ -29,7 +32,7 @@ libbluez_manager_la_CPPFLAGS = \ -DLOCALSTATEDIR=\"$(localstatedir)\" libbluez_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ diff --git a/src/bluez-manager/Makefile.in b/src/bluez-manager/Makefile.in index 9eb31c80..efb5ab4e 100644 --- a/src/bluez-manager/Makefile.in +++ b/src/bluez-manager/Makefile.in @@ -57,7 +57,7 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libbluez_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libbluez_manager_la_OBJECTS = \ @@ -144,6 +144,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -198,11 +200,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -213,6 +219,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -252,6 +259,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -318,10 +327,13 @@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ + -I${top_srcdir}/src/logging noinst_LTLIBRARIES = libbluez-manager.la libbluez_manager_la_SOURCES = \ @@ -345,7 +357,7 @@ libbluez_manager_la_CPPFLAGS = \ -DLOCALSTATEDIR=\"$(localstatedir)\" libbluez_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ diff --git a/src/bluez-manager/nm-bluez-manager.c b/src/bluez-manager/nm-bluez-manager.c index 5381151e..942d0f34 100644 --- a/src/bluez-manager/nm-bluez-manager.c +++ b/src/bluez-manager/nm-bluez-manager.c @@ -181,8 +181,11 @@ default_adapter_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) if (!dbus_g_proxy_end_call (proxy, call, &err, DBUS_TYPE_G_OBJECT_PATH, &default_adapter, G_TYPE_INVALID)) { - nm_log_warn (LOGD_BT, "bluez error getting default adapter: %s", - err && err->message ? err->message : "(unknown)"); + /* Ignore "No such adapter" errors; just means bluetooth isn't active */ + if (!dbus_g_error_has_name (err, "org.bluez.Error.NoSuchAdapter")) { + nm_log_warn (LOGD_BT, "bluez error getting default adapter: %s", + err && err->message ? err->message : "(unknown)"); + } g_error_free (err); return; } diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am index 14ddde0b..ce34c416 100644 --- a/src/dhcp-manager/Makefile.am +++ b/src/dhcp-manager/Makefile.am @@ -3,9 +3,12 @@ SUBDIRS=. tests INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la @@ -29,7 +32,6 @@ libdhcp_dhclient_la_CPPFLAGS = \ -DDHCLIENT_V$(DHCLIENT_VERSION) libdhcp_dhclient_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ @@ -55,7 +57,6 @@ libdhcp_manager_la_CPPFLAGS = \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" libdhcp_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/libdhcp-dhclient.la \ $(DBUS_LIBS) \ diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in index 2d90f043..4c389562 100644 --- a/src/dhcp-manager/Makefile.in +++ b/src/dhcp-manager/Makefile.in @@ -57,7 +57,6 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libdhcp_dhclient_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -69,7 +68,6 @@ AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent libdhcp_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/libdhcp-dhclient.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -192,6 +190,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -246,11 +246,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -261,6 +265,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -300,6 +305,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -367,9 +374,12 @@ SUBDIRS = . tests INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la @@ -392,7 +402,6 @@ libdhcp_dhclient_la_CPPFLAGS = \ -DDHCLIENT_V$(DHCLIENT_VERSION) libdhcp_dhclient_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ @@ -418,7 +427,6 @@ libdhcp_manager_la_CPPFLAGS = \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" libdhcp_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/libdhcp-dhclient.la \ $(DBUS_LIBS) \ diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index caf90f11..ab49a765 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -78,8 +78,8 @@ nm_dhcp_dhclient_create_config (const char *interface, /* Override config file "dhcp-client-id" and use one from the * connection. */ - if ( s_ip4 - && nm_setting_ip4_config_get_dhcp_client_id (s_ip4) + if ( s_ip4 + && nm_setting_ip4_config_get_dhcp_client_id (s_ip4) && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) continue; diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index e65f6935..1af1b163 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -44,8 +44,6 @@ #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - GQuark nm_dhcp_manager_error_quark (void) { @@ -57,22 +55,6 @@ nm_dhcp_manager_error_quark (void) return ret; } -GType -nm_dhcp_manager_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - ENUM_ENTRY (NM_DHCP_MANAGER_ERROR_BAD_CLIENT, "BadClient"), - ENUM_ENTRY (NM_DHCP_MANAGER_ERROR_INTERNAL, "InternalError"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMDhcpManagerError", values); - } - return etype; -} - #define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client" #define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index 9d83d096..d585c142 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -33,16 +33,14 @@ #include "nm-dhcp4-config.h" #include "nm-hostname-provider.h" -enum { - NM_DHCP_MANAGER_ERROR_BAD_CLIENT = 0, - NM_DHCP_MANAGER_ERROR_INTERNAL = 1, -}; +typedef enum { + NM_DHCP_MANAGER_ERROR_BAD_CLIENT = 0, /*< nick=BadClient >*/ + NM_DHCP_MANAGER_ERROR_INTERNAL = 1, /*< nick=InternalError >*/ +} NMDHCPManagerError; #define NM_DHCP_MANAGER_ERROR (nm_dhcp_manager_error_quark ()) -#define NN_TYPE_DHCP_MANAGER_ERROR (nm_dhcp_manager_error_get_type ()) GQuark nm_dhcp_manager_error_quark (void); -GType nm_dhcp_manager_error_get_type (void); #define NM_TYPE_DHCP_MANAGER (nm_dhcp_manager_get_type ()) diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am index b075fd68..1feade86 100644 --- a/src/dhcp-manager/tests/Makefile.am +++ b/src/dhcp-manager/tests/Makefile.am @@ -1,6 +1,8 @@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I$(top_srcdir)/src/dhcp-manager noinst_PROGRAMS = test-dhcp-dhclient diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in index 5c4c23a5..20422cdb 100644 --- a/src/dhcp-manager/tests/Makefile.in +++ b/src/dhcp-manager/tests/Makefile.in @@ -142,6 +142,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -196,11 +198,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -211,6 +217,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -250,6 +257,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -315,7 +324,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I$(top_srcdir)/src/dhcp-manager diff --git a/src/dns-manager/Makefile.am b/src/dns-manager/Makefile.am index b51f667b..331f85c4 100644 --- a/src/dns-manager/Makefile.am +++ b/src/dns-manager/Makefile.am @@ -1,8 +1,10 @@ INCLUDES = \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/include + -I${top_srcdir}/include \ + -I${top_builddir}/include noinst_LTLIBRARIES = libdns-manager.la diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in index 571f585b..c9b8b0b3 100644 --- a/src/dns-manager/Makefile.in +++ b/src/dns-manager/Makefile.in @@ -145,6 +145,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -199,11 +201,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -214,6 +220,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -253,6 +260,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -319,8 +328,10 @@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/include + -I${top_srcdir}/include \ + -I${top_builddir}/include noinst_LTLIBRARIES = libdns-manager.la libdns_manager_la_SOURCES = \ diff --git a/src/dns-manager/nm-dns-bind.c b/src/dns-manager/nm-dns-bind.c index 55fce030..1a3243be 100644 --- a/src/dns-manager/nm-dns-bind.c +++ b/src/dns-manager/nm-dns-bind.c @@ -413,7 +413,7 @@ update (NMDnsPlugin *plugin, g_clear_error (&error); goto out; } - ignored = chmod (CONFFILE, 0600); + ignored = chmod (CONFFILE, 0644); nm_log_dbg (LOGD_DNS, "BIND local caching DNS configuration:"); nm_log_dbg (LOGD_DNS, "%s", conf->str); diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c index a602c54f..8e216f4d 100644 --- a/src/dns-manager/nm-dns-dnsmasq.c +++ b/src/dns-manager/nm-dns-dnsmasq.c @@ -294,7 +294,7 @@ update (NMDnsPlugin *plugin, g_clear_error (&error); goto out; } - ignored = chmod (CONFFILE, 0600); + ignored = chmod (CONFFILE, 0644); nm_log_dbg (LOGD_DNS, "dnsmasq local caching DNS configuration:"); nm_log_dbg (LOGD_DNS, "%s", conf->str); @@ -302,13 +302,14 @@ update (NMDnsPlugin *plugin, argv[0] = find_dnsmasq (); argv[1] = "--no-resolv"; /* Use only commandline */ argv[2] = "--keep-in-foreground"; - argv[3] = "--strict-order"; + argv[3] = "--no-hosts"; /* don't use /etc/hosts to resolve */ argv[4] = "--bind-interfaces"; argv[5] = "--pid-file=" PIDFILE; argv[6] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */ argv[7] = "--conf-file=" CONFFILE; argv[8] = "--cache-size=400"; - argv[9] = NULL; + argv[9] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */ + argv[10] = NULL; /* And finally spawn dnsmasq */ pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq"); diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index ddfd47c8..6272e374 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -40,7 +40,7 @@ #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "nm-logging.h" -#include "nm-system.h" +#include "backends/nm-backend.h" #include "NetworkManagerUtils.h" #include "nm-dns-plugin.h" @@ -752,7 +752,7 @@ update_dns (NMDnsManager *self, success = update_resolv_conf (domain, searches, nameservers, iface, error); if (success) - nm_system_update_dns (); + nm_backend_update_dns (); if (searches) g_strfreev (searches); diff --git a/src/dnsmasq-manager/Makefile.in b/src/dnsmasq-manager/Makefile.in index 5b1328bf..bb1e56c0 100644 --- a/src/dnsmasq-manager/Makefile.in +++ b/src/dnsmasq-manager/Makefile.in @@ -141,6 +141,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -195,11 +197,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -210,6 +216,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -249,6 +256,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/firewall-manager/Makefile.am b/src/firewall-manager/Makefile.am new file mode 100644 index 00000000..2cfe32d0 --- /dev/null +++ b/src/firewall-manager/Makefile.am @@ -0,0 +1,23 @@ +INCLUDES = \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util + +noinst_LTLIBRARIES = libfirewall-manager.la + +libfirewall_manager_la_SOURCES = \ + nm-firewall-manager.h \ + nm-firewall-manager.c + +libfirewall_manager_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + -DNM_PKGDATADIR=\"$(pkgdatadir)\" \ + -DNM_LOCALSTATEDIR=\"$(localstatedir)\" + +libfirewall_manager_la_LIBADD = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + diff --git a/src/firewall-manager/Makefile.in b/src/firewall-manager/Makefile.in new file mode 100644 index 00000000..821fa838 --- /dev/null +++ b/src/firewall-manager/Makefile.in @@ -0,0 +1,641 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/firewall-manager +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libfirewall_manager_la_DEPENDENCIES = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libfirewall_manager_la_OBJECTS = \ + libfirewall_manager_la-nm-firewall-manager.lo +libfirewall_manager_la_OBJECTS = $(am_libfirewall_manager_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libfirewall_manager_la_SOURCES) +DIST_SOURCES = $(libfirewall_manager_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +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@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util + +noinst_LTLIBRARIES = libfirewall-manager.la +libfirewall_manager_la_SOURCES = \ + nm-firewall-manager.h \ + nm-firewall-manager.c + +libfirewall_manager_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + -DNM_PKGDATADIR=\"$(pkgdatadir)\" \ + -DNM_LOCALSTATEDIR=\"$(localstatedir)\" + +libfirewall_manager_la_LIBADD = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/firewall-manager/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/firewall-manager/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libfirewall-manager.la: $(libfirewall_manager_la_OBJECTS) $(libfirewall_manager_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libfirewall_manager_la_OBJECTS) $(libfirewall_manager_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfirewall_manager_la-nm-firewall-manager.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libfirewall_manager_la-nm-firewall-manager.lo: nm-firewall-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfirewall_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libfirewall_manager_la-nm-firewall-manager.lo -MD -MP -MF $(DEPDIR)/libfirewall_manager_la-nm-firewall-manager.Tpo -c -o libfirewall_manager_la-nm-firewall-manager.lo `test -f 'nm-firewall-manager.c' || echo '$(srcdir)/'`nm-firewall-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfirewall_manager_la-nm-firewall-manager.Tpo $(DEPDIR)/libfirewall_manager_la-nm-firewall-manager.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-firewall-manager.c' object='libfirewall_manager_la-nm-firewall-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfirewall_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libfirewall_manager_la-nm-firewall-manager.lo `test -f 'nm-firewall-manager.c' || echo '$(srcdir)/'`nm-firewall-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c new file mode 100644 index 00000000..c19be5e8 --- /dev/null +++ b/src/firewall-manager/nm-firewall-manager.c @@ -0,0 +1,327 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include <string.h> +#include <glib.h> +#include <dbus/dbus.h> + +#include "nm-firewall-manager.h" +#include "nm-dbus-manager.h" +#include "nm-logging.h" + +#define NM_FIREWALL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_FIREWALL_MANAGER, \ + NMFirewallManagerPrivate)) + +G_DEFINE_TYPE (NMFirewallManager, nm_firewall_manager, G_TYPE_OBJECT) + +/* Properties */ +enum { + PROP_0 = 0, + PROP_AVAILABLE, + LAST_PROP +}; + +typedef struct { + NMDBusManager * dbus_mgr; + guint name_owner_id; + DBusGProxy * proxy; + gboolean running; + gboolean disposed; +} NMFirewallManagerPrivate; + +enum { + STARTED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/********************************************************************/ + +typedef struct { + char *iface; + FwAddToZoneFunc callback; + gpointer user_data; +} CBInfo; + +static void +cb_info_free (CBInfo *info) +{ + g_return_if_fail (info != NULL); + g_free (info->iface); + g_free (info); +} + +static void +add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + CBInfo *info = user_data; + GError *error = NULL; + char *zone = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_STRING, &zone, + G_TYPE_INVALID)) { + g_assert (error); + nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed: (%d) %s", + info->iface, error->code, error->message); + } + + info->callback (error, info->user_data); + + g_free (zone); + g_clear_error (&error); +} + +gpointer +nm_firewall_manager_add_or_change_zone (NMFirewallManager *self, + const char *iface, + const char *zone, + gboolean add, /* TRUE == add, FALSE == change */ + FwAddToZoneFunc callback, + gpointer user_data) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + CBInfo *info; + + if (priv->running == FALSE) { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface); + callback (NULL, user_data); + return NULL; + } + + info = g_malloc0 (sizeof (*info)); + info->iface = g_strdup (iface); + info->callback = callback; + info->user_data = user_data; + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s", iface, add ? "add" : "change", zone); + return dbus_g_proxy_begin_call_with_timeout (priv->proxy, + add ? "addInterface" : "changeZone", + add_or_change_cb, + info, + (GDestroyNotify) cb_info_free, + 10000, /* timeout */ + G_TYPE_STRING, zone ? zone : "", + G_TYPE_STRING, iface, + G_TYPE_INVALID); +} + +static void +remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + CBInfo *info = user_data; + GError *error = NULL; + char * zone = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_STRING, &zone, + G_TYPE_INVALID)) { + g_assert (error); + nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed: (%d) %s", + info->iface, error->code, error->message); + } + + g_free (zone); + g_clear_error (&error); +} + +gpointer +nm_firewall_manager_remove_from_zone (NMFirewallManager *self, + const char *iface, + const char *zone) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + CBInfo *info; + + if (priv->running == FALSE) { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface); + return NULL; + } + + info = g_malloc0 (sizeof (*info)); + info->iface = g_strdup (iface); + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s", iface, zone ); + return dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "removeInterface", + remove_cb, + info, + (GDestroyNotify) cb_info_free, + 10000, /* timeout */ + G_TYPE_STRING, zone ? zone : "", + G_TYPE_STRING, iface, + G_TYPE_INVALID); +} + +void nm_firewall_manager_cancel_call (NMFirewallManager *self, gpointer call) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_FIREWALL_MANAGER (self)); + dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy, + (DBusGProxyCall *) call); +} + +static void +set_running (NMFirewallManager *self, gboolean now_running) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + gboolean old_running = priv->running; + + priv->running = now_running; + if (old_running != priv->running) + g_object_notify (G_OBJECT (self), NM_FIREWALL_MANAGER_AVAILABLE); +} + +static void +name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMFirewallManager *self = NM_FIREWALL_MANAGER (user_data); + gboolean old_owner_good = (old_owner && strlen (old_owner)); + gboolean new_owner_good = (new_owner && strlen (new_owner)); + + /* We only care about the firewall here */ + if (strcmp (FIREWALL_DBUS_SERVICE, name) != 0) + return; + + if (!old_owner_good && new_owner_good) { + nm_log_dbg (LOGD_FIREWALL, "firewall started"); + set_running (self, TRUE); + g_signal_emit (self, signals[STARTED], 0); + } else if (old_owner_good && !new_owner_good) { + nm_log_dbg (LOGD_FIREWALL, "firewall stopped"); + set_running (self, FALSE); + } +} + +/*******************************************************************/ + +NMFirewallManager * +nm_firewall_manager_get (void) +{ + static NMFirewallManager *singleton = NULL; + + if (!singleton) + singleton = NM_FIREWALL_MANAGER (g_object_new (NM_TYPE_FIREWALL_MANAGER, NULL)); + else + g_object_ref (singleton); + + g_assert (singleton); + return singleton; +} + +static void +nm_firewall_manager_init (NMFirewallManager * self) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + DBusGConnection *bus; + + priv->dbus_mgr = nm_dbus_manager_get (); + priv->name_owner_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed), + self); + priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, FIREWALL_DBUS_SERVICE); + nm_log_dbg (LOGD_FIREWALL, "firewall %s running", priv->running ? "is" : "is not" ); + + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (bus, + FIREWALL_DBUS_SERVICE, + FIREWALL_DBUS_PATH, + FIREWALL_DBUS_INTERFACE_ZONE); +} + +static void +set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static void +get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_AVAILABLE: + g_value_set_boolean (value, NM_FIREWALL_MANAGER_GET_PRIVATE (object)->running); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (object); + + if (priv->disposed) + goto out; + priv->disposed = TRUE; + + if (priv->dbus_mgr) { + if (priv->name_owner_id) + g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); + g_object_unref (G_OBJECT (priv->dbus_mgr)); + } + + if (priv->proxy) + g_object_unref (priv->proxy); + +out: + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_firewall_manager_parent_class)->dispose (object); +} + +static void +nm_firewall_manager_class_init (NMFirewallManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMFirewallManagerPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + g_object_class_install_property (object_class, PROP_AVAILABLE, + g_param_spec_boolean (NM_FIREWALL_MANAGER_AVAILABLE, + "Available", + "Available", + FALSE, + G_PARAM_READABLE)); + + signals[STARTED] = + g_signal_new ("started", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMFirewallManagerClass, started), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/firewall-manager/nm-firewall-manager.h new file mode 100644 index 00000000..a77984e3 --- /dev/null +++ b/src/firewall-manager/nm-firewall-manager.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef NM_FIREWALL_MANAGER_H +#define NM_FIREWALL_MANAGER_H + +#include <glib-object.h> +#include <dbus/dbus-glib.h> + +#define FIREWALL_DBUS_SERVICE "org.fedoraproject.FirewallD1" +#define FIREWALL_DBUS_PATH "/org/fedoraproject/FirewallD1" +#define FIREWALL_DBUS_INTERFACE "org.fedoraproject.FirewallD1" +#define FIREWALL_DBUS_INTERFACE_ZONE "org.fedoraproject.FirewallD1.zone" + + +G_BEGIN_DECLS + +#define NM_TYPE_FIREWALL_MANAGER (nm_firewall_manager_get_type ()) +#define NM_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManager)) +#define NM_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) +#define NM_IS_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_FIREWALL_MANAGER)) +#define NM_IS_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FIREWALL_MANAGER)) +#define NM_FIREWALL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) + +#define NM_FIREWALL_MANAGER_AVAILABLE "available" + +typedef struct { + GObject parent; +} NMFirewallManager; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*started) (NMFirewallManager *manager); +} NMFirewallManagerClass; + +GType nm_firewall_manager_get_type (void); + +NMFirewallManager *nm_firewall_manager_get (void); + +typedef void (*FwAddToZoneFunc) (GError *error, gpointer user_data); + +gpointer nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr, + const char *iface, + const char *zone, + gboolean add, + FwAddToZoneFunc callback, + gpointer user_data); +gpointer nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr, + const char *iface, + const char *zone); + +void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, gpointer fw_call); + +#endif /* NM_FIREWALL_MANAGER_H */ diff --git a/src/generated/Makefile.am b/src/generated/Makefile.am new file mode 100644 index 00000000..b7f13b88 --- /dev/null +++ b/src/generated/Makefile.am @@ -0,0 +1,77 @@ +include $(GLIB_MAKEFILE) + +noinst_LTLIBRARIES = libnm-generated.la + +libnm_generated_la_SOURCES = \ + nm-enum-types.c \ + nm-enum-types.h \ + nm-marshal.c \ + nm-marshal.h + +nm_daemon_all_sources = \ + $(top_srcdir)/src/*.[ch] \ + $(top_srcdir)/src/logging/*.[ch] \ + $(top_srcdir)/src/dns-manager/*.[ch] \ + $(top_srcdir)/src/vpn-manager/*.[ch] \ + $(top_srcdir)/src/dhcp-manager/*.[ch] \ + $(top_srcdir)/src/ip6-manager/*.[ch] \ + $(top_srcdir)/src/supplicant-manager/*.[ch] \ + $(top_srcdir)/src/backends/*.[ch] \ + $(top_srcdir)/src/ppp-manager/*.[ch] \ + $(top_srcdir)/src/dnsmasq-manager/*.[ch] \ + $(top_srcdir)/src/modem-manager/*.[ch] \ + $(top_srcdir)/src/bluez-manager/*.[ch] \ + $(top_srcdir)/src/firewall-manager/*.[ch] \ + $(top_srcdir)/src/settings/*.[ch] + +if WITH_WIMAX +nm_daemon_all_sources += $(top_srcdir)/src/wimax/*.[ch] +endif + +nm_daemon_sources = \ + $(filter-out %-glue.h %-bindings.h, $(wildcard $(nm_daemon_all_sources))) + +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c +nm_enum_types_sources = $(nm_daemon_sources) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM + +GLIB_GENERATED += nm-marshal.h nm-marshal.c +nm_marshal_sources = $(nm_daemon_sources) + +INCLUDES = \ + -I${top_srcdir}/include \ + -I${top_builddir}/include \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/dns-manager \ + -I${top_srcdir}/src/vpn-manager \ + -I${top_srcdir}/src/dhcp-manager \ + -I${top_srcdir}/src/ip6-manager \ + -I${top_srcdir}/src/supplicant-manager \ + -I${top_srcdir}/src/backends \ + -I${top_srcdir}/src/ppp-manager \ + -I${top_srcdir}/src/dnsmasq-manager \ + -I${top_srcdir}/src/modem-manager \ + -I$(top_srcdir)/src/bluez-manager \ + -I$(top_srcdir)/src/firewall-manager \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/src/wifi \ + -I$(top_srcdir)/src/wimax \ + -I$(top_srcdir)/libnm-util + +libnm_generated_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(SYSTEMD_CFLAGS) \ + $(IWMX_SDK_CFLAGS) + +libnm_generated_la_LIBADD = \ + $(GLIB_LIBS) + +BUILT_SOURCES = $(GLIB_GENERATED) + diff --git a/src/generated/Makefile.in b/src/generated/Makefile.in new file mode 100644 index 00000000..85a346be --- /dev/null +++ b/src/generated/Makefile.in @@ -0,0 +1,697 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WITH_WIMAX_TRUE@am__append_1 = $(top_srcdir)/src/wimax/*.[ch] +subdir = src/generated +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libnm_generated_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libnm_generated_la_OBJECTS = libnm_generated_la-nm-enum-types.lo \ + libnm_generated_la-nm-marshal.lo +libnm_generated_la_OBJECTS = $(am_libnm_generated_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libnm_generated_la_SOURCES) +DIST_SOURCES = $(libnm_generated_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +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@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libnm-generated.la +libnm_generated_la_SOURCES = \ + nm-enum-types.c \ + nm-enum-types.h \ + nm-marshal.c \ + nm-marshal.h + +nm_daemon_all_sources = $(top_srcdir)/src/*.[ch] \ + $(top_srcdir)/src/logging/*.[ch] \ + $(top_srcdir)/src/dns-manager/*.[ch] \ + $(top_srcdir)/src/vpn-manager/*.[ch] \ + $(top_srcdir)/src/dhcp-manager/*.[ch] \ + $(top_srcdir)/src/ip6-manager/*.[ch] \ + $(top_srcdir)/src/supplicant-manager/*.[ch] \ + $(top_srcdir)/src/backends/*.[ch] \ + $(top_srcdir)/src/ppp-manager/*.[ch] \ + $(top_srcdir)/src/dnsmasq-manager/*.[ch] \ + $(top_srcdir)/src/modem-manager/*.[ch] \ + $(top_srcdir)/src/bluez-manager/*.[ch] \ + $(top_srcdir)/src/firewall-manager/*.[ch] \ + $(top_srcdir)/src/settings/*.[ch] $(am__append_1) +nm_daemon_sources = \ + $(filter-out %-glue.h %-bindings.h, $(wildcard $(nm_daemon_all_sources))) + +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c nm-marshal.h \ + nm-marshal.c +nm_enum_types_sources = $(nm_daemon_sources) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_marshal_sources = $(nm_daemon_sources) +INCLUDES = \ + -I${top_srcdir}/include \ + -I${top_builddir}/include \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/dns-manager \ + -I${top_srcdir}/src/vpn-manager \ + -I${top_srcdir}/src/dhcp-manager \ + -I${top_srcdir}/src/ip6-manager \ + -I${top_srcdir}/src/supplicant-manager \ + -I${top_srcdir}/src/backends \ + -I${top_srcdir}/src/ppp-manager \ + -I${top_srcdir}/src/dnsmasq-manager \ + -I${top_srcdir}/src/modem-manager \ + -I$(top_srcdir)/src/bluez-manager \ + -I$(top_srcdir)/src/firewall-manager \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/src/wifi \ + -I$(top_srcdir)/src/wimax \ + -I$(top_srcdir)/libnm-util + +libnm_generated_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(SYSTEMD_CFLAGS) \ + $(IWMX_SDK_CFLAGS) + +libnm_generated_la_LIBADD = \ + $(GLIB_LIBS) + +BUILT_SOURCES = $(GLIB_GENERATED) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/generated/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/generated/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libnm-generated.la: $(libnm_generated_la_OBJECTS) $(libnm_generated_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libnm_generated_la_OBJECTS) $(libnm_generated_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_generated_la-nm-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_generated_la-nm-marshal.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libnm_generated_la-nm-enum-types.lo: nm-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_generated_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_generated_la-nm-enum-types.lo -MD -MP -MF $(DEPDIR)/libnm_generated_la-nm-enum-types.Tpo -c -o libnm_generated_la-nm-enum-types.lo `test -f 'nm-enum-types.c' || echo '$(srcdir)/'`nm-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_generated_la-nm-enum-types.Tpo $(DEPDIR)/libnm_generated_la-nm-enum-types.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-enum-types.c' object='libnm_generated_la-nm-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_generated_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_generated_la-nm-enum-types.lo `test -f 'nm-enum-types.c' || echo '$(srcdir)/'`nm-enum-types.c + +libnm_generated_la-nm-marshal.lo: nm-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_generated_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_generated_la-nm-marshal.lo -MD -MP -MF $(DEPDIR)/libnm_generated_la-nm-marshal.Tpo -c -o libnm_generated_la-nm-marshal.lo `test -f 'nm-marshal.c' || echo '$(srcdir)/'`nm-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_generated_la-nm-marshal.Tpo $(DEPDIR)/libnm_generated_la-nm-marshal.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-marshal.c' object='libnm_generated_la-nm-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_generated_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_generated_la-nm-marshal.lo `test -f 'nm-marshal.c' || echo '$(srcdir)/'`nm-marshal.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +include $(GLIB_MAKEFILE) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/generated/nm-enum-types.c b/src/generated/nm-enum-types.c new file mode 100644 index 00000000..a9973b4d --- /dev/null +++ b/src/generated/nm-enum-types.c @@ -0,0 +1,913 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#include "nm-enum-types.h" + +#include "nm-device-vlan.h" +#include "nm-device-olpc-mesh.h" +#include "nm-hostname-provider.h" +#include "nm-device.h" +#include "nm-rfkill.h" +#include "NetworkManagerUtils.h" +#include "nm-device-factory.h" +#include "nm-active-connection.h" +#include "nm-wifi-ap.h" +#include "nm-device-ethernet.h" +#include "nm-device-bt.h" +#include "nm-device-wifi.h" +#include "nm-dbus-manager.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-netlink-compat.h" +#include "nm-session-monitor.h" +#include "nm-ip4-config.h" +#include "nm-device-bond.h" +#include "nm-wifi-ap-utils.h" +#include "nm-call-store.h" +#include "nm-policy-hosts.h" +#include "nm-udev-manager.h" +#include "nm-manager.h" +#include "nm-device-modem.h" +#include "nm-device-wired.h" +#include "nm-activation-request.h" +#include "nm-session-utils.h" +#include "nm-policy-hostname.h" +#include "nm-device-infiniband.h" +#include "nm-properties-changed-signal.h" +#include "nm-ip6-config.h" +#include "nm-device-private.h" +#include "nm-policy.h" +#include "nm-manager-auth.h" +#include "nm-config.h" +#include "nm-netlink-utils.h" +#include "nm-netlink-monitor.h" +#include "nm-system.h" +#include "nm-connectivity.h" +#include "nm-logging.h" +#include "nm-dns-utils.h" +#include "nm-dns-plugin.h" +#include "nm-dns-manager.h" +#include "nm-dns-bind.h" +#include "nm-dns-dnsmasq.h" +#include "nm-vpn-manager.h" +#include "nm-vpn-service.h" +#include "nm-vpn-connection.h" +#include "nm-dhcp-dhcpcd.h" +#include "nm-dhcp-dhclient.h" +#include "nm-dhcp-client.h" +#include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-manager.h" +#include "nm-ip6-manager.h" +#include "nm-supplicant-types.h" +#include "nm-supplicant-config.h" +#include "nm-supplicant-settings-verify.h" +#include "nm-supplicant-manager.h" +#include "nm-supplicant-interface.h" +#include "nm-backend.h" +#include "NetworkManagerGeneric.h" +#include "nm-ppp-status.h" +#include "nm-pppd-plugin.h" +#include "nm-ppp-manager.h" +#include "nm-dnsmasq-manager.h" +#include "nm-modem.h" +#include "nm-modem-cdma.h" +#include "nm-modem-types.h" +#include "nm-modem-gsm.h" +#include "nm-modem-manager.h" +#include "nm-bluez-device.h" +#include "nm-bluez-manager.h" +#include "nm-bluez-adapter.h" +#include "nm-bluez-common.h" +#include "nm-firewall-manager.h" +#include "nm-settings.h" +#include "nm-settings-connection.h" +#include "nm-default-wired-connection.h" +#include "nm-system-config-interface.h" +#include "nm-settings-utils.h" +#include "nm-settings-error.h" +#include "nm-agent-manager.h" +#include "nm-inotify-helper.h" +#include "nm-secret-agent.h" +#include "nm-device-wimax.h" +#include "iwmxsdk.h" +#include "nm-wimax-types.h" +#include "nm-wimax-util.h" +#include "nm-wimax-nsp.h" + +GType +nm_vlan_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" }, + { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVlanError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_olpc_mesh_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH", "ConnectionNotMesh" }, + { NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "NM_OLPC_MESH_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMOlpcMeshError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_ERROR_CONNECTION_ACTIVATING, "NM_DEVICE_ERROR_CONNECTION_ACTIVATING", "ConnectionActivating" }, + { NM_DEVICE_ERROR_CONNECTION_INVALID, "NM_DEVICE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_DEVICE_ERROR_NOT_ACTIVE, "NM_DEVICE_ERROR_NOT_ACTIVE", "NotActive" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_rf_kill_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { RFKILL_UNBLOCKED, "RFKILL_UNBLOCKED", "unblocked" }, + { RFKILL_SOFT_BLOCKED, "RFKILL_SOFT_BLOCKED", "soft-blocked" }, + { RFKILL_HARD_BLOCKED, "RFKILL_HARD_BLOCKED", "hard-blocked" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("RfKillState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_rf_kill_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { RFKILL_TYPE_WLAN, "RFKILL_TYPE_WLAN", "wlan" }, + { RFKILL_TYPE_WWAN, "RFKILL_TYPE_WWAN", "wwan" }, + { RFKILL_TYPE_WIMAX, "RFKILL_TYPE_WIMAX", "wimax" }, + { RFKILL_TYPE_UNKNOWN, "RFKILL_TYPE_UNKNOWN", "unknown" }, + { RFKILL_TYPE_MAX, "RFKILL_TYPE_MAX", "max" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("RfKillType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_ethernet_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED", "ConnectionNotWired" }, + { NM_ETHERNET_ERROR_CONNECTION_INVALID, "NM_ETHERNET_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMEthernetError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_bt_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_BT_ERROR_CONNECTION_NOT_BT, "NM_BT_ERROR_CONNECTION_NOT_BT", "ConnectionNotBt" }, + { NM_BT_ERROR_CONNECTION_INVALID, "NM_BT_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "NM_BT_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMBtError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_wifi_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS, "NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS", "ConnectionNotWireless" }, + { NM_WIFI_ERROR_CONNECTION_INVALID, "NM_WIFI_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND", "AccessPointNotFound" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMWifiError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_ip4_config_compare_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_IP4_COMPARE_FLAG_NONE, "NM_IP4_COMPARE_FLAG_NONE", "none" }, + { NM_IP4_COMPARE_FLAG_ADDRESSES, "NM_IP4_COMPARE_FLAG_ADDRESSES", "addresses" }, + { NM_IP4_COMPARE_FLAG_PTP_ADDRESS, "NM_IP4_COMPARE_FLAG_PTP_ADDRESS", "ptp-address" }, + { NM_IP4_COMPARE_FLAG_NAMESERVERS, "NM_IP4_COMPARE_FLAG_NAMESERVERS", "nameservers" }, + { NM_IP4_COMPARE_FLAG_ROUTES, "NM_IP4_COMPARE_FLAG_ROUTES", "routes" }, + { NM_IP4_COMPARE_FLAG_DOMAINS, "NM_IP4_COMPARE_FLAG_DOMAINS", "domains" }, + { NM_IP4_COMPARE_FLAG_SEARCHES, "NM_IP4_COMPARE_FLAG_SEARCHES", "searches" }, + { NM_IP4_COMPARE_FLAG_MTU, "NM_IP4_COMPARE_FLAG_MTU", "mtu" }, + { NM_IP4_COMPARE_FLAG_MSS, "NM_IP4_COMPARE_FLAG_MSS", "mss" }, + { NM_IP4_COMPARE_FLAG_WINS_SERVERS, "NM_IP4_COMPARE_FLAG_WINS_SERVERS", "wins-servers" }, + { NM_IP4_COMPARE_FLAG_NIS_SERVERS, "NM_IP4_COMPARE_FLAG_NIS_SERVERS", "nis-servers" }, + { NM_IP4_COMPARE_FLAG_NIS_DOMAIN, "NM_IP4_COMPARE_FLAG_NIS_DOMAIN", "nis-domain" }, + { NM_IP4_COMPARE_FLAG_ALL, "NM_IP4_COMPARE_FLAG_ALL", "all" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMIP4ConfigCompareFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_bond_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_BOND_ERROR_CONNECTION_NOT_BOND, "NM_BOND_ERROR_CONNECTION_NOT_BOND", "ConnectionNotBond" }, + { NM_BOND_ERROR_CONNECTION_INVALID, "NM_BOND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, "NM_BOND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMBondError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "NM_MANAGER_ERROR_UNKNOWN_CONNECTION", "UnknownConnection" }, + { NM_MANAGER_ERROR_UNKNOWN_DEVICE, "NM_MANAGER_ERROR_UNKNOWN_DEVICE", "UnknownDevice" }, + { NM_MANAGER_ERROR_UNMANAGED_DEVICE, "NM_MANAGER_ERROR_UNMANAGED_DEVICE", "UnmanagedDevice" }, + { NM_MANAGER_ERROR_SYSTEM_CONNECTION, "NM_MANAGER_ERROR_SYSTEM_CONNECTION", "SystemConnection" }, + { NM_MANAGER_ERROR_PERMISSION_DENIED, "NM_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE", "ConnectionNotActive" }, + { NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE", "AlreadyAsleepOrAwake" }, + { NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED", "AlreadyEnabledOrDisabled" }, + { NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, "NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE", "UnsupportedConnectionType" }, + { NM_MANAGER_ERROR_DEPENDENCY_FAILED, "NM_MANAGER_ERROR_DEPENDENCY_FAILED", "DependencyFailed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_act_request_dependency_result_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_ACT_REQUEST_DEP_RESULT_UNKNOWN, "NM_ACT_REQUEST_DEP_RESULT_UNKNOWN", "unknown" }, + { NM_ACT_REQUEST_DEP_RESULT_WAIT, "NM_ACT_REQUEST_DEP_RESULT_WAIT", "wait" }, + { NM_ACT_REQUEST_DEP_RESULT_READY, "NM_ACT_REQUEST_DEP_RESULT_READY", "ready" }, + { NM_ACT_REQUEST_DEP_RESULT_FAILED, "NM_ACT_REQUEST_DEP_RESULT_FAILED", "failed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMActRequestDependencyResult"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_session_monitor_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SESSION_MONITOR_ERROR_IO_ERROR, "NM_SESSION_MONITOR_ERROR_IO_ERROR", "IOError" }, + { NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE", "MalformedDatabase" }, + { NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "NM_SESSION_MONITOR_ERROR_UNKNOWN_USER", "UnknownUser" }, + { NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NM_SESSION_MONITOR_ERROR_NO_DATABASE", "NoDatabase" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSessionMonitorError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_infiniband_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND, "NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND", "ConnectionNotInfiniband" }, + { NM_INFINIBAND_ERROR_CONNECTION_INVALID, "NM_INFINIBAND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, "NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMInfinibandError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_ip6_config_compare_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_IP6_COMPARE_FLAG_NONE, "NM_IP6_COMPARE_FLAG_NONE", "none" }, + { NM_IP6_COMPARE_FLAG_ADDRESSES, "NM_IP6_COMPARE_FLAG_ADDRESSES", "addresses" }, + { NM_IP6_COMPARE_FLAG_PTP_ADDRESS, "NM_IP6_COMPARE_FLAG_PTP_ADDRESS", "ptp-address" }, + { NM_IP6_COMPARE_FLAG_NAMESERVERS, "NM_IP6_COMPARE_FLAG_NAMESERVERS", "nameservers" }, + { NM_IP6_COMPARE_FLAG_ROUTES, "NM_IP6_COMPARE_FLAG_ROUTES", "routes" }, + { NM_IP6_COMPARE_FLAG_DOMAINS, "NM_IP6_COMPARE_FLAG_DOMAINS", "domains" }, + { NM_IP6_COMPARE_FLAG_SEARCHES, "NM_IP6_COMPARE_FLAG_SEARCHES", "searches" }, + { NM_IP6_COMPARE_FLAG_MSS, "NM_IP6_COMPARE_FLAG_MSS", "mss" }, + { NM_IP6_COMPARE_FLAG_ALL, "NM_IP6_COMPARE_FLAG_ALL", "all" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMIP6ConfigCompareFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_auth_call_result_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_AUTH_CALL_RESULT_UNKNOWN, "NM_AUTH_CALL_RESULT_UNKNOWN", "unknown" }, + { NM_AUTH_CALL_RESULT_YES, "NM_AUTH_CALL_RESULT_YES", "yes" }, + { NM_AUTH_CALL_RESULT_AUTH, "NM_AUTH_CALL_RESULT_AUTH", "auth" }, + { NM_AUTH_CALL_RESULT_NO, "NM_AUTH_CALL_RESULT_NO", "no" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMAuthCallResult"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_config_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CONFIG_ERROR_NO_MEMORY, "NM_CONFIG_ERROR_NO_MEMORY", "NoMemory" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMConfigError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_nm_nl_prop_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NMNL_PROP_INVALID, "NMNL_PROP_INVALID", "invalid" }, + { NMNL_PROP_PROT, "NMNL_PROP_PROT", "prot" }, + { NMNL_PROP_SCOPE, "NMNL_PROP_SCOPE", "scope" }, + { NMNL_PROP_TABLE, "NMNL_PROP_TABLE", "table" }, + { NMNL_PROP_PRIO, "NMNL_PROP_PRIO", "prio" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NmNlProp"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_netlink_monitor_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_NETLINK_MONITOR_ERROR_GENERIC, "NM_NETLINK_MONITOR_ERROR_GENERIC", "generic" }, + { NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, "NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE", "netlink-alloc-handle" }, + { NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, "NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT", "netlink-connect" }, + { NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP, "NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP", "netlink-join-group" }, + { NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE, "NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE", "netlink-alloc-link-cache" }, + { NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE, "NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE", "processing-message" }, + { NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, "NM_NETLINK_MONITOR_ERROR_BAD_ALLOC", "bad-alloc" }, + { NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA, "NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA", "waiting-for-socket-data" }, + { NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, "NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE", "link-cache-update" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMNetlinkMonitorError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_logging_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_LOGGING_ERROR_UNKNOWN_LEVEL, "NM_LOGGING_ERROR_UNKNOWN_LEVEL", "UnknownLevel" }, + { NM_LOGGING_ERROR_UNKNOWN_DOMAIN, "NM_LOGGING_ERROR_UNKNOWN_DOMAIN", "UnknownDomain" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMLoggingError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_dns_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DNS_MANAGER_ERROR_SYSTEM, "NM_DNS_MANAGER_ERROR_SYSTEM", "system" }, + { NM_DNS_MANAGER_ERROR_INVALID_NAMESERVER, "NM_DNS_MANAGER_ERROR_INVALID_NAMESERVER", "invalid-nameserver" }, + { NM_DNS_MANAGER_ERROR_INVALID_HOST, "NM_DNS_MANAGER_ERROR_INVALID_HOST", "invalid-host" }, + { NM_DNS_MANAGER_ERROR_INVALID_ID, "NM_DNS_MANAGER_ERROR_INVALID_ID", "invalid-id" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDnsManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_dns_ip_config_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DNS_IP_CONFIG_TYPE_DEFAULT, "NM_DNS_IP_CONFIG_TYPE_DEFAULT", "default" }, + { NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, "NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE", "best-device" }, + { NM_DNS_IP_CONFIG_TYPE_VPN, "NM_DNS_IP_CONFIG_TYPE_VPN", "vpn" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDnsIPConfigType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE", "BaseDeviceNotActive" }, + { NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "NM_VPN_MANAGER_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "NM_VPN_MANAGER_ERROR_SERVICE_INVALID", "ServiceInvalid" }, + { NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, "NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED", "ServiceStartFailed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVPNManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_dhcp_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { DHC_NBI, "DHC_NBI", "nbi" }, + { DHC_PREINIT, "DHC_PREINIT", "preinit" }, + { DHC_PREINIT6, "DHC_PREINIT6", "preinit6" }, + { DHC_BOUND4, "DHC_BOUND4", "bound4" }, + { DHC_BOUND6, "DHC_BOUND6", "bound6" }, + { DHC_IPV4LL, "DHC_IPV4LL", "ipv4ll" }, + { DHC_RENEW4, "DHC_RENEW4", "renew4" }, + { DHC_RENEW6, "DHC_RENEW6", "renew6" }, + { DHC_REBOOT, "DHC_REBOOT", "reboot" }, + { DHC_REBIND4, "DHC_REBIND4", "rebind4" }, + { DHC_REBIND6, "DHC_REBIND6", "rebind6" }, + { DHC_DEPREF6, "DHC_DEPREF6", "depref6" }, + { DHC_STOP, "DHC_STOP", "stop" }, + { DHC_STOP6, "DHC_STOP6", "stop6" }, + { DHC_MEDIUM, "DHC_MEDIUM", "medium" }, + { DHC_TIMEOUT, "DHC_TIMEOUT", "timeout" }, + { DHC_FAIL, "DHC_FAIL", "fail" }, + { DHC_EXPIRE, "DHC_EXPIRE", "expire" }, + { DHC_EXPIRE6, "DHC_EXPIRE6", "expire6" }, + { DHC_RELEASE, "DHC_RELEASE", "release" }, + { DHC_RELEASE6, "DHC_RELEASE6", "release6" }, + { DHC_START, "DHC_START", "start" }, + { DHC_ABEND, "DHC_ABEND", "abend" }, + { DHC_END, "DHC_END", "end" }, + { DHC_END_OPTIONS, "DHC_END_OPTIONS", "end-options" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDHCPState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_dhcp_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DHCP_MANAGER_ERROR_BAD_CLIENT, "NM_DHCP_MANAGER_ERROR_BAD_CLIENT", "BadClient" }, + { NM_DHCP_MANAGER_ERROR_INTERNAL, "NM_DHCP_MANAGER_ERROR_INTERNAL", "InternalError" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDHCPManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_opt_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { TYPE_INVALID, "TYPE_INVALID", "invalid" }, + { TYPE_INT, "TYPE_INT", "int" }, + { TYPE_BYTES, "TYPE_BYTES", "bytes" }, + { TYPE_UTF8, "TYPE_UTF8", "utf8" }, + { TYPE_KEYWORD, "TYPE_KEYWORD", "keyword" }, + { TYPE_STRING, "TYPE_STRING", "string" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("OptType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_ppp_status_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_PPP_STATUS_UNKNOWN, "NM_PPP_STATUS_UNKNOWN", "unknown" }, + { NM_PPP_STATUS_DEAD, "NM_PPP_STATUS_DEAD", "dead" }, + { NM_PPP_STATUS_INITIALIZE, "NM_PPP_STATUS_INITIALIZE", "initialize" }, + { NM_PPP_STATUS_SERIALCONN, "NM_PPP_STATUS_SERIALCONN", "serialconn" }, + { NM_PPP_STATUS_DORMANT, "NM_PPP_STATUS_DORMANT", "dormant" }, + { NM_PPP_STATUS_ESTABLISH, "NM_PPP_STATUS_ESTABLISH", "establish" }, + { NM_PPP_STATUS_AUTHENTICATE, "NM_PPP_STATUS_AUTHENTICATE", "authenticate" }, + { NM_PPP_STATUS_CALLBACK, "NM_PPP_STATUS_CALLBACK", "callback" }, + { NM_PPP_STATUS_NETWORK, "NM_PPP_STATUS_NETWORK", "network" }, + { NM_PPP_STATUS_RUNNING, "NM_PPP_STATUS_RUNNING", "running" }, + { NM_PPP_STATUS_TERMINATE, "NM_PPP_STATUS_TERMINATE", "terminate" }, + { NM_PPP_STATUS_DISCONNECT, "NM_PPP_STATUS_DISCONNECT", "disconnect" }, + { NM_PPP_STATUS_HOLDOFF, "NM_PPP_STATUS_HOLDOFF", "holdoff" }, + { NM_PPP_STATUS_MASTER, "NM_PPP_STATUS_MASTER", "master" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMPPPStatus"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_dns_masq_status_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DNSMASQ_STATUS_UNKNOWN, "NM_DNSMASQ_STATUS_UNKNOWN", "unknown" }, + { NM_DNSMASQ_STATUS_DEAD, "NM_DNSMASQ_STATUS_DEAD", "dead" }, + { NM_DNSMASQ_STATUS_RUNNING, "NM_DNSMASQ_STATUS_RUNNING", "running" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDnsMasqStatus"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_cdma_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CDMA_ERROR_CONNECTION_NOT_CDMA, "NM_CDMA_ERROR_CONNECTION_NOT_CDMA", "ConnectionNotCdma" }, + { NM_CDMA_ERROR_CONNECTION_INVALID, "NM_CDMA_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_CDMA_ERROR_CONNECTION_INCOMPATIBLE, "NM_CDMA_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMCdmaError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_gsm_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_GSM_ERROR_CONNECTION_NOT_GSM, "NM_GSM_ERROR_CONNECTION_NOT_GSM", "ConnectionNotGsm" }, + { NM_GSM_ERROR_CONNECTION_INVALID, "NM_GSM_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_GSM_ERROR_CONNECTION_INCOMPATIBLE, "NM_GSM_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMGsmError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_system_config_interface_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, "NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE", "none" }, + { NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS, "NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS", "modify-connections" }, + { NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME, "NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME", "modify-hostname" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSystemConfigInterfaceCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_system_config_interface_prop_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST, "NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST", "first" }, + { NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, "NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME", "name" }, + { NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, "NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO", "info" }, + { NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, "NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES", "capabilities" }, + { NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, "NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME", "hostname" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSystemConfigInterfaceProp"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_settings_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTINGS_ERROR_GENERAL, "NM_SETTINGS_ERROR_GENERAL", "GeneralError" }, + { NM_SETTINGS_ERROR_INVALID_CONNECTION, "NM_SETTINGS_ERROR_INVALID_CONNECTION", "InvalidConnection" }, + { NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "NM_SETTINGS_ERROR_READ_ONLY_CONNECTION", "ReadOnlyConnection" }, + { NM_SETTINGS_ERROR_INTERNAL_ERROR, "NM_SETTINGS_ERROR_INTERNAL_ERROR", "InternalError" }, + { NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE", "SecretsUnavailable" }, + { NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED", "SecretsRequestCanceled" }, + { NM_SETTINGS_ERROR_PERMISSION_DENIED, "NM_SETTINGS_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_SETTINGS_ERROR_INVALID_SETTING, "NM_SETTINGS_ERROR_INVALID_SETTING", "InvalidSetting" }, + { NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NM_SETTINGS_ERROR_NOT_PRIVILEGED", "NotPrivileged" }, + { NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED", "AddNotSupported" }, + { NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED", "UpdateNotSupported" }, + { NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED", "DeleteNotSupported" }, + { NM_SETTINGS_ERROR_ADD_FAILED, "NM_SETTINGS_ERROR_ADD_FAILED", "AddFailed" }, + { NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED", "SaveHostnameNotSupported" }, + { NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED", "SaveHostnameFailed" }, + { NM_SETTINGS_ERROR_UUID_EXISTS, "NM_SETTINGS_ERROR_UUID_EXISTS", "UuidExists" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingsError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_agent_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN", "SenderUnknown" }, + { NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND", "SessionNotFound" }, + { NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER", "InvalidIdentifier" }, + { NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NM_AGENT_MANAGER_ERROR_NOT_REGISTERED", "NotRegistered" }, + { NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR", "InternalError" }, + { NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NM_AGENT_MANAGER_ERROR_NO_SECRETS", "NoSecrets" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMAgentManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_wimax_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX, "NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX", "ConnectionNotWimax" }, + { NM_WIMAX_ERROR_CONNECTION_INVALID, "NM_WIMAX_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { NM_WIMAX_ERROR_NSP_NOT_FOUND, "NM_WIMAX_ERROR_NSP_NOT_FOUND", "NspNotFound" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMWimaxError"), 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; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, "NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN", "unknown" }, + { NM_WIMAX_NSP_NETWORK_TYPE_HOME, "NM_WIMAX_NSP_NETWORK_TYPE_HOME", "home" }, + { NM_WIMAX_NSP_NETWORK_TYPE_PARTNER, "NM_WIMAX_NSP_NETWORK_TYPE_PARTNER", "partner" }, + { NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER, "NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER", "roaming-partner" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMWimaxNspNetworkType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + + + diff --git a/src/generated/nm-enum-types.h b/src/generated/nm-enum-types.h new file mode 100644 index 00000000..324dbf6a --- /dev/null +++ b/src/generated/nm-enum-types.h @@ -0,0 +1,89 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#ifndef __NM_ENUM_TYPES_H__ +#define __NM_ENUM_TYPES_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS +GType nm_vlan_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VLAN_ERROR (nm_vlan_error_get_type ()) +GType nm_olpc_mesh_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ()) +GType nm_device_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ()) +GType nm_rf_kill_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_RF_KILL_STATE (nm_rf_kill_state_get_type ()) +GType nm_rf_kill_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_RF_KILL_TYPE (nm_rf_kill_type_get_type ()) +GType nm_ethernet_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ()) +GType nm_bt_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_BT_ERROR (nm_bt_error_get_type ()) +GType nm_wifi_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) +GType nm_ip4_config_compare_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_IP4_CONFIG_COMPARE_FLAGS (nm_ip4_config_compare_flags_get_type ()) +GType nm_bond_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_BOND_ERROR (nm_bond_error_get_type ()) +GType nm_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MANAGER_ERROR (nm_manager_error_get_type ()) +GType nm_act_request_dependency_result_get_type (void) G_GNUC_CONST; +#define NM_TYPE_ACT_REQUEST_DEPENDENCY_RESULT (nm_act_request_dependency_result_get_type ()) +GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SESSION_MONITOR_ERROR (nm_session_monitor_error_get_type ()) +GType nm_infiniband_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_INFINIBAND_ERROR (nm_infiniband_error_get_type ()) +GType nm_ip6_config_compare_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_IP6_CONFIG_COMPARE_FLAGS (nm_ip6_config_compare_flags_get_type ()) +GType nm_auth_call_result_get_type (void) G_GNUC_CONST; +#define NM_TYPE_AUTH_CALL_RESULT (nm_auth_call_result_get_type ()) +GType nm_config_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CONFIG_ERROR (nm_config_error_get_type ()) +GType nm_nm_nl_prop_get_type (void) G_GNUC_CONST; +#define NM_TYPE_NM_NL_PROP (nm_nm_nl_prop_get_type ()) +GType nm_netlink_monitor_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_get_type ()) +GType nm_logging_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_LOGGING_ERROR (nm_logging_error_get_type ()) +GType nm_dns_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DNS_MANAGER_ERROR (nm_dns_manager_error_get_type ()) +GType nm_dns_ip_config_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DNS_IP_CONFIG_TYPE (nm_dns_ip_config_type_get_type ()) +GType nm_vpn_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_MANAGER_ERROR (nm_vpn_manager_error_get_type ()) +GType nm_dhcp_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DHCP_STATE (nm_dhcp_state_get_type ()) +GType nm_dhcp_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DHCP_MANAGER_ERROR (nm_dhcp_manager_error_get_type ()) +GType nm_opt_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_OPT_TYPE (nm_opt_type_get_type ()) +GType nm_ppp_status_get_type (void) G_GNUC_CONST; +#define NM_TYPE_PPP_STATUS (nm_ppp_status_get_type ()) +GType nm_dns_masq_status_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DNS_MASQ_STATUS (nm_dns_masq_status_get_type ()) +GType nm_cdma_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CDMA_ERROR (nm_cdma_error_get_type ()) +GType nm_gsm_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_GSM_ERROR (nm_gsm_error_get_type ()) +GType nm_system_config_interface_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SYSTEM_CONFIG_INTERFACE_CAPABILITIES (nm_system_config_interface_capabilities_get_type ()) +GType nm_system_config_interface_prop_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SYSTEM_CONFIG_INTERFACE_PROP (nm_system_config_interface_prop_get_type ()) +GType nm_settings_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) +GType nm_agent_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) +GType nm_wimax_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_WIMAX_ERROR (nm_wimax_error_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 + +#endif /* __NM_ENUM_TYPES_H__ */ + + + diff --git a/src/generated/nm-marshal.c b/src/generated/nm-marshal.c new file mode 100644 index 00000000..4ba973af --- /dev/null +++ b/src/generated/nm-marshal.c @@ -0,0 +1,705 @@ +#include "nm-marshal.h" + +#include <glib-object.h> + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* BOOLEAN:VOID (nm-marshal.list:1) */ +void +_nm_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_BOOLEAN__VOID callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* VOID:BOOLEAN,UINT (nm-marshal.list:2) */ +void +_nm_marshal_VOID__BOOLEAN_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__BOOLEAN_UINT) (gpointer data1, + gboolean arg_1, + guint arg_2, + gpointer data2); + register GMarshalFunc_VOID__BOOLEAN_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOOLEAN_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_boolean (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + data2); +} + +/* VOID:INT,UINT,BOOLEAN (nm-marshal.list:3) */ +void +_nm_marshal_VOID__INT_UINT_BOOLEAN (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_UINT_BOOLEAN) (gpointer data1, + gint arg_1, + guint arg_2, + gboolean arg_3, + gpointer data2); + register GMarshalFunc_VOID__INT_UINT_BOOLEAN callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_UINT_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + g_marshal_value_peek_boolean (param_values + 3), + data2); +} + +/* VOID:OBJECT,STRING (nm-marshal.list:4) */ +void +_nm_marshal_VOID__OBJECT_STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_STRING) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__OBJECT_STRING callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + data2); +} + +/* VOID:OBJECT,UINT,UINT (nm-marshal.list:5) */ +void +_nm_marshal_VOID__OBJECT_UINT_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_UINT_UINT) (gpointer data1, + gpointer arg_1, + guint arg_2, + guint arg_3, + gpointer data2); + register GMarshalFunc_VOID__OBJECT_UINT_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + g_marshal_value_peek_uint (param_values + 3), + data2); +} + +/* VOID:POINTER (nm-marshal.list:6) */ + +/* VOID:POINTER,POINTER,POINTER,POINTER,INT (nm-marshal.list:7) */ +void +_nm_marshal_VOID__POINTER_POINTER_POINTER_POINTER_INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_POINTER_POINTER_POINTER_INT) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer arg_4, + gint arg_5, + gpointer data2); + register GMarshalFunc_VOID__POINTER_POINTER_POINTER_POINTER_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 6); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_POINTER_POINTER_POINTER_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + g_marshal_value_peek_pointer (param_values + 4), + g_marshal_value_peek_int (param_values + 5), + data2); +} + +/* VOID:POINTER,STRING (nm-marshal.list:8) */ +void +_nm_marshal_VOID__POINTER_STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_STRING) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__POINTER_STRING callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + data2); +} + +/* VOID:STRING,BOXED (nm-marshal.list:9) */ +void +_nm_marshal_VOID__STRING_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_BOXED callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + data2); +} + +/* VOID:STRING,BOXED,BOXED (nm-marshal.list:10) */ +void +_nm_marshal_VOID__STRING_BOXED_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED_BOXED) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_VOID__STRING_BOXED_BOXED callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + g_marshal_value_peek_boxed (param_values + 3), + data2); +} + +/* VOID:STRING,OBJECT (nm-marshal.list:11) */ +void +_nm_marshal_VOID__STRING_OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_OBJECT) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_OBJECT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + data2); +} + +/* VOID:STRING,OBJECT,POINTER (nm-marshal.list:12) */ +void +_nm_marshal_VOID__STRING_OBJECT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_OBJECT_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_VOID__STRING_OBJECT_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_OBJECT_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); +} + +/* VOID:STRING,POINTER (nm-marshal.list:13) */ +void +_nm_marshal_VOID__STRING_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); +} + +/* VOID:STRING,STRING (nm-marshal.list:14) */ +void +_nm_marshal_VOID__STRING_STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_STRING callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + data2); +} + +/* VOID:STRING,STRING,STRING (nm-marshal.list:15) */ +void +_nm_marshal_VOID__STRING_STRING_STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_VOID__STRING_STRING_STRING callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + data2); +} + +/* VOID:STRING,STRING,STRING,UINT (nm-marshal.list:16) */ +void +_nm_marshal_VOID__STRING_STRING_STRING_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING_UINT) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + guint arg_4, + gpointer data2); + register GMarshalFunc_VOID__STRING_STRING_STRING_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_STRING_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + g_marshal_value_peek_uint (param_values + 4), + data2); +} + +/* VOID:UINT,UINT (nm-marshal.list:17) */ +void +_nm_marshal_VOID__UINT_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1, + guint arg_1, + guint arg_2, + gpointer data2); + register GMarshalFunc_VOID__UINT_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uint (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + data2); +} + +/* VOID:UINT,UINT,UINT (nm-marshal.list:18) */ +void +_nm_marshal_VOID__UINT_UINT_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT) (gpointer data1, + guint arg_1, + guint arg_2, + guint arg_3, + gpointer data2); + register GMarshalFunc_VOID__UINT_UINT_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uint (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + g_marshal_value_peek_uint (param_values + 3), + data2); +} + diff --git a/src/generated/nm-marshal.h b/src/generated/nm-marshal.h new file mode 100644 index 00000000..9f9ea6ad --- /dev/null +++ b/src/generated/nm-marshal.h @@ -0,0 +1,151 @@ + +#ifndef ___nm_marshal_MARSHAL_H__ +#define ___nm_marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +/* BOOLEAN:VOID (nm-marshal.list:1) */ +extern void _nm_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:BOOLEAN,UINT (nm-marshal.list:2) */ +extern void _nm_marshal_VOID__BOOLEAN_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:INT,UINT,BOOLEAN (nm-marshal.list:3) */ +extern void _nm_marshal_VOID__INT_UINT_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:OBJECT,STRING (nm-marshal.list:4) */ +extern void _nm_marshal_VOID__OBJECT_STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:OBJECT,UINT,UINT (nm-marshal.list:5) */ +extern void _nm_marshal_VOID__OBJECT_UINT_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:POINTER (nm-marshal.list:6) */ +#define _nm_marshal_VOID__POINTER g_cclosure_marshal_VOID__POINTER + +/* VOID:POINTER,POINTER,POINTER,POINTER,INT (nm-marshal.list:7) */ +extern void _nm_marshal_VOID__POINTER_POINTER_POINTER_POINTER_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:POINTER,STRING (nm-marshal.list:8) */ +extern void _nm_marshal_VOID__POINTER_STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,BOXED (nm-marshal.list:9) */ +extern void _nm_marshal_VOID__STRING_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,BOXED,BOXED (nm-marshal.list:10) */ +extern void _nm_marshal_VOID__STRING_BOXED_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,OBJECT (nm-marshal.list:11) */ +extern void _nm_marshal_VOID__STRING_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,OBJECT,POINTER (nm-marshal.list:12) */ +extern void _nm_marshal_VOID__STRING_OBJECT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,POINTER (nm-marshal.list:13) */ +extern void _nm_marshal_VOID__STRING_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,STRING (nm-marshal.list:14) */ +extern void _nm_marshal_VOID__STRING_STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,STRING,STRING (nm-marshal.list:15) */ +extern void _nm_marshal_VOID__STRING_STRING_STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:STRING,STRING,STRING,UINT (nm-marshal.list:16) */ +extern void _nm_marshal_VOID__STRING_STRING_STRING_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:UINT,UINT (nm-marshal.list:17) */ +extern void _nm_marshal_VOID__UINT_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:UINT,UINT,UINT (nm-marshal.list:18) */ +extern void _nm_marshal_VOID__UINT_UINT_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +G_END_DECLS + +#endif /* ___nm_marshal_MARSHAL_H__ */ + diff --git a/src/ip6-manager/Makefile.am b/src/ip6-manager/Makefile.am index b98d6def..016fc25d 100644 --- a/src/ip6-manager/Makefile.am +++ b/src/ip6-manager/Makefile.am @@ -1,8 +1,11 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src @@ -19,7 +22,7 @@ libip6_manager_la_CPPFLAGS = \ -DG_DISABLE_DEPRECATED libip6_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) \ diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in index 6eb818c0..59c2e7b4 100644 --- a/src/ip6-manager/Makefile.in +++ b/src/ip6-manager/Makefile.in @@ -57,7 +57,7 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libip6_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -142,6 +142,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -196,11 +198,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -211,6 +217,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -250,6 +257,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -316,8 +325,11 @@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src @@ -333,7 +345,7 @@ libip6_manager_la_CPPFLAGS = \ -DG_DISABLE_DEPRECATED libip6_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) \ diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 503dab51..99f85ede 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -91,7 +91,7 @@ typedef struct { char *disable_ip6_path; gboolean disable_ip6_save_valid; - guint32 disable_ip6_save; + gint32 disable_ip6_save; guint finish_addrconf_id; guint config_changed_id; @@ -112,6 +112,14 @@ typedef struct { } NMIP6Device; static void +clear_config_changed (NMIP6Device *device) +{ + if (device->config_changed_id) + g_source_remove (device->config_changed_id); + device->config_changed_id = 0; +} + +static void nm_ip6_device_destroy (NMIP6Device *device) { g_return_if_fail (device != NULL); @@ -124,8 +132,9 @@ nm_ip6_device_destroy (NMIP6Device *device) if (device->finish_addrconf_id) g_source_remove (device->finish_addrconf_id); - if (device->config_changed_id) - g_source_remove (device->config_changed_id); + + clear_config_changed (device); + g_free (device->iface); if (device->rdnss_servers) g_array_free (device->rdnss_servers, TRUE); @@ -176,9 +185,10 @@ nm_ip6_device_new (NMIP6Manager *manager, int ifindex) device->disable_ip6_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/disable_ipv6", device->iface); g_assert (device->disable_ip6_path); - device->disable_ip6_save_valid = nm_utils_get_proc_sys_net_value (device->disable_ip6_path, - device->iface, - &device->disable_ip6_save); + device->disable_ip6_save_valid = nm_utils_get_proc_sys_net_value_with_bounds (device->disable_ip6_path, + device->iface, + &device->disable_ip6_save, + 0, 1); return device; @@ -267,6 +277,7 @@ rdnss_expired (gpointer user_data) nm_log_dbg (LOGD_IP6, "(%s): IPv6 RDNSS information expired", device->iface); set_rdnss_timeout (device); + clear_config_changed (device); emit_config_changed (&info); return FALSE; } @@ -321,11 +332,12 @@ static gboolean dnssl_expired (gpointer user_data) { NMIP6Device *device = user_data; - CallbackInfo info = { device, IP6_DHCP_OPT_NONE }; + CallbackInfo info = { device, IP6_DHCP_OPT_NONE, FALSE }; nm_log_dbg (LOGD_IP6, "(%s): IPv6 DNSSL information expired", device->iface); set_dnssl_timeout (device); + clear_config_changed (device); emit_config_changed (&info); return FALSE; } @@ -434,8 +446,9 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) addr = nl_addr_get_binary_addr (nladdr); if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) { - nm_log_dbg (LOGD_IP6, "(%s): netlink address: %s", - device->iface, buf); + nm_log_dbg (LOGD_IP6, "(%s): netlink address: %s/%d", + device->iface, buf, + rtnl_addr_get_prefixlen (rtnladdr)); } if (IN6_IS_ADDR_LINKLOCAL (addr)) { @@ -972,6 +985,28 @@ static struct nla_policy link_prot_policy[IFLA_INET6_MAX + 1] = { [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, }; +static char * +ra_flags_to_string (guint32 ra_flags) +{ + GString *s = g_string_sized_new (20); + + g_string_append (s, " ("); + if (ra_flags & IF_RS_SENT) + g_string_append_c (s, 'S'); + + if (ra_flags & IF_RA_RCVD) + g_string_append_c (s, 'R'); + + if (ra_flags & IF_RA_OTHERCONF) + g_string_append_c (s, 'O'); + + if (ra_flags & IF_RA_MANAGED) + g_string_append_c (s, 'M'); + + g_string_append_c (s, ')'); + return g_string_free (s, FALSE); +} + static NMIP6Device * process_newlink (NMIP6Manager *manager, struct nl_msg *msg) { @@ -981,6 +1016,7 @@ process_newlink (NMIP6Manager *manager, struct nl_msg *msg) struct nlattr *tb[IFLA_MAX + 1]; struct nlattr *pi[IFLA_INET6_MAX + 1]; int err; + char *flags_str = NULL; /* FIXME: we have to do this manually for now since libnl doesn't yet * support the IFLA_PROTINFO attribute of NEWLINK messages. When it does, @@ -1024,7 +1060,12 @@ process_newlink (NMIP6Manager *manager, struct nl_msg *msg) } device->ra_flags = nla_get_u32 (pi[IFLA_INET6_FLAGS]); - nm_log_dbg (LOGD_IP6, "(%s): got IPv6 flags 0x%X", device->iface, device->ra_flags); + + if (nm_logging_level_enabled (LOGL_DEBUG)) + flags_str = ra_flags_to_string (device->ra_flags); + nm_log_dbg (LOGD_IP6, "(%s): got IPv6 flags 0x%X%s", + device->iface, device->ra_flags, flags_str ? flags_str : ""); + g_free (flags_str); return device; } @@ -1038,7 +1079,7 @@ netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer us gboolean config_changed = FALSE; hdr = nlmsg_hdr (msg); - nm_log_dbg (LOGD_HW, "netlink notificate type %d", hdr->nlmsg_type); + nm_log_dbg (LOGD_HW, "netlink event type %d", hdr->nlmsg_type); switch (hdr->nlmsg_type) { case RTM_NEWADDR: case RTM_DELADDR: diff --git a/src/logging/Makefile.in b/src/logging/Makefile.in index 72274507..c73f71b4 100644 --- a/src/logging/Makefile.in +++ b/src/logging/Makefile.in @@ -138,6 +138,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -192,11 +194,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -207,6 +213,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -246,6 +253,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 078f1527..a2b0ebaf 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -23,7 +23,6 @@ #include <dlfcn.h> #include <syslog.h> -#include <execinfo.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -47,7 +46,7 @@ static guint32 log_domains = \ LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 | \ LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_AGENTS | \ LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH | \ - LOGD_WIMAX; + LOGD_WIMAX | LOGD_INFINIBAND | LOGD_FIREWALL; typedef struct { guint32 num; @@ -88,18 +87,13 @@ static const LogDesc domain_descs[] = { { LOGD_DEVICE, "DEVICE" }, { LOGD_OLPC_MESH, "OLPC" }, { LOGD_WIMAX, "WIMAX" }, + { LOGD_INFINIBAND,"INFINIBAND" }, + { LOGD_FIREWALL, "FIREWALL" }, { 0, NULL } }; /************************************************************************/ -enum { - NM_LOGGING_ERROR_UNKNOWN_LEVEL = 0, - NM_LOGGING_ERROR_UNKNOWN_DOMAIN = 1, -}; - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - GQuark nm_logging_error_quark (void) { @@ -110,22 +104,6 @@ nm_logging_error_quark (void) return ret; } -GType -nm_logging_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - ENUM_ENTRY (NM_LOGGING_ERROR_UNKNOWN_LEVEL, "UnknownLevel"), - ENUM_ENTRY (NM_LOGGING_ERROR_UNKNOWN_DOMAIN, "UnknownDomain"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMLoggingError", values); - } - return etype; -} - /************************************************************************/ gboolean diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h index e3e05f59..7e27f311 100644 --- a/src/logging/nm-logging.h +++ b/src/logging/nm-logging.h @@ -52,6 +52,8 @@ enum { LOGD_DEVICE = 0x00200000, /* Device state and activation */ LOGD_OLPC_MESH = 0x00400000, LOGD_WIMAX = 0x00800000, + LOGD_INFINIBAND = 0x01000000, + LOGD_FIREWALL = 0x02000000, }; #define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6) @@ -64,10 +66,13 @@ enum { LOGL_DEBUG = 0x00000008 }; +typedef enum { + NM_LOGGING_ERROR_UNKNOWN_LEVEL = 0, /*< nick=UnknownLevel >*/ + NM_LOGGING_ERROR_UNKNOWN_DOMAIN = 1, /*< nick=UnknownDomain >*/ +} NMLoggingError; + #define NM_LOGGING_ERROR (nm_logging_error_quark ()) -#define NM_TYPE_LOGGING_ERROR (nm_logging_error_get_type ()) GQuark nm_logging_error_quark (void); -GType nm_logging_error_get_type (void); #define nm_log_err(domain, ...) \ diff --git a/src/main.c b/src/main.c index 12a0b893..4a21959f 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2011 Red Hat, Inc. + * Copyright (C) 2004 - 2012 Red Hat, Inc. * Copyright (C) 2005 - 2008 Novell, Inc. */ @@ -25,6 +25,7 @@ #include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib.h> #include <getopt.h> +#include <locale.h> #include <errno.h> #include <stdlib.h> #include <signal.h> @@ -40,11 +41,12 @@ #include "NetworkManagerUtils.h" #include "nm-manager.h" #include "nm-policy.h" -#include "nm-system.h" +#include "backends/nm-backend.h" #include "nm-dns-manager.h" #include "nm-dbus-manager.h" #include "nm-supplicant-manager.h" #include "nm-dhcp-manager.h" +#include "nm-firewall-manager.h" #include "nm-hostname-provider.h" #include "nm-netlink-monitor.h" #include "nm-vpn-manager.h" @@ -66,80 +68,6 @@ static NMManager *manager = NULL; static GMainLoop *main_loop = NULL; static int quit_pipe[2] = { -1, -1 }; -typedef struct { - time_t time; - GQuark domain; - guint32 code; - guint32 count; -} MonitorInfo; - -static gboolean -detach_monitor (gpointer data) -{ - nm_log_warn (LOGD_HW, "detaching netlink event monitor"); - nm_netlink_monitor_detach (NM_NETLINK_MONITOR (data)); - return FALSE; -} - -static void -nm_error_monitoring_device_link_state (NMNetlinkMonitor *monitor, - GError *error, - gpointer user_data) -{ - MonitorInfo *info = (MonitorInfo *) user_data; - time_t now; - - now = time (NULL); - - if ( (info->domain != error->domain) - || (info->code != error->code) - || (info->time && now > info->time + 10)) { - /* FIXME: Try to handle the error instead of just printing it. */ - nm_log_warn (LOGD_HW, "error monitoring device for netlink events: %s\n", error->message); - - info->time = now; - info->domain = error->domain; - info->code = error->code; - info->count = 0; - } - - info->count++; - if (info->count > 100) { - /* Broken drivers will sometimes cause a flood of netlink errors. - * rh #459205, novell #443429, lp #284507 - */ - nm_log_warn (LOGD_HW, "excessive netlink errors ocurred, disabling netlink monitor."); - nm_log_warn (LOGD_HW, "link change events will not be processed."); - g_idle_add_full (G_PRIORITY_HIGH, detach_monitor, monitor, NULL); - } -} - -static gboolean -nm_monitor_setup (GError **error) -{ - NMNetlinkMonitor *monitor; - MonitorInfo *info; - - monitor = nm_netlink_monitor_get (); - if (!nm_netlink_monitor_open_connection (monitor, error)) { - g_object_unref (monitor); - return FALSE; - } - - info = g_new0 (MonitorInfo, 1); - g_signal_connect_data (G_OBJECT (monitor), "error", - G_CALLBACK (nm_error_monitoring_device_link_state), - info, - (GClosureNotify) g_free, - 0); - nm_netlink_monitor_attach (monitor); - - /* Request initial status of cards */ - nm_netlink_monitor_request_status (monitor, NULL); - - return TRUE; -} - static gboolean quit_early = FALSE; static void @@ -212,7 +140,7 @@ setup_signals (void) /* Set up our quit pipe */ if (pipe (quit_pipe) < 0) { - fprintf (stderr, "Failed to initialze SIGTERM pipe: %d", errno); + fprintf (stderr, _("Failed to initialize SIGTERM pipe: %d"), errno); exit (1); } fcntl (quit_pipe[1], F_SETFL, O_NONBLOCK | fcntl (quit_pipe[1], F_GETFL)); @@ -243,18 +171,18 @@ write_pidfile (const char *pidfile) gboolean success = FALSE; if ((fd = open (pidfile, O_CREAT|O_WRONLY|O_TRUNC, 00644)) < 0) { - fprintf (stderr, "Opening %s failed: %s\n", pidfile, strerror (errno)); + fprintf (stderr, _("Opening %s failed: %s\n"), pidfile, strerror (errno)); return FALSE; } snprintf (pid, sizeof (pid), "%d", getpid ()); if (write (fd, pid, strlen (pid)) < 0) - fprintf (stderr, "Writing to %s failed: %s\n", pidfile, strerror (errno)); + fprintf (stderr, _("Writing to %s failed: %s\n"), pidfile, strerror (errno)); else success = TRUE; if (close (fd)) - fprintf (stderr, "Closing %s failed: %s\n", pidfile, strerror (errno)); + fprintf (stderr, _("Closing %s failed: %s\n"), pidfile, strerror (errno)); return success; } @@ -297,7 +225,7 @@ check_pidfile (const char *pidfile) if (strcmp (process_name, "NetworkManager") == 0) { /* Check that the process exists */ if (kill (pid, 0) == 0) { - fprintf (stderr, "NetworkManager is already running (pid %ld)\n", pid); + fprintf (stderr, _("NetworkManager is already running (pid %ld)\n"), pid); nm_running = TRUE; } } @@ -341,8 +269,7 @@ parse_state_file (const char *filename, * /var/lib/NetworkManager for us since we have to ensure that * users upgrading NM get this working too. */ - if ( tmp_error->domain == G_FILE_ERROR - && tmp_error->code == G_FILE_ERROR_NOENT) { + if (g_error_matches (tmp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { char *data, *dirname; gsize len = 0; @@ -419,6 +346,9 @@ main (int argc, char *argv[]) char *pidfile = NULL, *state_file = NULL; char *config_path = NULL, *plugins = NULL; char *log_level = NULL, *log_domains = NULL; + char *connectivity_uri = NULL; + gint connectivity_interval = -1; + char *connectivity_response = NULL; gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success, show_version = FALSE; NMPolicy *policy = NULL; @@ -427,47 +357,58 @@ main (int argc, char *argv[]) NMDBusManager *dbus_mgr = NULL; NMSupplicantManager *sup_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL; + NMFirewallManager *fw_mgr = NULL; NMSettings *settings = NULL; NMConfig *config; + NMNetlinkMonitor *monitor = NULL; GError *error = NULL; gboolean wrote_pidfile = FALSE; GOptionEntry options[] = { - { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Print NetworkManager version and exit", NULL }, - { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL }, - { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL }, - { "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &pidfile, "Specify the location of a PID file", "filename" }, - { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, "State file location", "/path/to/state.file" }, - { "config", 0, 0, G_OPTION_ARG_FILENAME, &config_path, "Config file location", "/path/to/config.file" }, - { "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ','", "plugin1,plugin2" }, - { "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" }, + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL }, + { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL }, + { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL }, + { "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &pidfile, N_("Specify the location of a PID file"), N_("filename") }, + { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, N_("State file location"), N_("/path/to/state.file") }, + { "config", 0, 0, G_OPTION_ARG_FILENAME, &config_path, N_("Config file location"), N_("/path/to/config.file") }, + { "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") }, + /* Translators: Do not translate the values in the square brackets */ + { "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, N_("Log level: one of [ERR, WARN, INFO, DEBUG]"), "INFO" }, { "log-domains", 0, 0, G_OPTION_ARG_STRING, &log_domains, - "Log domains separated by ',': any combination of\n" + /* Translators: Do not translate the values in the square brackets */ + N_("Log domains separated by ',': any combination of\n" " [NONE,HW,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,\n" " WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,\n" - " AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,WIMAX]", + " AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,WIMAX,\n" + " INFINIBAND,FIREWALL]"), "HW,RFKILL,WIFI" }, + { "connectivity-uri", 0, 0, G_OPTION_ARG_STRING, &connectivity_uri, "A http(s) address to check internet connectivity" }, + { "connectivity-interval", 0, 0, G_OPTION_ARG_INT, &connectivity_interval, "the interval in seconds how often a connectivity check will be done" }, + { "connectivity-response", 0, 0, G_OPTION_ARG_STRING, &connectivity_response, "the expected start of the response" }, {NULL} }; if (!g_module_supported ()) { - fprintf (stderr, "GModules are not supported on your platform!\n"); + fprintf (stderr, _("GModules are not supported on your platform!\n")); exit (1); } + /* Set locale to be able to use environment variables */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* Parse options */ - opt_ctx = g_option_context_new (""); - g_option_context_set_translation_domain (opt_ctx, "UTF-8"); + opt_ctx = g_option_context_new (NULL); + g_option_context_set_translation_domain (opt_ctx, GETTEXT_PACKAGE); g_option_context_set_ignore_unknown_options (opt_ctx, FALSE); g_option_context_set_help_enabled (opt_ctx, TRUE); g_option_context_add_main_entries (opt_ctx, options, NULL); g_option_context_set_summary (opt_ctx, - "NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with."); + _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")); success = g_option_context_parse (opt_ctx, &argc, &argv, NULL); g_option_context_free (opt_ctx); @@ -483,7 +424,7 @@ main (int argc, char *argv[]) } if (getuid () != 0) { - fprintf (stderr, "You must be root to run NetworkManager!\n"); + fprintf (stderr, _("You must be root to run NetworkManager!\n")); exit (1); } @@ -501,11 +442,12 @@ main (int argc, char *argv[]) exit (1); /* Read the config file and CLI overrides */ - config = nm_config_new (config_path, plugins, log_level, log_domains, &error); + config = nm_config_new (config_path, plugins, log_level, log_domains, + connectivity_uri, connectivity_interval, connectivity_response, &error); if (config == NULL) { - fprintf (stderr, "Failed to read configuration: (%d) %s\n", + fprintf (stderr, _("Failed to read configuration: (%d) %s\n"), error ? error->code : -1, - (error && error->message) ? error->message : "unknown"); + (error && error->message) ? error->message : _("unknown")); exit (1); } @@ -521,10 +463,10 @@ main (int argc, char *argv[]) /* Parse the state file */ if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) { - fprintf (stderr, "State file %s parsing failed: (%d) %s\n", + fprintf (stderr, _("State file %s parsing failed: (%d) %s\n"), state_file, error ? error->code : -1, - (error && error->message) ? error->message : "unknown"); + (error && error->message) ? error->message : _("unknown")); /* Not a hard failure */ } g_clear_error (&error); @@ -538,7 +480,7 @@ main (int argc, char *argv[]) int saved_errno; saved_errno = errno; - fprintf (stderr, "Could not daemonize: %s [error %u]\n", + fprintf (stderr, _("Could not daemonize: %s [error %u]\n"), g_strerror (saved_errno), saved_errno); exit (1); @@ -598,12 +540,8 @@ main (int argc, char *argv[]) main_loop = g_main_loop_new (NULL, FALSE); - /* Create watch functions that monitor cards for link status. */ - if (!nm_monitor_setup (&error)) { - nm_log_err (LOGD_CORE, "failed to start monitoring devices: %s.", - error && error->message ? error->message : "(unknown)"); - goto done; - } + /* Create netlink monitor object */ + monitor = nm_netlink_monitor_get (); /* Initialize our DBus service & connection */ dbus_mgr = nm_dbus_manager_get (); @@ -635,6 +573,9 @@ main (int argc, char *argv[]) wifi_enabled, wwan_enabled, wimax_enabled, + nm_config_get_connectivity_uri (config), + nm_config_get_connectivity_interval (config), + nm_config_get_connectivity_response (config), &error); if (manager == NULL) { nm_log_err (LOGD_CORE, "failed to initialize the network manager: %s", @@ -664,6 +605,13 @@ main (int argc, char *argv[]) nm_dhcp_manager_set_hostname_provider (dhcp_mgr, NM_HOSTNAME_PROVIDER (manager)); + /* Initialize Firewall manager */ + fw_mgr = nm_firewall_manager_get (); + if (!fw_mgr) { + nm_log_err (LOGD_CORE, "failed to start the Firewall manager: %s.", error->message); + goto done; + } + /* Start our DBus service */ if (!nm_dbus_manager_start_service (dbus_mgr)) { nm_log_err (LOGD_CORE, "failed to start the dbus service."); @@ -676,7 +624,7 @@ main (int argc, char *argv[]) nm_manager_start (manager); /* Bring up the loopback interface. */ - nm_system_enable_loopback (); + nm_backend_enable_loopback (); success = TRUE; @@ -708,6 +656,9 @@ done: if (sup_mgr) g_object_unref (sup_mgr); + if (fw_mgr) + g_object_unref (fw_mgr); + if (dbus_mgr) g_object_unref (dbus_mgr); @@ -725,6 +676,8 @@ done: g_free (plugins); g_free (log_level); g_free (log_domains); + g_free (connectivity_uri); + g_free (connectivity_response); nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error"); exit (success ? 0 : 1); diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am index 3c3af16c..a5c6a668 100644 --- a/src/modem-manager/Makefile.am +++ b/src/modem-manager/Makefile.am @@ -1,9 +1,14 @@ +include $(GLIB_MAKEFILE) + INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_builddir}/libnm-util noinst_LTLIBRARIES = libmodem-manager.la @@ -23,7 +28,7 @@ libmodem_manager_la_CPPFLAGS = \ $(DBUS_CFLAGS) libmodem_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in index 494bb1be..87afed0c 100644 --- a/src/modem-manager/Makefile.in +++ b/src/modem-manager/Makefile.in @@ -57,7 +57,7 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libmodem_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libmodem_manager_la_OBJECTS = libmodem_manager_la-nm-modem.lo \ @@ -144,6 +144,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -198,11 +200,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -213,6 +219,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -252,6 +259,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -317,10 +326,13 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_builddir}/libnm-util noinst_LTLIBRARIES = libmodem-manager.la libmodem_manager_la_SOURCES = \ @@ -339,7 +351,7 @@ libmodem_manager_la_CPPFLAGS = \ $(DBUS_CFLAGS) libmodem_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) @@ -663,6 +675,7 @@ uninstall-am: mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am +include $(GLIB_MAKEFILE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c index 5db6a84f..fa19a342 100644 --- a/src/modem-manager/nm-modem-cdma.c +++ b/src/modem-manager/nm-modem-cdma.c @@ -27,11 +27,13 @@ #include "nm-dbus-glib-types.h" #include "nm-modem-cdma.h" #include "nm-modem-types.h" +#include "nm-enum-types.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-dbus-manager.h" #include "nm-setting-connection.h" #include "nm-setting-cdma.h" +#include "nm-setting-ppp.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" @@ -46,14 +48,7 @@ typedef struct { } NMModemCdmaPrivate; -typedef enum { - NM_CDMA_ERROR_CONNECTION_NOT_CDMA = 0, - NM_CDMA_ERROR_CONNECTION_INVALID, - NM_CDMA_ERROR_CONNECTION_INCOMPATIBLE, -} NMCdmaError; - #define NM_CDMA_ERROR (nm_cdma_error_quark ()) -#define NM_TYPE_CDMA_ERROR (nm_cdma_error_get_type ()) static GQuark nm_cdma_error_quark (void) @@ -64,29 +59,6 @@ nm_cdma_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_cdma_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a CDMA connection. */ - ENUM_ENTRY (NM_CDMA_ERROR_CONNECTION_NOT_CDMA, "ConnectionNotCdma"), - /* Connection was not a valid CDMA connection. */ - ENUM_ENTRY (NM_CDMA_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_CDMA_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMCdmaError", values); - } - return etype; -} - NMModem * nm_modem_cdma_new (const char *path, @@ -169,7 +141,7 @@ create_connect_properties (NMConnection *connection) GHashTable *properties; const char *str; - setting = NM_SETTING_CDMA (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA)); + setting = nm_connection_get_setting_cdma (connection); properties = value_hash_create (); str = nm_setting_cdma_get_number (setting); @@ -230,7 +202,7 @@ real_get_best_auto_connection (NMModem *modem, NMConnection *connection = NM_CONNECTION (iter->data); NMSettingConnection *s_con; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (!nm_setting_connection_get_autoconnect (s_con)) @@ -252,7 +224,7 @@ real_check_connection_compatible (NMModem *modem, NMSettingConnection *s_con; NMSettingCdma *s_cdma; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME)) { @@ -262,7 +234,7 @@ real_check_connection_compatible (NMModem *modem, return FALSE; } - s_cdma = NM_SETTING_CDMA (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA)); + s_cdma = nm_connection_get_setting_cdma (connection); if (!s_cdma) { g_set_error (error, NM_CDMA_ERROR, NM_CDMA_ERROR_CONNECTION_INVALID, @@ -280,8 +252,9 @@ real_complete_connection (NMModem *modem, GError **error) { NMSettingCdma *s_cdma; + NMSettingPPP *s_ppp; - s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); + s_cdma = nm_connection_get_setting_cdma (connection); if (!s_cdma) { s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); nm_connection_add_setting (connection, NM_SETTING (s_cdma)); @@ -290,6 +263,16 @@ real_complete_connection (NMModem *modem, if (!nm_setting_cdma_get_number (s_cdma)) g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); + s_ppp = nm_connection_get_setting_ppp (connection); + if (!s_ppp) { + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + g_object_set (G_OBJECT (s_ppp), + NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, + NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, + NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + } + nm_utils_complete_generic (connection, NM_SETTING_CDMA_SETTING_NAME, existing_connections, @@ -308,7 +291,7 @@ real_get_user_pass (NMModem *modem, { NMSettingCdma *s_cdma; - s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); + s_cdma = nm_connection_get_setting_cdma (connection); if (!s_cdma) return FALSE; diff --git a/src/modem-manager/nm-modem-cdma.h b/src/modem-manager/nm-modem-cdma.h index 0abe4e0c..2229c183 100644 --- a/src/modem-manager/nm-modem-cdma.h +++ b/src/modem-manager/nm-modem-cdma.h @@ -33,6 +33,12 @@ G_BEGIN_DECLS #define NM_IS_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_CDMA)) #define NM_MODEM_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) +typedef enum { + NM_CDMA_ERROR_CONNECTION_NOT_CDMA = 0, /*< nick=ConnectionNotCdma >*/ + NM_CDMA_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_CDMA_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMCdmaError; + typedef struct { NMModem parent; } NMModemCdma; diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index 9a96ae99..183b4780 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -30,7 +30,9 @@ #include "nm-device-private.h" #include "nm-setting-connection.h" #include "nm-setting-gsm.h" +#include "nm-setting-ppp.h" #include "nm-modem-types.h" +#include "nm-enum-types.h" #include "nm-logging.h" #include "NetworkManagerUtils.h" @@ -60,6 +62,18 @@ typedef enum { MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY } MMModemGsmAllowedMode; +typedef enum { + MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN = 0x0000, + /* bits 0..4 order match Ericsson device bitmap */ + MM_MODEM_GSM_ALLOWED_AUTH_NONE = 0x0001, + MM_MODEM_GSM_ALLOWED_AUTH_PAP = 0x0002, + MM_MODEM_GSM_ALLOWED_AUTH_CHAP = 0x0004, + MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP = 0x0008, + MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2 = 0x0010, + MM_MODEM_GSM_ALLOWED_AUTH_EAP = 0x0020, + + MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP +} MMModemGsmAllowedAuth; G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM) @@ -70,17 +84,12 @@ typedef struct { GHashTable *connect_properties; guint32 pin_tries; + + guint enable_delay_id; } NMModemGsmPrivate; -typedef enum { - NM_GSM_ERROR_CONNECTION_NOT_GSM = 0, - NM_GSM_ERROR_CONNECTION_INVALID, - NM_GSM_ERROR_CONNECTION_INCOMPATIBLE, -} NMGsmError; - #define NM_GSM_ERROR (nm_gsm_error_quark ()) -#define NM_TYPE_GSM_ERROR (nm_gsm_error_get_type ()) static GQuark nm_gsm_error_quark (void) @@ -91,30 +100,6 @@ nm_gsm_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_gsm_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a GSM connection. */ - ENUM_ENTRY (NM_GSM_ERROR_CONNECTION_NOT_GSM, "ConnectionNotGsm"), - /* Connection was not a valid GSM connection. */ - ENUM_ENTRY (NM_GSM_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_GSM_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMGsmError", values); - } - return etype; -} - - NMModem * nm_modem_gsm_new (const char *path, const char *device, @@ -140,20 +125,33 @@ translate_mm_error (GError *error) if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_NO_CARRIER)) reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; - if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_NO_DIALTONE)) - reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_BUSY)) + else if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_NO_DIALTONE)) + reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; + else if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_BUSY)) reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; - if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_NO_ANSWER)) + else if (dbus_g_error_has_name (error, MM_MODEM_CONNECT_ERROR_NO_ANSWER)) reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NETWORK_NOT_ALLOWED)) + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NETWORK_NOT_ALLOWED)) reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; - if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NETWORK_TIMEOUT)) + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NETWORK_TIMEOUT)) reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; - if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NO_NETWORK)) + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_NO_NETWORK)) reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_NOT_INSERTED)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; + else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; + else { + /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ + nm_log_dbg (LOGD_MB, "unmapped dbus error detected: '%s'", dbus_g_error_get_name (error)); + reason = NM_DEVICE_STATE_REASON_UNKNOWN; + } - /* FIXME: We have only GSM error messages here, and we have no idea which + /* FIXME: We have only GSM error messages here, and we have no idea which activation state failed. Reasons like: NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, @@ -162,9 +160,6 @@ translate_mm_error (GError *error) NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED are not used. */ - else - reason = NM_DEVICE_STATE_REASON_UNKNOWN; - return reason; } @@ -237,38 +232,51 @@ do_connect (NMModemGsm *self) static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data); -static void +/* do_enable() is used as a GSourceFunc, hence the gboolean return */ +static gboolean do_enable (NMModemGsm *self) { DBusGProxy *proxy; - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_MODEM_GSM (self)); + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_MODEM_GSM (self), FALSE); + NM_MODEM_GSM_GET_PRIVATE (self)->enable_delay_id = 0; proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM); dbus_g_proxy_begin_call_with_timeout (proxy, "Enable", stage1_enable_done, self, NULL, 20000, G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); + return FALSE; } static void stage1_pin_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMModemGsm *self = NM_MODEM_GSM (user_data); + NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self); + NMDeviceStateReason reason; GError *error = NULL; if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - /* Success; go back and try the enable again */ - do_enable (self); + /* Success; try to enable the modem again. Wait a few seconds to ensure + * that ModemManager is ready for the enable right after the unlock. + */ + if (priv->enable_delay_id == 0) + priv->enable_delay_id = g_timeout_add_seconds (4, (GSourceFunc) do_enable, self); } else { nm_log_warn (LOGD_MB, "GSM PIN unlock failed: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); - g_error_free (error); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + /* try to translate the error reason */ + reason = translate_mm_error (error); + if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) + reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); + g_error_free (error); } } @@ -301,6 +309,7 @@ static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMModemGsm *self = NM_MODEM_GSM (user_data); + NMDeviceStateReason reason; GError *error = NULL; if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) @@ -312,8 +321,13 @@ stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_da if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) handle_enable_pin_required (self); - else - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + else { + /* try to translate the error reason */ + reason = translate_mm_error (error); + if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) + reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); + } g_error_free (error); } @@ -324,10 +338,11 @@ static GHashTable * create_connect_properties (NMConnection *connection) { NMSettingGsm *setting; + NMSettingPPP *s_ppp; GHashTable *properties; const char *str; - setting = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + setting = nm_connection_get_setting_gsm (connection); properties = value_hash_create (); str = nm_setting_gsm_get_number (setting); @@ -382,6 +397,28 @@ create_connect_properties (NMConnection *connection) if (nm_setting_gsm_get_home_only (setting)) value_hash_add_bool (properties, "home_only", TRUE); + /* For IpMethod == STATIC or DHCP */ + s_ppp = nm_connection_get_setting_ppp (connection); + if (s_ppp) { + guint32 auth = MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN; + + if (nm_setting_ppp_get_noauth (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_NONE; + if (!nm_setting_ppp_get_refuse_pap (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_PAP; + if (!nm_setting_ppp_get_refuse_chap (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_CHAP; + if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP; + if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2; + if (!nm_setting_ppp_get_refuse_eap (s_ppp)) + auth |= MM_MODEM_GSM_ALLOWED_AUTH_EAP; + + if (auth != MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN) + value_hash_add_uint (properties, "allowed_auth", auth); + } + return properties; } @@ -429,7 +466,7 @@ real_get_best_auto_connection (NMModem *modem, NMConnection *connection = NM_CONNECTION (iter->data); NMSettingConnection *s_con; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (!nm_setting_connection_get_autoconnect (s_con)) @@ -451,7 +488,7 @@ real_check_connection_compatible (NMModem *modem, NMSettingConnection *s_con; NMSettingGsm *s_gsm; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME)) { @@ -461,7 +498,7 @@ real_check_connection_compatible (NMModem *modem, return FALSE; } - s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + s_gsm = nm_connection_get_setting_gsm (connection); if (!s_gsm) { g_set_error (error, NM_GSM_ERROR, NM_GSM_ERROR_CONNECTION_INVALID, @@ -479,8 +516,9 @@ real_complete_connection (NMModem *modem, GError **error) { NMSettingGsm *s_gsm; + NMSettingPPP *s_ppp; - s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); + s_gsm = nm_connection_get_setting_gsm (connection); if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { /* Need an APN at least */ g_set_error_literal (error, @@ -493,6 +531,16 @@ real_complete_connection (NMModem *modem, if (!nm_setting_gsm_get_number (s_gsm)) g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); + s_ppp = nm_connection_get_setting_ppp (connection); + if (!s_ppp) { + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + g_object_set (G_OBJECT (s_ppp), + NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, + NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, + NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + } + nm_utils_complete_generic (connection, NM_SETTING_GSM_SETTING_NAME, existing_connections, @@ -511,7 +559,7 @@ real_get_user_pass (NMModem *modem, { NMSettingGsm *s_gsm; - s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); + s_gsm = nm_connection_get_setting_gsm (connection); if (!s_gsm) return FALSE; @@ -544,6 +592,9 @@ real_deactivate (NMModem *modem, NMDevice *device) priv->pin_tries = 0; + if (priv->enable_delay_id) + g_source_remove (priv->enable_delay_id); + NM_MODEM_CLASS (nm_modem_gsm_parent_class)->deactivate (modem, device); } @@ -563,6 +614,8 @@ dispose (GObject *object) if (priv->connect_properties) g_hash_table_destroy (priv->connect_properties); + if (priv->enable_delay_id) + g_source_remove (priv->enable_delay_id); G_OBJECT_CLASS (nm_modem_gsm_parent_class)->dispose (object); } diff --git a/src/modem-manager/nm-modem-gsm.h b/src/modem-manager/nm-modem-gsm.h index f481bdb8..e1c94f04 100644 --- a/src/modem-manager/nm-modem-gsm.h +++ b/src/modem-manager/nm-modem-gsm.h @@ -33,6 +33,12 @@ G_BEGIN_DECLS #define NM_IS_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GSM)) #define NM_MODEM_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM, NMModemGsmClass)) +typedef enum { + NM_GSM_ERROR_CONNECTION_NOT_GSM = 0, /*< nick=ConnectionNotGsm >*/ + NM_GSM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_GSM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMGsmError; + typedef struct { NMModem parent; } NMModemGsm; diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c index 3509d667..051940f5 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/modem-manager/nm-modem-manager.c @@ -76,86 +76,56 @@ get_modem_properties (DBusGConnection *connection, char **data_device, char **driver, guint32 *type, - guint32 *ip_method) + guint32 *ip_method, + guint32 *ip_timeout) { DBusGProxy *proxy; - GValue value = { 0 }; GError *err = NULL; + GHashTable *props = NULL; + GHashTableIter iter; + const char *prop; + GValue *value; proxy = dbus_g_proxy_new_for_name (connection, - MM_DBUS_SERVICE, - path, - "org.freedesktop.DBus.Properties"); - - if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "Type", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - *type = g_value_get_uint (&value); - g_value_unset (&value); - } else { - nm_log_warn (LOGD_MB, "could not get device type: %s", err->message); - goto out; - } - - if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "MasterDevice", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - *device = g_value_dup_string (&value); - g_value_unset (&value); - } else { - nm_log_warn (LOGD_MB, "could not get device: %s", err->message); - goto out; - } - - if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "IpMethod", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - *ip_method = g_value_get_uint (&value); - g_value_unset (&value); - } else { - nm_log_warn (LOGD_MB, "could not get IP method: %s", err->message); + MM_DBUS_SERVICE, + path, + "org.freedesktop.DBus.Properties"); + + if (!dbus_g_proxy_call_with_timeout (proxy, "GetAll", 15000, &err, + G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, + G_TYPE_INVALID, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_MB, "could not get modem properties: %s %s", + err ? dbus_g_error_get_name (err) : "(none)", + err ? err->message : "(unknown)"); + g_clear_error (&err); goto out; } - if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "Device", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - *data_device = g_value_dup_string (&value); - g_value_unset (&value); - } else { - nm_log_warn (LOGD_MB, "could not get modem data device: %s", err->message); + if (!props) { + nm_log_warn (LOGD_MB, "no modem properties found"); goto out; } - if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "Driver", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - *driver = g_value_dup_string (&value); - g_value_unset (&value); - } else { - nm_log_warn (LOGD_MB, "could not get modem driver: %s", err->message); - goto out; + g_hash_table_iter_init (&iter, props); + while (g_hash_table_iter_next (&iter, (gpointer) &prop, (gpointer) &value)) { + if (g_strcmp0 (prop, "Type") == 0) + *type = g_value_get_uint (value); + else if (g_strcmp0 (prop, "MasterDevice") == 0) + *device = g_value_dup_string (value); + else if (g_strcmp0 (prop, "IpMethod") == 0) + *ip_method = g_value_get_uint (value); + else if (g_strcmp0 (prop, "Device") == 0) + *data_device = g_value_dup_string (value); + else if (g_strcmp0 (prop, "Driver") == 0) + *driver = g_value_dup_string (value); + else if (g_strcmp0 (prop, "IpTimeout") == 0) + *ip_timeout = g_value_get_uint (value); } + g_hash_table_unref (props); out: - if (err) - g_error_free (err); - g_object_unref (proxy); return *data_device && *driver; @@ -169,6 +139,7 @@ create_modem (NMModemManager *manager, const char *path) char *data_device = NULL, *driver = NULL, *master_device = NULL; uint modem_type = MM_MODEM_TYPE_UNKNOWN; uint ip_method = MM_MODEM_IP_METHOD_PPP; + uint ip_timeout = 0; if (g_hash_table_lookup (priv->modems, path)) { nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); @@ -177,7 +148,7 @@ create_modem (NMModemManager *manager, const char *path) if (!get_modem_properties (nm_dbus_manager_get_connection (priv->dbus_mgr), path, &master_device, &data_device, &driver, - &modem_type, &ip_method)) + &modem_type, &ip_method, &ip_timeout)) return; if (modem_type == MM_MODEM_TYPE_UNKNOWN) { @@ -210,6 +181,7 @@ create_modem (NMModemManager *manager, const char *path) g_free (data_device); if (modem) { + g_object_set (G_OBJECT (modem), NM_MODEM_IP_TIMEOUT, ip_timeout, NULL); g_hash_table_insert (priv->modems, g_strdup (path), modem); g_signal_emit (manager, signals[MODEM_ADDED], 0, modem, driver); } diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index debfbdf7..91c0b06d 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -30,7 +30,6 @@ #include "nm-logging.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "nm-device-interface.h" #include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT) @@ -43,6 +42,7 @@ enum { PROP_IFACE, PROP_PATH, PROP_IP_METHOD, + PROP_IP_TIMEOUT, PROP_ENABLED, LAST_PROP @@ -55,7 +55,6 @@ typedef struct { char *path; NMPPPManager *ppp_manager; - NMIP4Config *pending_ip4_config; guint32 ip_method; char *device; char *iface; @@ -67,6 +66,7 @@ typedef struct { DBusGProxyCall *call; gboolean mm_enabled; + guint32 mm_ip_timeout; /* PPP stats */ guint32 in_bytes; @@ -129,21 +129,6 @@ nm_modem_get_proxy (NMModem *self, return priv->proxy; } -static void -merge_ip4_config (NMActRequest *req, NMIP4Config *config) -{ - NMConnection *connection; - NMSettingIP4Config *s_ip4; - - /* Merge user-defined overrides into the IP4Config to be applied */ - connection = nm_act_request_get_connection (req); - g_assert (connection); - - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (s_ip4) - nm_utils_merge_ip4_config (config, s_ip4); -} - /*****************************************************************************/ /* IP method PPP */ @@ -169,7 +154,6 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gpointer user_data) { NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); guint32 i, num; guint32 bad_dns1 = htonl (0x0A0B0C0D); guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ @@ -213,7 +197,6 @@ ppp_ip4_config (NMPPPManager *ppp_manager, nm_ip4_config_add_nameserver (config, good_dns2); } - priv->pending_ip4_config = g_object_ref (config); g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, iface, config, NULL); } @@ -243,6 +226,7 @@ ppp_stage3_ip4_config_start (NMModem *self, const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; + guint ip_timeout = 20; g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -258,8 +242,16 @@ ppp_stage3_ip4_config_start (NMModem *self, return NM_ACT_STAGE_RETURN_FAILURE; } + /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, + * use the default one (20s) */ + if (priv->mm_ip_timeout > 0) { + nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", + priv->mm_ip_timeout); + ip_timeout = priv->mm_ip_timeout; + } + priv->ppp_manager = nm_ppp_manager_new (priv->iface); - if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, 20, &error)) { + if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) { g_signal_connect (priv->ppp_manager, "state-changed", G_CALLBACK (ppp_state_changed), self); @@ -287,22 +279,6 @@ ppp_stage3_ip4_config_start (NMModem *self, return ret; } -static NMActStageReturn -ppp_stage4 (NMModem *self, - NMActRequest *req, - NMIP4Config **config, - NMDeviceStateReason *reason) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - - *config = priv->pending_ip4_config; - priv->pending_ip4_config = NULL; - - merge_ip4_config (req, *config); - - return NM_ACT_STAGE_RETURN_SUCCESS; -} - /*****************************************************************************/ /* IP method static */ @@ -336,9 +312,6 @@ static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) nm_ip4_config_add_nameserver (config, g_value_get_uint (value)); } g_value_array_free (ret_array); - - priv->pending_ip4_config = g_object_ref (config); - g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, NULL); } g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, error); @@ -368,32 +341,6 @@ static_stage3_ip4_config_start (NMModem *self, return NM_ACT_STAGE_RETURN_POSTPONE; } -static NMActStageReturn -static_stage4 (NMModem *self, - NMActRequest *req, - NMDevice *device, - NMIP4Config **config, - NMDeviceStateReason *reason) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - gboolean no_firmware = FALSE; - - if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) { - if (no_firmware) - *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING; - else - *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - *config = priv->pending_ip4_config; - priv->pending_ip4_config = NULL; - - merge_ip4_config (req, *config); - - return NM_ACT_STAGE_RETURN_SUCCESS; -} - /*****************************************************************************/ NMActStageReturn @@ -426,7 +373,7 @@ nm_modem_stage3_ip4_config_start (NMModem *self, ret = static_stage3_ip4_config_start (self, req, reason); break; case MM_MODEM_IP_METHOD_DHCP: - ret = device_class->act_stage3_ip4_config_start (device, reason); + ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); @@ -438,45 +385,14 @@ nm_modem_stage3_ip4_config_start (NMModem *self, } NMActStageReturn -nm_modem_stage4_get_ip4_config (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, - NMIP4Config **config, - NMDeviceStateReason *reason) +nm_modem_stage3_ip6_config_start (NMModem *self, + NMDevice *device, + NMDeviceClass *device_class, + NMDeviceStateReason *reason) { - NMModemPrivate *priv; - NMActRequest *req; - NMActStageReturn ret; - - g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (device != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_DEVICE (device), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (device_class != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_DEVICE_CLASS (device_class), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - req = nm_device_get_act_request (device); - g_assert (req); - - priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - ret = ppp_stage4 (self, req, config, reason); - break; - case MM_MODEM_IP_METHOD_STATIC: - ret = static_stage4 (self, req, device, config, reason); - break; - case MM_MODEM_IP_METHOD_DHCP: - ret = device_class->act_stage4_get_ip4_config (device, config, reason); - break; - default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - ret = NM_ACT_STAGE_RETURN_FAILURE; - break; - } - - return ret; + /* FIXME: We don't support IPv6 on modems quite yet... */ + nm_device_activate_schedule_ip6_config_timeout (device); + return NM_ACT_STAGE_RETURN_POSTPONE; } static void @@ -586,7 +502,7 @@ nm_modem_act_stage1_prepare (NMModem *self, if (hints) g_ptr_array_free (hints, TRUE); } - + return ret; } @@ -662,11 +578,6 @@ real_deactivate (NMModem *self, NMDevice *device) priv->call = NULL; } - if (priv->pending_ip4_config) { - g_object_unref (priv->pending_ip4_config); - priv->pending_ip4_config = NULL; - } - priv->in_bytes = priv->out_bytes = 0; if (priv->ppp_manager) { @@ -680,10 +591,12 @@ real_deactivate (NMModem *self, NMDevice *device) case MM_MODEM_IP_METHOD_STATIC: case MM_MODEM_IP_METHOD_DHCP: ifindex = nm_device_get_ip_ifindex (device); - /* FIXME: use AF_UNSPEC here when we have IPv6 support */ - nm_system_iface_flush_routes (ifindex, AF_INET); - nm_system_iface_flush_addresses (ifindex, AF_UNSPEC); - nm_system_iface_set_up (ifindex, FALSE, NULL); + if (ifindex >= 0) { + /* FIXME: use AF_UNSPEC here when we have IPv6 support */ + nm_system_iface_flush_routes (ifindex, AF_INET); + nm_system_iface_flush_addresses (ifindex, AF_UNSPEC); + nm_system_iface_set_up (ifindex, FALSE, NULL); + } break; default: nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); @@ -721,7 +634,7 @@ nm_modem_device_state_changed (NMModem *self, g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_MODEM (self)); - if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED)) + if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_ACTIVATED) was_connected = TRUE; priv = NM_MODEM_GET_PRIVATE (self); @@ -758,44 +671,20 @@ nm_modem_device_state_changed (NMModem *self, } } -static gboolean -_state_is_active (NMDeviceState state) -{ - return (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING); -} - gboolean nm_modem_hw_is_up (NMModem *self, NMDevice *device) { - guint32 ip_method = NM_MODEM_GET_PRIVATE (self)->ip_method; + int ifindex = nm_device_get_ip_ifindex (device); - if (ip_method == MM_MODEM_IP_METHOD_STATIC || ip_method == MM_MODEM_IP_METHOD_DHCP) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMDeviceState state; - - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); - if (priv->pending_ip4_config || _state_is_active (state)) - return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); - } - - return TRUE; + return ifindex > 0 ? nm_system_iface_is_up (ifindex) : TRUE; } gboolean nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware) { - guint32 ip_method = NM_MODEM_GET_PRIVATE (self)->ip_method; - - if (ip_method == MM_MODEM_IP_METHOD_STATIC || ip_method == MM_MODEM_IP_METHOD_DHCP) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMDeviceState state; - - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); - if (priv->pending_ip4_config || _state_is_active (state)) - return nm_system_iface_set_up (nm_device_get_ip_ifindex (device), TRUE, no_firmware); - } + int ifindex = nm_device_get_ip_ifindex (device); - return TRUE; + return ifindex > 0 ? nm_system_iface_set_up (ifindex, TRUE, no_firmware) : TRUE; } const char * @@ -1013,6 +902,9 @@ get_property (GObject *object, guint prop_id, case PROP_IP_METHOD: g_value_set_uint (value, priv->ip_method); break; + case PROP_IP_TIMEOUT: + g_value_set_uint (value, priv->mm_ip_timeout); + break; case PROP_ENABLED: g_value_set_boolean (value, priv->mm_enabled); break; @@ -1046,6 +938,9 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->ip_method = g_value_get_uint (value); break; + case PROP_IP_TIMEOUT: + priv->mm_ip_timeout = g_value_get_uint (value); + break; case PROP_ENABLED: break; default: @@ -1129,6 +1024,14 @@ nm_modem_class_init (NMModemClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property + (object_class, PROP_IP_TIMEOUT, + g_param_spec_uint (NM_MODEM_IP_TIMEOUT, + "IP timeout", + "IP timeout", + 0, 360, 20, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, PROP_ENABLED, g_param_spec_boolean (NM_MODEM_ENABLED, "Enabled", diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h index bad19b04..8fe52bc0 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/modem-manager/nm-modem.h @@ -40,6 +40,7 @@ G_BEGIN_DECLS #define NM_MODEM_DEVICE "device" #define NM_MODEM_IFACE "iface" #define NM_MODEM_IP_METHOD "ip-method" +#define NM_MODEM_IP_TIMEOUT "ip-timeout" #define NM_MODEM_ENABLED "enabled" #define NM_MODEM_PPP_STATS "ppp-stats" @@ -129,11 +130,10 @@ NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem, NMDeviceClass *device_class, NMDeviceStateReason *reason); -NMActStageReturn nm_modem_stage4_get_ip4_config (NMModem *modem, - NMDevice *device, - NMDeviceClass *device_class, - NMIP4Config **config, - NMDeviceStateReason *reason); +NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, + NMDevice *device, + NMDeviceClass *device_class, + NMDeviceStateReason *reason); gboolean nm_modem_get_secrets (NMModem *modem, const char *setting_name, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index d3eb920d..3fc7b538 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -34,25 +34,16 @@ #include "nm-setting-8021x.h" #include "nm-dbus-manager.h" #include "nm-device.h" -#include "nm-properties-changed-signal.h" #include "nm-active-connection.h" -#include "nm-dbus-glib-types.h" -#include "nm-active-connection-glue.h" #include "nm-settings-connection.h" -G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMActRequest, nm_act_request, NM_TYPE_ACTIVE_CONNECTION) #define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_ACT_REQUEST, \ NMActRequestPrivate)) -enum { - PROPERTIES_CHANGED, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL] = { 0 }; - typedef struct { char *table; char *rule; @@ -65,36 +56,30 @@ typedef struct { GSList *secrets_calls; - char *specific_object; NMDevice *device; gboolean user_requested; gulong user_uid; - NMActiveConnectionState state; - gboolean is_default; - gboolean is_default6; + NMActiveConnection *dep; + guint dep_state_id; + gboolean shared; GSList *share_rules; - char *ac_path; - gboolean assumed; } NMActRequestPrivate; enum { - PROP_0, - PROP_CONNECTION, - PROP_UUID, - PROP_SPECIFIC_OBJECT, - PROP_DEVICES, - PROP_STATE, - PROP_DEFAULT, - PROP_DEFAULT6, - PROP_VPN, - - LAST_PROP + PROP_MASTER = 2000, }; +enum { + DEP_RESULT, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + /*******************************************************************/ typedef struct { @@ -199,29 +184,6 @@ nm_act_request_get_connection (NMActRequest *req) return NM_ACT_REQUEST_GET_PRIVATE (req)->connection; } -const char * -nm_act_request_get_specific_object (NMActRequest *req) -{ - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); - - return NM_ACT_REQUEST_GET_PRIVATE (req)->specific_object; -} - -void -nm_act_request_set_specific_object (NMActRequest *req, - const char *specific_object) -{ - NMActRequestPrivate *priv; - - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - g_return_if_fail (specific_object != NULL); - - priv = NM_ACT_REQUEST_GET_PRIVATE (req); - - g_free (priv->specific_object); - priv->specific_object = g_strdup (specific_object); -} - gboolean nm_act_request_get_user_requested (NMActRequest *req) { @@ -230,74 +192,47 @@ nm_act_request_get_user_requested (NMActRequest *req) return NM_ACT_REQUEST_GET_PRIVATE (req)->user_requested; } -const char * -nm_act_request_get_active_connection_path (NMActRequest *req) +GObject * +nm_act_request_get_device (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); - return NM_ACT_REQUEST_GET_PRIVATE (req)->ac_path; -} - -void -nm_act_request_set_default (NMActRequest *req, gboolean is_default) -{ - NMActRequestPrivate *priv; - - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv = NM_ACT_REQUEST_GET_PRIVATE (req); - if (priv->is_default == is_default) - return; - - priv->is_default = is_default; - g_object_notify (G_OBJECT (req), NM_ACTIVE_CONNECTION_DEFAULT); + return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device); } gboolean -nm_act_request_get_default (NMActRequest *req) +nm_act_request_get_assumed (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); - return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default; + return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed; } -void -nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6) +NMActiveConnection * +nm_act_request_get_dependency (NMActRequest *req) { - NMActRequestPrivate *priv; - - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv = NM_ACT_REQUEST_GET_PRIVATE (req); - if (priv->is_default6 == is_default6) - return; - - priv->is_default6 = is_default6; - g_object_notify (G_OBJECT (req), NM_ACTIVE_CONNECTION_DEFAULT6); + return NM_ACT_REQUEST_GET_PRIVATE (req)->dep; } -gboolean -nm_act_request_get_default6 (NMActRequest *req) +static NMActRequestDependencyResult +ac_state_to_dep_result (NMActiveConnection *ac) { - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + NMActiveConnectionState state = nm_active_connection_get_state (ac); - return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6; -} + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING) + return NM_ACT_REQUEST_DEP_RESULT_WAIT; + else if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) + return NM_ACT_REQUEST_DEP_RESULT_READY; -GObject * -nm_act_request_get_device (NMActRequest *req) -{ - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); - - return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device); + return NM_ACT_REQUEST_DEP_RESULT_FAILED; } -gboolean -nm_act_request_get_assumed (NMActRequest *req) +NMActRequestDependencyResult +nm_act_request_get_dependency_result (NMActRequest *req) { - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); - return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed; + return priv->dep ? ac_state_to_dep_result (priv->dep) : NM_ACT_REQUEST_DEP_RESULT_READY; } /********************************************************************/ @@ -423,9 +358,7 @@ device_state_changed (NMDevice *device, gpointer user_data) { NMActRequest *self = NM_ACT_REQUEST (user_data); - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); NMActiveConnectionState new_ac_state; - gboolean new_default = FALSE, new_default6 = FALSE; /* Set NMActiveConnection state based on the device's state */ switch (new_state) { @@ -439,43 +372,84 @@ device_state_changed (NMDevice *device, break; case NM_DEVICE_STATE_ACTIVATED: new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED; - new_default = priv->is_default; - new_default6 = priv->is_default6; break; case NM_DEVICE_STATE_DEACTIVATING: new_ac_state = NM_ACTIVE_CONNECTION_STATE_DEACTIVATING; break; default: new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - new_default = new_default6 = FALSE; + nm_active_connection_set_default (NM_ACTIVE_CONNECTION (self), FALSE); + nm_active_connection_set_default6 (NM_ACTIVE_CONNECTION (self), FALSE); break; } - if (new_ac_state != priv->state) { - priv->state = new_ac_state; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); - } + nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self), new_ac_state); +} - if (new_default != priv->is_default) { - priv->is_default = new_default; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT); - } +/********************************************************************/ - if (new_default6 != priv->is_default6) { - priv->is_default6 = new_default6; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6); - } +static void +dep_gone (NMActRequest *self, GObject *ignored) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + g_warn_if_fail (G_OBJECT (priv->dep) == ignored); + + /* Dependent connection is gone; clean up and fail */ + priv->dep = NULL; + priv->dep_state_id = 0; + g_signal_emit (self, signals[DEP_RESULT], 0, NM_ACT_REQUEST_DEP_RESULT_FAILED); } -/********************************************************************/ +static void +dep_state_changed (NMActiveConnection *dep, + GParamSpec *pspec, + NMActRequest *self) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + NMActRequestDependencyResult result; + g_warn_if_fail (priv->dep == dep); + + result = ac_state_to_dep_result (priv->dep); + if (result == NM_ACT_REQUEST_DEP_RESULT_FAILED) { + g_object_weak_unref (G_OBJECT (priv->dep), (GWeakNotify) dep_gone, self); + g_signal_handler_disconnect (priv->dep, priv->dep_state_id); + priv->dep = NULL; + priv->dep_state_id = 0; + } + g_signal_emit (self, signals[DEP_RESULT], 0, result); +} + +/** + * nm_act_request_new: + * + * @connection: the connection to activate @device with + * @specific_object: the object path of the specific object (ie, WiFi access point, + * etc) that will be used to activate @connection and @device + * @user_requested: pass %TRUE if the activation was requested via D-Bus, + * otherwise %FALSE if requested internally by NM (ie, autoconnect) + * @user_uid: if @user_requested is %TRUE, the Unix UID of the user that requested + * the activation + * @assumed: pass %TRUE if the activation should "assume" (ie, taking over) an + * existing connection made before this instance of NM started + * @device: the device/interface to configure according to @connection + * @dependency: if the activation depends on another device (ie, VLAN slave, + * bond slave, etc) pass the #NMActiveConnection that this activation request + * should wait for before proceeding + * + * Begins activation of @device using the given @connection and other details. + * + * Returns: the new activation request on success, %NULL on error. + */ NMActRequest * nm_act_request_new (NMConnection *connection, const char *specific_object, gboolean user_requested, gulong user_uid, gboolean assumed, - gpointer *device) + gpointer *device, + NMActiveConnection *dependency) { GObject *object; NMActRequestPrivate *priv; @@ -483,16 +457,15 @@ nm_act_request_new (NMConnection *connection, g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_DEVICE (device), NULL); - object = g_object_new (NM_TYPE_ACT_REQUEST, NULL); + object = g_object_new (NM_TYPE_ACT_REQUEST, + NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, + NULL); if (!object) return NULL; priv = NM_ACT_REQUEST_GET_PRIVATE (object); priv->connection = g_object_ref (connection); - if (specific_object) - priv->specific_object = g_strdup (specific_object); - priv->device = NM_DEVICE (device); g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), @@ -502,23 +475,28 @@ nm_act_request_new (NMConnection *connection, priv->user_requested = user_requested; priv->assumed = assumed; - return NM_ACT_REQUEST (object); + if (dependency) { + priv->dep = dependency; + g_object_weak_ref (G_OBJECT (dependency), (GWeakNotify) dep_gone, object); + priv->dep_state_id = g_signal_connect (dependency, + "notify::" NM_ACTIVE_CONNECTION_STATE, + G_CALLBACK (dep_state_changed), + object); + } + + if (!nm_active_connection_export (NM_ACTIVE_CONNECTION (object), + connection, + nm_device_get_path (NM_DEVICE (device)))) { + g_object_unref (object); + object = NULL; + } + + return (NMActRequest *) object; } static void nm_act_request_init (NMActRequest *req) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); - NMDBusManager *dbus_mgr; - - priv->ac_path = nm_active_connection_get_next_object_path (); - priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - - dbus_mgr = nm_dbus_manager_get (); - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), - priv->ac_path, - G_OBJECT (req)); - g_object_unref (dbus_mgr); } static void @@ -526,38 +504,17 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - GPtrArray *devices; + NMDevice *master; switch (prop_id) { - case PROP_CONNECTION: - g_value_set_boxed (value, nm_connection_get_path (priv->connection)); - break; - case PROP_UUID: - g_value_set_string (value, nm_connection_get_uuid (priv->connection)); - break; - case PROP_SPECIFIC_OBJECT: - if (priv->specific_object) - g_value_set_boxed (value, priv->specific_object); - else + case PROP_MASTER: + if (priv->dep && NM_IS_ACT_REQUEST (priv->dep)) { + master = NM_DEVICE (nm_act_request_get_device (NM_ACT_REQUEST (priv->dep))); + g_assert (master); + g_value_set_boxed (value, nm_device_get_path (master)); + } else g_value_set_boxed (value, "/"); break; - case PROP_DEVICES: - devices = g_ptr_array_sized_new (1); - g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device))); - g_value_take_boxed (value, devices); - break; - case PROP_STATE: - g_value_set_uint (value, priv->state); - break; - case PROP_DEFAULT: - g_value_set_boolean (value, priv->is_default); - break; - case PROP_DEFAULT6: - g_value_set_boolean (value, priv->is_default6); - break; - case PROP_VPN: - g_value_set_boolean (value, FALSE); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -595,17 +552,19 @@ dispose (GObject *object) g_object_unref (priv->connection); + if (priv->dep) { + g_object_weak_unref (G_OBJECT (priv->dep), (GWeakNotify) dep_gone, object); + g_signal_handler_disconnect (priv->dep, priv->dep_state_id); + priv->dep = NULL; + priv->dep_state_id = 0; + } + G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } static void finalize (GObject *object) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - - g_free (priv->specific_object); - g_free (priv->ac_path); - clear_share_rules (NM_ACT_REQUEST (object)); G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object); @@ -623,23 +582,14 @@ nm_act_request_class_init (NMActRequestClass *req_class) object_class->dispose = dispose; object_class->finalize = finalize; - /* properties */ - nm_active_connection_install_properties (object_class, - PROP_CONNECTION, - PROP_UUID, - PROP_SPECIFIC_OBJECT, - PROP_DEVICES, - PROP_STATE, - PROP_DEFAULT, - PROP_DEFAULT6, - PROP_VPN); - - /* Signals */ - signals[PROPERTIES_CHANGED] = - nm_properties_changed_signal_new (object_class, - G_STRUCT_OFFSET (NMActRequestClass, properties_changed)); - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class), - &dbus_glib_nm_active_connection_object_info); + g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); + + signals[DEP_RESULT] = + g_signal_new (NM_ACT_REQUEST_DEPENDENCY_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index dac9d89a..d7c094e6 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -34,6 +34,15 @@ #define NM_IS_ACT_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACT_REQUEST)) #define NM_ACT_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACT_REQUEST, NMActRequestClass)) +typedef enum { + NM_ACT_REQUEST_DEP_RESULT_UNKNOWN, + NM_ACT_REQUEST_DEP_RESULT_WAIT, + NM_ACT_REQUEST_DEP_RESULT_READY, + NM_ACT_REQUEST_DEP_RESULT_FAILED, +} NMActRequestDependencyResult; + +#define NM_ACT_REQUEST_DEPENDENCY_RESULT "dependency-result" + typedef struct { GObject parent; } NMActRequest; @@ -43,6 +52,8 @@ typedef struct { /* Signals */ void (*properties_changed) (NMActRequest *req, GHashTable *properties); + + void (*dependency_result) (NMActRequest *req, NMActRequestDependencyResult result); } NMActRequestClass; GType nm_act_request_get_type (void); @@ -52,26 +63,13 @@ NMActRequest *nm_act_request_new (NMConnection *connection, gboolean user_requested, gulong user_uid, gboolean assumed, - gpointer *device); /* An NMDevice */ + gpointer *device, /* An NMDevice */ + NMActiveConnection *dependency); NMConnection *nm_act_request_get_connection (NMActRequest *req); -const char * nm_act_request_get_specific_object (NMActRequest *req); - -void nm_act_request_set_specific_object (NMActRequest *req, - const char *specific_object); gboolean nm_act_request_get_user_requested (NMActRequest *req); -const char * nm_act_request_get_active_connection_path (NMActRequest *req); - -void nm_act_request_set_default (NMActRequest *req, gboolean is_default); - -gboolean nm_act_request_get_default (NMActRequest *req); - -void nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6); - -gboolean nm_act_request_get_default6 (NMActRequest *req); - gboolean nm_act_request_get_shared (NMActRequest *req); void nm_act_request_set_shared (NMActRequest *req, gboolean shared); @@ -84,6 +82,10 @@ GObject * nm_act_request_get_device (NMActRequest *req); gboolean nm_act_request_get_assumed (NMActRequest *req); +NMActiveConnection * nm_act_request_get_dependency (NMActRequest *req); + +NMActRequestDependencyResult nm_act_request_get_dependency_result (NMActRequest *req); + /* Secrets handling */ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index ae2afb07..2de62197 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2012 Red Hat, Inc. */ #include <glib.h> @@ -23,55 +23,306 @@ #include "NetworkManager.h" #include "nm-logging.h" #include "nm-dbus-glib-types.h" +#include "nm-dbus-manager.h" +#include "nm-properties-changed-signal.h" -char * -nm_active_connection_get_next_object_path (void) +#include "nm-active-connection-glue.h" + +/* Base class for anything implementing the Connection.Active D-Bus interface */ +G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, G_TYPE_OBJECT) + +#define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_ACTIVE_CONNECTION, \ + NMActiveConnectionPrivate)) + +typedef struct { + gboolean disposed; + + NMConnection *connection; + char *path; + char *specific_object; + char *device_path; + gboolean is_default; + gboolean is_default6; + NMActiveConnectionState state; + gboolean vpn; +} NMActiveConnectionPrivate; + +enum { + PROP_0, + PROP_CONNECTION, + PROP_UUID, + PROP_SPECIFIC_OBJECT, + PROP_DEVICES, + PROP_STATE, + PROP_DEFAULT, + PROP_DEFAULT6, + PROP_VPN, + PROP_MASTER, + + LAST_PROP +}; + +enum { + PROPERTIES_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/****************************************************************/ + +NMActiveConnectionState +nm_active_connection_get_state (NMActiveConnection *self) { - static guint32 counter = 0; + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->state; +} - return g_strdup_printf (NM_DBUS_PATH "/ActiveConnection/%d", counter++); +void +nm_active_connection_set_state (NMActiveConnection *self, + NMActiveConnectionState new_state) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + if (priv->state != new_state) { + priv->state = new_state; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); + } +} + +NMConnection * +nm_active_connection_get_connection (NMActiveConnection *self) +{ + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection; +} + +const char * +nm_active_connection_get_path (NMActiveConnection *self) +{ + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->path; +} + +const char * +nm_active_connection_get_specific_object (NMActiveConnection *self) +{ + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->specific_object; } void -nm_active_connection_install_properties (GObjectClass *object_class, - guint prop_connection, - guint prop_uuid, - guint prop_specific_object, - guint prop_devices, - guint prop_state, - guint prop_default, - guint prop_default6, - guint prop_vpn) -{ - g_object_class_install_property (object_class, prop_connection, +nm_active_connection_set_specific_object (NMActiveConnection *self, + const char *specific_object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + if (g_strcmp0 (priv->specific_object, specific_object) == 0) + return; + + g_free (priv->specific_object); + priv->specific_object = g_strdup (specific_object); + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT); +} + +void +nm_active_connection_set_default (NMActiveConnection *self, gboolean is_default) +{ + NMActiveConnectionPrivate *priv; + + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + if (priv->is_default == is_default) + return; + + priv->is_default = is_default; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT); +} + +gboolean +nm_active_connection_get_default (NMActiveConnection *self) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default; +} + +void +nm_active_connection_set_default6 (NMActiveConnection *self, gboolean is_default6) +{ + NMActiveConnectionPrivate *priv; + + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + if (priv->is_default6 == is_default6) + return; + + priv->is_default6 = is_default6; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6); +} + +gboolean +nm_active_connection_get_default6 (NMActiveConnection *self) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default6; +} + +gboolean +nm_active_connection_export (NMActiveConnection *self, + NMConnection *connection, + const char *devpath) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMDBusManager *dbus_mgr; + static guint32 counter = 0; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (devpath != NULL, FALSE); + + priv->connection = g_object_ref (connection); + priv->path = g_strdup_printf (NM_DBUS_PATH "/ActiveConnection/%d", counter++); + priv->device_path = g_strdup (devpath); + + dbus_mgr = nm_dbus_manager_get (); + dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), + priv->path, G_OBJECT (self)); + g_object_unref (dbus_mgr); + return TRUE; +} + +/****************************************************************/ + +static void +nm_active_connection_init (NMActiveConnection *self) +{ +} + +static void +dispose (GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + if (!priv->disposed) { + priv->disposed = TRUE; + + g_free (priv->path); + g_free (priv->specific_object); + g_free (priv->device_path); + g_object_unref (priv->connection); + } + + G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SPECIFIC_OBJECT: + priv->specific_object = g_value_dup_boxed (value); + break; + case PROP_DEFAULT: + priv->is_default = g_value_get_boolean (value); + break; + case PROP_DEFAULT6: + priv->is_default6 = g_value_get_boolean (value); + break; + case PROP_VPN: + priv->vpn = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + GPtrArray *devices; + + switch (prop_id) { + case PROP_CONNECTION: + g_value_set_boxed (value, nm_connection_get_path (priv->connection)); + break; + case PROP_UUID: + g_value_set_string (value, nm_connection_get_uuid (priv->connection)); + break; + case PROP_SPECIFIC_OBJECT: + g_value_set_boxed (value, priv->specific_object ? priv->specific_object : "/"); + break; + case PROP_DEVICES: + devices = g_ptr_array_sized_new (1); + g_ptr_array_add (devices, g_strdup (priv->device_path)); + g_value_take_boxed (value, devices); + break; + case PROP_STATE: + g_value_set_uint (value, priv->state); + break; + case PROP_DEFAULT: + g_value_set_boolean (value, priv->is_default); + break; + case PROP_DEFAULT6: + g_value_set_boolean (value, priv->is_default6); + break; + case PROP_VPN: + g_value_set_boolean (value, priv->vpn); + break; + case PROP_MASTER: + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_active_connection_class_init (NMActiveConnectionClass *vpn_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (vpn_class); + + g_type_class_add_private (vpn_class, sizeof (NMActiveConnectionPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + /* properties */ + g_object_class_install_property (object_class, PROP_CONNECTION, g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, "Connection", "Connection", DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property (object_class, prop_uuid, + g_object_class_install_property (object_class, PROP_UUID, g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "Connection UUID", "Connection UUID", NULL, G_PARAM_READABLE)); - g_object_class_install_property (object_class, prop_specific_object, + g_object_class_install_property (object_class, PROP_SPECIFIC_OBJECT, g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, "Specific object", "Specific object", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, prop_devices, + g_object_class_install_property (object_class, PROP_DEVICES, g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "Devices", "Devices", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property (object_class, prop_state, + g_object_class_install_property (object_class, PROP_STATE, g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, "State", "State", @@ -80,25 +331,40 @@ nm_active_connection_install_properties (GObjectClass *object_class, NM_ACTIVE_CONNECTION_STATE_UNKNOWN, G_PARAM_READABLE)); - g_object_class_install_property (object_class, prop_default, + g_object_class_install_property (object_class, PROP_DEFAULT, g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "Default", "Is the default IPv4 active connection", FALSE, - G_PARAM_READABLE)); + G_PARAM_READWRITE)); - g_object_class_install_property (object_class, prop_default6, + g_object_class_install_property (object_class, PROP_DEFAULT6, g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "Default6", "Is the default IPv6 active connection", FALSE, - G_PARAM_READABLE)); + G_PARAM_READWRITE)); - g_object_class_install_property (object_class, prop_vpn, + g_object_class_install_property (object_class, PROP_VPN, g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "VPN", "Is a VPN connection", FALSE, - G_PARAM_READABLE)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_MASTER, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_MASTER, + "Master", + "Path of master device", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMActiveConnectionClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (vpn_class), + &dbus_glib_nm_active_connection_object_info); } diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 4bd8c78e..419cbcff 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2012 Red Hat, Inc. */ #ifndef NM_ACTIVE_CONNECTION_H @@ -24,25 +24,63 @@ #include <glib-object.h> #include "nm-connection.h" -#define NM_ACTIVE_CONNECTION_CONNECTION "connection" -#define NM_ACTIVE_CONNECTION_UUID "uuid" +#define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ()) +#define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) +#define NM_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) +#define NM_IS_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_IS_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_ACTIVE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) + +/* Properties */ +#define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_UUID "uuid" #define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" -#define NM_ACTIVE_CONNECTION_DEVICES "devices" -#define NM_ACTIVE_CONNECTION_STATE "state" -#define NM_ACTIVE_CONNECTION_DEFAULT "default" -#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6" -#define NM_ACTIVE_CONNECTION_VPN "vpn" - -char *nm_active_connection_get_next_object_path (void); - -void nm_active_connection_install_properties (GObjectClass *object_class, - guint prop_connection, - guint prop_uuid, - guint prop_specific_object, - guint prop_devices, - guint prop_state, - guint prop_default, - guint prop_default6, - guint prop_vpn); +#define NM_ACTIVE_CONNECTION_DEVICES "devices" +#define NM_ACTIVE_CONNECTION_STATE "state" +#define NM_ACTIVE_CONNECTION_DEFAULT "default" +#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6" +#define NM_ACTIVE_CONNECTION_VPN "vpn" +#define NM_ACTIVE_CONNECTION_MASTER "master" + +typedef struct { + GObject parent; +} NMActiveConnection; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*properties_changed) (NMActiveConnection *req, GHashTable *properties); +} NMActiveConnectionClass; + +GType nm_active_connection_get_type (void); + +gboolean nm_active_connection_export (NMActiveConnection *self, + NMConnection *connection, + const char *devpath); + +NMConnection *nm_active_connection_get_connection (NMActiveConnection *self); + +const char * nm_active_connection_get_path (NMActiveConnection *self); + +const char * nm_active_connection_get_specific_object (NMActiveConnection *self); + +void nm_active_connection_set_specific_object (NMActiveConnection *self, + const char *specific_object); + +void nm_active_connection_set_default (NMActiveConnection *self, + gboolean is_default); + +gboolean nm_active_connection_get_default (NMActiveConnection *self); + +void nm_active_connection_set_default6 (NMActiveConnection *self, + gboolean is_default6); + +gboolean nm_active_connection_get_default6 (NMActiveConnection *self); + +NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *self); + +void nm_active_connection_set_state (NMActiveConnection *self, + NMActiveConnectionState state); #endif /* NM_ACTIVE_CONNECTION_H */ diff --git a/src/nm-config.c b/src/nm-config.c index 71f67d55..f64b8bdb 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -34,6 +34,9 @@ struct NMConfig { char **dns_plugins; char *log_level; char *log_domains; + char *connectivity_uri; + guint connectivity_interval; + char *connectivity_response; }; /************************************************************************/ @@ -47,25 +50,6 @@ nm_config_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_config_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Not enough memory to parse the config file. */ - ENUM_ENTRY (NM_CONFIG_ERROR_NO_MEMORY, "NoMemory"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMConfigError", values); - } - return etype; -} - /************************************************************************/ const char * @@ -116,6 +100,31 @@ nm_config_get_log_domains (NMConfig *config) return config->log_domains; } +const char * +nm_config_get_connectivity_uri (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->connectivity_uri; +} + +const guint +nm_config_get_connectivity_interval (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, -1); + + return config->connectivity_interval; +} + +const char * +nm_config_get_connectivity_response (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return config->connectivity_response; +} + + /************************************************************************/ static gboolean @@ -124,6 +133,9 @@ fill_from_file (NMConfig *config, const char *cli_plugins, const char *cli_log_level, const char *cli_log_domains, + const char *cli_connectivity_uri, + const gint cli_connectivity_interval, + const char *cli_connectivity_response, GError **error) { GKeyFile *kf; @@ -163,6 +175,22 @@ fill_from_file (NMConfig *config, config->log_domains = g_strdup (cli_log_domains); else config->log_domains = g_key_file_get_value (kf, "logging", "domains", NULL); + + if (cli_connectivity_uri && strlen (cli_connectivity_uri)) + config->connectivity_uri = g_strdup (cli_connectivity_uri); + else + config->connectivity_uri = g_key_file_get_value (kf, "connectivity", "uri", NULL); + + if (cli_connectivity_interval >= 0) + config->connectivity_interval = cli_connectivity_interval; + else + config->connectivity_interval = g_key_file_get_integer (kf, "connectivity", "interval", NULL); + + if (cli_connectivity_response && strlen (cli_connectivity_response)) + config->connectivity_response = g_strdup (cli_connectivity_response); + else + config->connectivity_response = g_key_file_get_value (kf, "connectivity", "response", NULL); + success = TRUE; } @@ -175,6 +203,9 @@ nm_config_new (const char *cli_config_path, const char *cli_plugins, const char *cli_log_level, const char *cli_log_domains, + const char *cli_connectivity_uri, + const gint cli_connectivity_interval, + const char *cli_connectivity_response, GError **error) { NMConfig *config; @@ -184,7 +215,9 @@ nm_config_new (const char *cli_config_path, if (cli_config_path) { /* Bad user-specific config file path is a hard error */ - if (!fill_from_file (config, cli_config_path, cli_plugins, cli_log_level, cli_log_domains, error)) { + if (!fill_from_file (config, cli_config_path, cli_plugins, cli_log_level, cli_log_domains, + cli_connectivity_uri, cli_connectivity_interval, cli_connectivity_response, + error)) { nm_config_free (config); return NULL; } @@ -199,7 +232,9 @@ nm_config_new (const char *cli_config_path, */ /* Try deprecated nm-system-settings.conf first */ - if (fill_from_file (config, NM_OLD_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, &local)) + if (fill_from_file (config, NM_OLD_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, + cli_connectivity_uri, cli_connectivity_interval, cli_connectivity_response, + &local)) return config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { @@ -211,7 +246,9 @@ nm_config_new (const char *cli_config_path, g_clear_error (&local); /* Try the standard config file location next */ - if (fill_from_file (config, NM_DEFAULT_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, &local)) + if (fill_from_file (config, NM_DEFAULT_SYSTEM_CONF_FILE, cli_plugins, cli_log_level, cli_log_domains, + cli_connectivity_uri, cli_connectivity_interval, cli_connectivity_response, + &local)) return config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { @@ -224,6 +261,15 @@ nm_config_new (const char *cli_config_path, return NULL; } + /* If for some reason no config file exists, and NM wasn't given on on + * the command line, just use the default config file path. + */ + if (config->path == NULL) { + config->path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE); + fprintf (stderr, "No config file found or given; using %s\n", + NM_DEFAULT_SYSTEM_CONF_FILE); + } + /* ignore error if config file not found */ g_clear_error (&local); return config; @@ -240,7 +286,8 @@ nm_config_free (NMConfig *config) g_strfreev (config->dns_plugins); g_free (config->log_level); g_free (config->log_domains); - + g_free (config->connectivity_uri); + g_free (config->connectivity_response); memset (config, 0, sizeof (*config)); g_free (config); } diff --git a/src/nm-config.h b/src/nm-config.h index fae344fb..6c4206c1 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -27,19 +27,20 @@ typedef struct NMConfig NMConfig; typedef enum { - NM_CONFIG_ERROR_NO_MEMORY = 0, + NM_CONFIG_ERROR_NO_MEMORY = 0, /*< nick=NoMemory >*/ } NMConfigError; #define NM_CONFIG_ERROR (nm_config_error_quark ()) GQuark nm_config_error_quark (void); -#define NM_TYPE_CONFIG_ERROR (nm_config_error_get_type ()) -GType nm_config_error_get_type (void); NMConfig *nm_config_new (const char *cli_config_path, const char *cli_plugins, const char *cli_log_level, const char *cli_log_domains, + const char *cli_connectivity_check_uri, + const gint connectivity_check_interval, + const char *cli_connectivity_check_response, GError **error); const char *nm_config_get_path (NMConfig *config); @@ -48,6 +49,9 @@ const char *nm_config_get_dhcp_client (NMConfig *config); const char **nm_config_get_dns_plugins (NMConfig *config); const char *nm_config_get_log_level (NMConfig *config); const char *nm_config_get_log_domains (NMConfig *config); +const char *nm_config_get_connectivity_uri (NMConfig *config); +const guint nm_config_get_connectivity_interval (NMConfig *config); +const char *nm_config_get_connectivity_response (NMConfig *config); void nm_config_free (NMConfig *config); diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c new file mode 100644 index 00000000..7e0de2c1 --- /dev/null +++ b/src/nm-connectivity.c @@ -0,0 +1,368 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Thomas Bechtold <thomasbechtold@jpberlin.de> + * Copyright (C) 2011 Dan Williams <dcbw@redhat.com> + */ + +#include <config.h> + +#include <string.h> +#include <libsoup/soup.h> + +#include "nm-connectivity.h" +#include "nm-logging.h" +#include "nm-manager.h" + +G_DEFINE_TYPE (NMConnectivity, nm_connectivity, G_TYPE_OBJECT) + +#define NM_CONNECTIVITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONNECTIVITY, NMConnectivityPrivate)) + + +#define DEFAULT_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */ + +typedef struct { + /* used for http requests */ + SoupSession *soup_session; + /* indicates if a connectivity check is currently running */ + gboolean running; + /* the uri to check */ + char *uri; + /* seconds when a check will be repeated */ + guint interval; + /* the expected response for the connectivity check */ + char *response; + /* indicates if the last connection check was successful */ + gboolean connected; + /* the source id for the periodic check */ + guint check_id; +} NMConnectivityPrivate; + +enum { + PROP_0, + PROP_RUNNING, + PROP_URI, + PROP_INTERVAL, + PROP_RESPONSE, + PROP_CONNECTED, + LAST_PROP +}; + + +gboolean +nm_connectivity_get_connected (NMConnectivity *connectivity) +{ + g_return_val_if_fail (NM_IS_CONNECTIVITY (connectivity), FALSE); + + return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->connected; +} + +static void +update_connected (NMConnectivity *self, gboolean connected) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + gboolean old_connected = priv->connected; + + if (priv->uri == NULL || priv->interval == 0) { + /* Default to connected if no checks are to be run */ + priv->connected = TRUE; + } else + priv->connected = connected; + + if (priv->connected != old_connected) + g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_CONNECTED); +} + +static void +nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) +{ + NMConnectivity *self = NM_CONNECTIVITY (user_data); + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + SoupURI *soup_uri; + gboolean connected_new = FALSE; + const char *nm_header; + char *uri_string; + + soup_uri = soup_message_get_uri (msg); + uri_string = soup_uri_to_string (soup_uri, FALSE); + + /* Check headers; if we find the NM-specific one we're done */ + nm_header = soup_message_headers_get_one (msg->response_headers, "X-NetworkManager-Status"); + if (g_strcmp0 (nm_header, "online") == 0) { + nm_log_dbg (LOGD_CORE, "Connectivity check for uri '%s' with Status header successful.", uri_string); + connected_new = TRUE; + } else { + /* check response */ + if (msg->response_body->data && (g_str_has_prefix (msg->response_body->data, priv->response))) { + nm_log_dbg (LOGD_CORE, "Connectivity check for uri '%s' with expected response '%s' successful.", + uri_string, priv->response); + connected_new = TRUE; + } else { + nm_log_dbg (LOGD_CORE, "Connectivity check for uri '%s' with expected response '%s' failed (status %d).", + uri_string, priv->response, msg->status_code); + } + } + g_free (uri_string); + + /* update connectivity and emit signal */ + update_connected (self, connected_new); + + priv->running = FALSE; + g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_RUNNING); +} + +static gboolean +run_check (gpointer user_data) +{ + NMConnectivity *self = NM_CONNECTIVITY (user_data); + NMConnectivityPrivate *priv; + SoupURI *soup_uri; + SoupMessage *msg; + + g_return_val_if_fail (NM_IS_CONNECTIVITY (self), FALSE); + priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + /* check given url async */ + soup_uri = soup_uri_new (priv->uri); + if (soup_uri && SOUP_URI_VALID_FOR_HTTP (soup_uri)) { + msg = soup_message_new_from_uri ("GET", soup_uri); + soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); + soup_session_queue_message (priv->soup_session, + msg, + nm_connectivity_check_cb, + self); + + priv->running = TRUE; + g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_RUNNING); + nm_log_dbg (LOGD_CORE, "Connectivity check with uri '%s' started.", priv->uri); + } else + nm_log_err (LOGD_CORE, "Invalid uri '%s' for connectivity check.", priv->uri); + + if (soup_uri) + soup_uri_free (soup_uri); + + return TRUE; /* keep firing */ +} + +void +nm_connectivity_start_check (NMConnectivity *self) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + if (!priv->uri || !priv->interval) { + nm_connectivity_stop_check (self); + return; + } + + if (priv->check_id == 0) + priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); + + /* Start an immediate check */ + if (priv->running == FALSE) + run_check (self); +} + +void +nm_connectivity_stop_check (NMConnectivity *self) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + if (priv->check_id) { + g_source_remove (priv->check_id); + priv->check_id = 0; + } + + update_connected (self, FALSE); +} + +NMConnectivity * +nm_connectivity_new (const gchar *check_uri, + guint check_interval, + const gchar *check_response) +{ + NMConnectivity *self; + + self = g_object_new (NM_TYPE_CONNECTIVITY, + NM_CONNECTIVITY_URI, check_uri, + NM_CONNECTIVITY_INTERVAL, check_interval, + NM_CONNECTIVITY_RESPONSE, check_response ? check_response : DEFAULT_RESPONSE, + NULL); + g_return_val_if_fail (self != NULL, NULL); + update_connected (self, FALSE); + + return self; +} + +static char * +sanitize_string_val (const GValue *val) +{ + char *s; + + /* Return NULL if string is NULL or zero-length */ + s = g_value_dup_string (val); + if (!s || !s[0]) { + g_free (s); + return NULL; + } + return s; +} + +static void +set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + NMConnectivity *self = NM_CONNECTIVITY (object); + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + switch (property_id) { + case PROP_RUNNING: + priv->running = g_value_get_boolean (value); + break; + case PROP_URI: + g_free (priv->uri); + priv->uri = sanitize_string_val (value); + break; + case PROP_INTERVAL: + priv->interval = g_value_get_uint (value); + break; + case PROP_RESPONSE: + g_free (priv->response); + priv->response = sanitize_string_val (value); + break; + case PROP_CONNECTED: + priv->connected = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + NMConnectivity *self = NM_CONNECTIVITY (object); + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + switch (property_id) { + case PROP_RUNNING: + g_value_set_boolean (value, priv->running); + break; + case PROP_URI: + g_value_set_string (value, priv->uri); + break; + case PROP_INTERVAL: + g_value_set_uint (value, priv->interval); + break; + case PROP_RESPONSE: + g_value_set_string (value, priv->response); + break; + case PROP_CONNECTED: + g_value_set_boolean (value, priv->connected); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void +nm_connectivity_init (NMConnectivity *self) +{ + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + priv->soup_session = soup_session_async_new_with_options (SOUP_SESSION_TIMEOUT, 15, NULL); +} + + +static void +dispose (GObject *object) +{ + NMConnectivity *self = NM_CONNECTIVITY (object); + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + if (priv->soup_session) { + soup_session_abort (priv->soup_session); + g_object_unref (priv->soup_session); + priv->soup_session = NULL; + } + + g_free (priv->uri); + g_free (priv->response); + + if (priv->check_id > 0) { + g_source_remove (priv->check_id); + priv->check_id = 0; + } +} + + +static void +nm_connectivity_class_init (NMConnectivityClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + g_type_class_add_private (klass, sizeof (NMConnectivityPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + + /* properties */ + g_object_class_install_property + (object_class, PROP_RUNNING, + g_param_spec_boolean (NM_CONNECTIVITY_RUNNING, + "Running", + "Connectivity check is running", + FALSE, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_URI, + g_param_spec_string (NM_CONNECTIVITY_URI, + "URI", + "Connectivity check URI", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_INTERVAL, + g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, + "Interval", + "Connectivity check interval in seconds", + 0, G_MAXUINT, 300, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property + (object_class, PROP_RESPONSE, + g_param_spec_string (NM_CONNECTIVITY_RESPONSE, + "Response", + "Expected connectivity check reponse", + DEFAULT_RESPONSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property + (object_class, PROP_CONNECTED, + g_param_spec_boolean (NM_CONNECTIVITY_CONNECTED, + "Connected", + "Is connected", + FALSE, + G_PARAM_READABLE)); +} + diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h new file mode 100644 index 00000000..cecc6676 --- /dev/null +++ b/src/nm-connectivity.h @@ -0,0 +1,66 @@ + +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Thomas Bechtold <thomasbechtold@jpberlin.de> + */ + +#ifndef NM_CONNECTIVITY_H +#define NM_CONNECTIVITY_H + +#include <glib.h> +#include <glib-object.h> + +#include "NetworkManager.h" + +#define NM_TYPE_CONNECTIVITY (nm_connectivity_get_type ()) +#define NM_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTIVITY, NMConnectivity)) +#define NM_CONNECTIVITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONNECTIVITY, NMConnectivityClass)) +#define NM_IS_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTIVITY)) +#define NM_IS_CONNECTIVITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTIVITY)) +#define NM_CONNECTIVITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTIVITY, NMConnectivityClass)) + +/* Properties */ +#define NM_CONNECTIVITY_RUNNING "running" +#define NM_CONNECTIVITY_URI "uri" +#define NM_CONNECTIVITY_INTERVAL "interval" +#define NM_CONNECTIVITY_RESPONSE "response" +#define NM_CONNECTIVITY_CONNECTED "connected" + + +typedef struct { + GObject parent; +} NMConnectivity; + +typedef struct { + GObjectClass parent; +} NMConnectivityClass; + +GType nm_connectivity_get_type (void); + + +NMConnectivity *nm_connectivity_new (const gchar *check_uri, + guint check_interval, + const gchar *check_response); + +void nm_connectivity_start_check (NMConnectivity *connectivity); + +void nm_connectivity_stop_check (NMConnectivity *connectivity); + +gboolean nm_connectivity_get_connected (NMConnectivity *connectivity); + +#endif /* NM_CONNECTIVITY_H */ diff --git a/src/nm-device-bond.c b/src/nm-device-bond.c new file mode 100644 index 00000000..0d99fd71 --- /dev/null +++ b/src/nm-device-bond.c @@ -0,0 +1,569 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2011 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include <glib/gi18n.h> + +#include <netinet/ether.h> + +#include "nm-device-bond.h" +#include "nm-logging.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-netlink-monitor.h" +#include "nm-enum-types.h" +#include "nm-system.h" + +#include "nm-device-bond-glue.h" + + +G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE_WIRED) + +#define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) + +#define NM_BOND_ERROR (nm_bond_error_quark ()) + +typedef struct { + GSList *slaves; +} NMDeviceBondPrivate; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + + LAST_PROP +}; + +/******************************************************************/ + +static GQuark +nm_bond_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-bond-error"); + return quark; +} + +/******************************************************************/ + +static void +device_state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + if (new_state == NM_DEVICE_STATE_UNAVAILABLE) { + /* Use NM_DEVICE_STATE_REASON_CARRIER to make sure num retries is reset */ + nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + } +} + +static void +real_update_hw_address (NMDevice *dev) +{ + const guint8 *hw_addr; + guint8 old_addr[NM_UTILS_HWADDR_LEN_MAX]; + int addrtype, addrlen; + + addrtype = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (dev)); + g_assert (addrtype >= 0); + addrlen = nm_utils_hwaddr_len (addrtype); + g_assert (addrlen > 0); + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + memcpy (old_addr, hw_addr, addrlen); + + NM_DEVICE_CLASS (nm_device_bond_parent_class)->update_hw_address (dev); + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + if (memcmp (old_addr, hw_addr, addrlen)) + g_object_notify (G_OBJECT (dev), NM_DEVICE_BOND_HW_ADDRESS); +} + +static guint32 +real_get_generic_capabilities (NMDevice *dev) +{ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED; +} + +static gboolean +match_bond_connection (NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface; + NMSettingBond *s_bond; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { + g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND, + "The connection was not a bond connection."); + return FALSE; + } + + /* Bond connections must specify the virtual interface name */ + iface = nm_connection_get_virtual_iface_name (connection); + if (!iface || strcmp (nm_device_get_iface (device), iface)) { + g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND, + "The bond connection virtual interface name did not match."); + return FALSE; + } + + /* FIXME: match bond properties like mode, etc? */ + + return TRUE; +} + +static NMConnection * +real_get_best_auto_connection (NMDevice *dev, + GSList *connections, + char **specific_object) +{ + GSList *iter; + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + if ( nm_setting_connection_get_autoconnect (s_con) + && match_bond_connection (dev, connection, NULL)) + return connection; + } + return NULL; +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + return match_bond_connection (device, connection, error); +} + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMSettingBond *s_bond, *tmp; + guint32 i = 0; + char *name; + const GSList *iter; + gboolean found; + + nm_utils_complete_generic (connection, + NM_SETTING_BOND_SETTING_NAME, + existing_connections, + _("Bond connection %d"), + NULL, + TRUE); + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond) { + s_bond = (NMSettingBond *) nm_setting_bond_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bond)); + } + + /* Grab the first name that doesn't exist in either our connections + * or a device on the system. + */ + while (i < 500 && !nm_setting_bond_get_interface_name (s_bond)) { + name = g_strdup_printf ("bond%u", i); + /* check interface names */ + if (nm_netlink_iface_to_index (name) < 0) { + /* check existing bond connections */ + for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = iter->data; + + tmp = nm_connection_get_setting_bond (candidate); + if (tmp && nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) { + if (g_strcmp0 (nm_setting_bond_get_interface_name (tmp), name) == 0) { + found = TRUE; + break; + } + } + } + + if (!found) + g_object_set (G_OBJECT (s_bond), NM_SETTING_BOND_INTERFACE_NAME, name, NULL); + } + + g_free (name); + i++; + } + + return TRUE; +} + +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + char *hwaddr; + gboolean matched; + + hwaddr = nm_utils_hwaddr_ntoa (nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)), ARPHRD_ETHER); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + +static gboolean +bond_match_config (NMDevice *self, NMConnection *connection) +{ + NMSettingBond *s_bond; + const char *ifname; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond) + return FALSE; + + /* Interface name */ + ifname = nm_setting_bond_get_interface_name (s_bond); + if (g_strcmp0 (ifname, nm_device_get_ip_iface (self)) != 0) + return FALSE; + + return TRUE; +} + +static NMConnection * +connection_match_config (NMDevice *self, const GSList *connections) +{ + const GSList *iter; + GSList *bond_matches; + NMConnection *match; + + /* First narrow @connections down to those that match in their + * NMSettingBond configuration. + */ + bond_matches = NULL; + for (iter = connections; iter; iter = iter->next) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if (!nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) + continue; + if (!bond_match_config (self, candidate)) + continue; + + bond_matches = g_slist_prepend (bond_matches, candidate); + } + + /* Now pass those to the super method, which will check IP config */ + bond_matches = g_slist_reverse (bond_matches); + match = NM_DEVICE_CLASS (nm_device_bond_parent_class)->connection_match_config (self, bond_matches); + g_slist_free (bond_matches); + + return match; +} + +/******************************************************************/ + +static NMActStageReturn +real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +{ + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + NMConnection *connection; + NMSettingBond *s_bond; + gboolean no_firmware = FALSE; + + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + ret = NM_DEVICE_CLASS (nm_device_bond_parent_class)->act_stage1_prepare (dev, reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + connection = nm_device_get_connection (dev); + g_assert (connection); + s_bond = nm_connection_get_setting_bond (connection); + g_assert (s_bond); + + /* Interface must be down to set bond options */ + nm_device_hw_take_down (dev, TRUE); + + if (!nm_system_apply_bonding_config (nm_device_get_ip_iface (dev), s_bond)) + ret = NM_ACT_STAGE_RETURN_FAILURE; + + nm_device_hw_bring_up (dev, TRUE, &no_firmware); + } + return ret; +} + +static void +slave_state_changed (NMDevice *slave, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + NMDeviceBond *self = NM_DEVICE_BOND (user_data); + + nm_log_dbg (LOGD_DEVICE, "(%s): slave %s state change %d -> %d", + nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_iface (slave), + old_state, + new_state); + + if ( old_state > NM_DEVICE_STATE_DISCONNECTED + && new_state <= NM_DEVICE_STATE_DISCONNECTED) { + /* Slave is no longer available or managed; can't use it */ + nm_device_release_slave (NM_DEVICE (self), slave); + } +} + +typedef struct { + NMDevice *slave; + guint state_id; +} SlaveInfo; + +static SlaveInfo * +find_slave_info_by_device (NMDeviceBond *self, NMDevice *slave) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->slaves; iter; iter = g_slist_next (iter)) { + if (((SlaveInfo *) iter->data)->slave == slave) + return iter->data; + } + return NULL; +} + +static void +free_slave_info (SlaveInfo *sinfo) +{ + g_return_if_fail (sinfo != NULL); + g_return_if_fail (sinfo->slave != NULL); + + g_signal_handler_disconnect (sinfo->slave, sinfo->state_id); + g_object_unref (sinfo->slave); + memset (sinfo, 0, sizeof (*sinfo)); + g_free (sinfo); +} + +static gboolean +enslave_slave (NMDevice *device, NMDevice *slave) +{ + NMDeviceBond *self = NM_DEVICE_BOND (device); + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (self); + gboolean success, no_firmware = FALSE; + + if (find_slave_info_by_device (self, slave)) + return TRUE; + + nm_device_hw_take_down (slave, TRUE); + + success = nm_system_iface_enslave (nm_device_get_ip_ifindex (device), + nm_device_get_ip_iface (device), + nm_device_get_ip_ifindex (slave), + nm_device_get_ip_iface (slave)); + if (success) { + SlaveInfo *sinfo; + + sinfo = g_malloc0 (sizeof (*slave)); + sinfo->slave = g_object_ref (slave); + sinfo->state_id = g_signal_connect (slave, + "state-changed", + (GCallback) slave_state_changed, + self); + priv->slaves = g_slist_append (priv->slaves, sinfo); + + nm_log_dbg (LOGD_DEVICE, "(%s): enslaved bond slave %s", + nm_device_get_ip_iface (device), + nm_device_get_ip_iface (slave)); + } + + nm_device_hw_bring_up (slave, TRUE, &no_firmware); + + return success; +} + +static gboolean +release_slave (NMDevice *device, NMDevice *slave) +{ + NMDeviceBond *self = NM_DEVICE_BOND (device); + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (self); + gboolean success; + SlaveInfo *sinfo; + + sinfo = find_slave_info_by_device (self, slave); + if (!sinfo) + return FALSE; + + success = nm_system_iface_release (nm_device_get_ip_ifindex (device), + nm_device_get_ip_iface (device), + nm_device_get_ip_ifindex (slave), + nm_device_get_ip_iface (slave)); + nm_log_dbg (LOGD_DEVICE, "(%s): released bond slave %s (success %d)", + nm_device_get_ip_iface (device), + nm_device_get_ip_iface (slave), + success); + priv->slaves = g_slist_remove (priv->slaves, sinfo); + free_slave_info (sinfo); + return success; +} + +/******************************************************************/ + +NMDevice * +nm_device_bond_new (const char *udi, const char *iface) +{ + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bonding", + NM_DEVICE_TYPE_DESC, "Bond", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NULL); +} + +static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_device_bond_parent_class)->constructed (object); + + nm_log_dbg (LOGD_HW | LOGD_DEVICE, "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (object)), + nm_device_get_ifindex (NM_DEVICE (object))); +} + +static void +nm_device_bond_init (NMDeviceBond * self) +{ + g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), NULL); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + const guint8 *current_addr; + + switch (prop_id) { + case PROP_HW_ADDRESS: + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (object)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (current_addr, ARPHRD_ETHER)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMDeviceBond *self = NM_DEVICE_BOND (object); + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->slaves; iter; iter = g_slist_next (iter)) + release_slave (NM_DEVICE (self), ((SlaveInfo *) iter->data)->slave); + g_slist_free (priv->slaves); + priv->slaves = NULL; + + G_OBJECT_CLASS (nm_device_bond_parent_class)->dispose (object); +} + +static void +nm_device_bond_class_init (NMDeviceBondClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceBondPrivate)); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + parent_class->get_generic_capabilities = real_get_generic_capabilities; + parent_class->update_hw_address = real_update_hw_address; + parent_class->get_best_auto_connection = real_get_best_auto_connection; + parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; + + parent_class->spec_match_list = spec_match_list; + parent_class->connection_match_config = connection_match_config; + + parent_class->act_stage1_prepare = real_act_stage1_prepare; + parent_class->enslave_slave = enslave_slave; + parent_class->release_slave = release_slave; + + /* properties */ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, + "Active MAC Address", + "Currently set hardware MAC address", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_BOND_CARRIER, + "Carrier", + "Carrier", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDeviceBondClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_bond_object_info); + + dbus_g_error_domain_register (NM_BOND_ERROR, NULL, NM_TYPE_BOND_ERROR); +} diff --git a/src/nm-device-bond.h b/src/nm-device-bond.h new file mode 100644 index 00000000..50ca45ea --- /dev/null +++ b/src/nm-device-bond.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_BOND_H +#define NM_DEVICE_BOND_H + +#include <glib-object.h> + +#include "nm-device-wired.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type ()) +#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) +#define NM_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BOND)) +#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) +#define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) + +typedef enum { + NM_BOND_ERROR_CONNECTION_NOT_BOND = 0, /*< nick=ConnectionNotBond >*/ + NM_BOND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMBondError; + +#define NM_DEVICE_BOND_HW_ADDRESS "hw-address" +#define NM_DEVICE_BOND_CARRIER "carrier" + +typedef struct { + NMDeviceWired parent; +} NMDeviceBond; + +typedef struct { + NMDeviceWiredClass parent; + + /* Signals */ + void (*properties_changed) (NMDeviceBond *device, GHashTable *properties); +} NMDeviceBondClass; + + +GType nm_device_bond_get_type (void); + +NMDevice *nm_device_bond_new (const char *udi, + const char *iface); + +G_END_DECLS + +#endif /* NM_DEVICE_BOND_H */ diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index c36e0c0b..726762b6 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -31,7 +31,6 @@ #include "nm-bluez-common.h" #include "nm-dbus-manager.h" #include "nm-device-bt.h" -#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-logging.h" #include "nm-marshal.h" @@ -45,6 +44,8 @@ #include "nm-setting-ppp.h" #include "nm-device-bt-glue.h" #include "NetworkManagerUtils.h" +#include "nm-enum-types.h" +#include "nm-utils.h" #define BLUETOOTH_DUN_UUID "dun" #define BLUETOOTH_NAP_UUID "nap" @@ -91,14 +92,7 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef enum { - NM_BT_ERROR_CONNECTION_NOT_BT = 0, - NM_BT_ERROR_CONNECTION_INVALID, - NM_BT_ERROR_CONNECTION_INCOMPATIBLE, -} NMBtError; - #define NM_BT_ERROR (nm_bt_error_quark ()) -#define NM_TYPE_BT_ERROR (nm_bt_error_get_type ()) static GQuark nm_bt_error_quark (void) @@ -109,30 +103,6 @@ nm_bt_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_bt_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a BT connection. */ - ENUM_ENTRY (NM_BT_ERROR_CONNECTION_NOT_BT, "ConnectionNotBt"), - /* Connection was not a valid BT connection. */ - ENUM_ENTRY (NM_BT_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMBtError", values); - } - return etype; -} - - guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) { g_return_val_if_fail (self != NULL, NM_BT_CAPABILITY_NONE); @@ -155,7 +125,7 @@ get_connection_bt_type (NMConnection *connection) NMSettingBluetooth *s_bt; const char *bt_type; - s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + s_bt = nm_connection_get_setting_bluetooth (connection); if (!s_bt) return NM_BT_CAPABILITY_NONE; @@ -183,7 +153,7 @@ real_get_best_auto_connection (NMDevice *device, NMSettingConnection *s_con; guint32 bt_type; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (!nm_setting_connection_get_autoconnect (s_con)) @@ -214,7 +184,7 @@ real_check_connection_compatible (NMDevice *device, int addr_match = FALSE; guint32 bt_type; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) { @@ -224,7 +194,7 @@ real_check_connection_compatible (NMDevice *device, return FALSE; } - s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH)); + s_bt = nm_connection_get_setting_bluetooth (connection); if (!s_bt) { g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INVALID, @@ -276,12 +246,12 @@ real_complete_connection (NMDevice *device, NMSettingPPP *s_ppp; const char *format = NULL, *preferred = NULL; - s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); - s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); - s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); - s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + s_gsm = nm_connection_get_setting_gsm (connection); + s_cdma = nm_connection_get_setting_cdma (connection); + s_serial = nm_connection_get_setting_serial (connection); + s_ppp = nm_connection_get_setting_ppp (connection); - s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + s_bt = nm_connection_get_setting_bluetooth (connection); if (!s_bt) { s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new (); nm_connection_add_setting (connection, NM_SETTING (s_bt)); @@ -404,6 +374,42 @@ real_get_generic_capabilities (NMDevice *dev) return NM_DEVICE_CAP_NM_SUPPORTED; } +static gboolean +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); + NMSettingBluetooth *s_bt; + const GByteArray *mac = NULL; + gboolean matches = FALSE; + GByteArray *devmac; + + s_bt = nm_connection_get_setting_bluetooth (connection); + if (s_bt) + mac = nm_setting_bluetooth_get_bdaddr (s_bt); + + if (mac) { + devmac = nm_utils_hwaddr_atoba (priv->bdaddr, ARPHRD_ETHER); + g_return_val_if_fail (devmac != NULL, FALSE); + g_return_val_if_fail (devmac->len == mac->len, FALSE); + + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == devmac->len, FALSE); + matches = (memcmp (mac->data, other_hwaddr, mac->len) == 0) ? TRUE : FALSE; + } else + matches = (memcmp (mac->data, devmac->data, mac->len) == 0) ? TRUE : FALSE; + + g_byte_array_free (devmac, TRUE); + return matches; + } else if (fail_if_no_hwaddr == FALSE) + return TRUE; + + return FALSE; +} + /*****************************************************************************/ /* IP method PPP */ @@ -421,17 +427,19 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); - switch (nm_device_interface_get_state (NM_DEVICE_INTERFACE (device))) { + switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: case NM_DEVICE_STATE_NEED_AUTH: - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_ACTIVATED: nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); break; case NM_DEVICE_STATE_IP_CONFIG: - if (nm_device_ip_config_should_fail (device, FALSE)) { + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + if (nm_device_activate_ip4_state_in_conf (device)) + nm_device_activate_schedule_ip4_config_timeout (device); + else { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -478,7 +486,7 @@ modem_prepare_result (NMModem *modem, NMDevice *device = NM_DEVICE (user_data); NMDeviceState state; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); + state = nm_device_get_state (device); g_return_if_fail (state == NM_DEVICE_STATE_CONFIG || state == NM_DEVICE_STATE_NEED_AUTH); if (success) { @@ -526,10 +534,8 @@ modem_ip4_config_result (NMModem *self, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); - NMDeviceState state; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); - g_return_if_fail (state == NM_DEVICE_STATE_IP_CONFIG); + g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { nm_log_warn (LOGD_MB | LOGD_IP4 | LOGD_BT, @@ -543,7 +549,7 @@ modem_ip4_config_result (NMModem *self, if (iface) nm_device_set_ip_iface (device, iface); - nm_device_activate_schedule_stage4_ip4_config_get (device); + nm_device_activate_schedule_ip4_config_result (device, config); } } @@ -613,7 +619,7 @@ nm_device_bt_modem_added (NMDeviceBt *self, /* Can only accept the modem in stage2, but since the interface matched * what we were expecting, don't let anything else claim the modem either. */ - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + state = nm_device_get_state (NM_DEVICE (self)); if (state != NM_DEVICE_STATE_CONFIG) { nm_log_warn (LOGD_BT | LOGD_MB, "(%s): modem found but device not in correct state (%d)", @@ -847,15 +853,14 @@ static NMActStageReturn real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); - NMActRequest *req; NMDBusManager *dbus_mgr; DBusGConnection *g_connection; gboolean dun = FALSE; + NMConnection *connection; - req = nm_device_get_act_request (device); - g_assert (req); - - priv->bt_type = get_connection_bt_type (nm_act_request_get_connection (req)); + connection = nm_device_get_connection (device); + g_assert (connection); + priv->bt_type = get_connection_bt_type (connection); if (priv->bt_type == NM_BT_CAPABILITY_NONE) { // FIXME: set a reason code return NM_ACT_STAGE_RETURN_FAILURE; @@ -920,7 +925,9 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } static NMActStageReturn -real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) +real_act_stage3_ip4_config_start (NMDevice *device, + NMIP4Config **out_config, + NMDeviceStateReason *reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMActStageReturn ret; @@ -931,27 +938,26 @@ real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) NM_DEVICE_CLASS (nm_device_bt_parent_class), reason); } else - ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip4_config_start (device, reason); + ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip4_config_start (device, out_config, reason); return ret; } static NMActStageReturn -real_act_stage4_get_ip4_config (NMDevice *device, - NMIP4Config **config, - NMDeviceStateReason *reason) +real_act_stage3_ip6_config_start (NMDevice *device, + NMIP6Config **out_config, + NMDeviceStateReason *reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMActStageReturn ret; if (priv->bt_type == NM_BT_CAPABILITY_DUN) { - ret = nm_modem_stage4_get_ip4_config (NM_DEVICE_BT_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_bt_parent_class), - config, - reason); + ret = nm_modem_stage3_ip6_config_start (NM_DEVICE_BT_GET_PRIVATE (device)->modem, + device, + NM_DEVICE_CLASS (nm_device_bt_parent_class), + reason); } else - ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage4_get_ip4_config (device, config, reason); + ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip6_config_start (device, out_config, reason); return ret; } @@ -1037,15 +1043,15 @@ nm_device_bt_new (const char *udi, g_return_val_if_fail (capabilities != NM_BT_CAPABILITY_NONE, NULL); device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_BT, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_IFACE, bdaddr, - NM_DEVICE_INTERFACE_DRIVER, "bluez", + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, bdaddr, + NM_DEVICE_DRIVER, "bluez", NM_DEVICE_BT_HW_ADDRESS, bdaddr, NM_DEVICE_BT_NAME, name, NM_DEVICE_BT_CAPABILITIES, capabilities, - NM_DEVICE_INTERFACE_MANAGED, managed, - NM_DEVICE_INTERFACE_TYPE_DESC, "Bluetooth", - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_BT, + NM_DEVICE_MANAGED, managed, + NM_DEVICE_TYPE_DESC, "Bluetooth", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BT, NULL); if (device) g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), device); @@ -1148,9 +1154,10 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) device_class->deactivate = real_deactivate; device_class->act_stage2_config = real_act_stage2_config; device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; - device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; + device_class->act_stage3_ip6_config_start = real_act_stage3_ip6_config_start; device_class->check_connection_compatible = real_check_connection_compatible; device_class->complete_connection = real_complete_connection; + device_class->hwaddr_matches = hwaddr_matches; /* Properties */ g_object_class_install_property diff --git a/src/nm-device-bt.h b/src/nm-device-bt.h index d3187d76..0d54d607 100644 --- a/src/nm-device-bt.h +++ b/src/nm-device-bt.h @@ -33,6 +33,12 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT)) #define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) +typedef enum { + NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ + NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMBtError; + #define NM_DEVICE_BT_HW_ADDRESS "hw-address" #define NM_DEVICE_BT_NAME "name" #define NM_DEVICE_BT_CAPABILITIES "bt-capabilities" @@ -69,4 +75,4 @@ gboolean nm_device_bt_modem_removed (NMDeviceBt *device, NMModem *modem); G_END_DECLS -#endif /* NM_GSM_DEVICE_H */ +#endif /* NM_DEVICE_BT_H */ diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 8556c5bd..df0ae94f 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -24,11 +24,8 @@ #include <glib/gi18n.h> #include <netinet/in.h> #include <string.h> -#include <net/ethernet.h> #include <stdlib.h> -#include <linux/types.h> #include <linux/sockios.h> -#include <linux/version.h> #include <linux/ethtool.h> #include <sys/ioctl.h> #include <unistd.h> @@ -38,47 +35,37 @@ #include <gudev/gudev.h> -#include <netlink/route/addr.h> - #include "nm-glib-compat.h" #include "nm-device-ethernet.h" -#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-activation-request.h" #include "NetworkManagerUtils.h" #include "nm-supplicant-manager.h" #include "nm-supplicant-interface.h" #include "nm-supplicant-config.h" -#include "nm-netlink-monitor.h" #include "nm-system.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-8021x.h" #include "nm-setting-pppoe.h" +#include "nm-setting-bond.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-logging.h" #include "nm-properties-changed-signal.h" -#include "nm-dhcp-manager.h" -#include "nm-netlink-utils.h" +#include "nm-utils.h" +#include "nm-enum-types.h" +#include "nm-netlink-monitor.h" #include "nm-device-ethernet-glue.h" -G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) +G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE_WIRED) #define NM_DEVICE_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate)) #define WIRED_SECRETS_TRIES "wired-secrets-tries" -typedef enum -{ - NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED = 0, - NM_ETHERNET_ERROR_CONNECTION_INVALID, - NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, -} NMEthernetError; - #define NM_ETHERNET_ERROR (nm_ethernet_error_quark ()) -#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ()) typedef struct Supplicant { NMSupplicantManager *mgr; @@ -94,17 +81,8 @@ typedef struct Supplicant { } Supplicant; typedef struct { - gboolean disposed; - - guint8 hw_addr[ETH_ALEN]; /* Currently set MAC address */ guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ - gboolean carrier; - - NMNetlinkMonitor * monitor; - gulong link_connected_id; - gulong link_disconnected_id; - guint carrier_action_defer_id; Supplicant supplicant; guint supplicant_timeout_id; @@ -151,145 +129,6 @@ nm_ethernet_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_ethernet_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a wired connection. */ - ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "ConnectionNotWired"), - /* Connection was not a valid wired connection. */ - ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMEthernetError", values); - } - return etype; -} - -static void -carrier_action_defer_clear (NMDeviceEthernet *self) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - if (priv->carrier_action_defer_id) { - g_source_remove (priv->carrier_action_defer_id); - priv->carrier_action_defer_id = 0; - } -} - -static gboolean -carrier_action_defer_cb (gpointer user_data) -{ - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDeviceState state; - - priv->carrier_action_defer_id = 0; - - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - if (state == NM_DEVICE_STATE_UNAVAILABLE) { - if (priv->carrier) - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); - } else if (state >= NM_DEVICE_STATE_DISCONNECTED) { - if (!priv->carrier) - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); - } - - return FALSE; -} - -static void -set_carrier (NMDeviceEthernet *self, - const gboolean carrier, - const gboolean defer_action) -{ - NMDeviceEthernetPrivate *priv; - NMDeviceState state; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - if (priv->carrier == carrier) - return; - - /* Clear any previous deferred action */ - carrier_action_defer_clear (self); - - priv->carrier = carrier; - g_object_notify (G_OBJECT (self), NM_DEVICE_ETHERNET_CARRIER); - - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - nm_log_info (LOGD_HW | LOGD_ETHER, "(%s): carrier now %s (device state %d%s)", - nm_device_get_iface (NM_DEVICE (self)), - carrier ? "ON" : "OFF", - state, - defer_action ? ", deferring action for 4 seconds" : ""); - - if (defer_action) - priv->carrier_action_defer_id = g_timeout_add_seconds (4, carrier_action_defer_cb, self); - else - carrier_action_defer_cb (self); -} - -static void -carrier_on (NMNetlinkMonitor *monitor, - int idx, - gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - guint32 caps; - - /* Make sure signal is for us */ - if (idx == nm_device_get_ifindex (device)) { - /* Ignore spurious netlink messages */ - caps = nm_device_get_capabilities (device); - if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) - return; - - set_carrier (self, TRUE, FALSE); - } -} - -static void -carrier_off (NMNetlinkMonitor *monitor, - int idx, - gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - guint32 caps; - - /* Make sure signal is for us */ - if (idx == nm_device_get_ifindex (device)) { - NMDeviceState state; - gboolean defer = FALSE; - - /* Ignore spurious netlink messages */ - caps = nm_device_get_capabilities (device); - if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) - return; - - /* Defer carrier-off event actions while connected by a few seconds - * so that tripping over a cable, power-cycling a switch, or breaking - * off the RJ45 locking tab isn't so catastrophic. - */ - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - if (state > NM_DEVICE_STATE_DISCONNECTED) - defer = TRUE; - - set_carrier (self, FALSE, defer); - } -} - static void _update_s390_subchannels (NMDeviceEthernet *self) { @@ -401,75 +240,26 @@ constructor (GType type, GObject *object; NMDeviceEthernetPrivate *priv; NMDevice *self; - guint32 caps; + int itype; object = G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; + if (object) { + self = NM_DEVICE (object); + priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - self = NM_DEVICE (object); - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - - /* s390 stuff */ - _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); - - caps = nm_device_get_capabilities (self); - if (caps & NM_DEVICE_CAP_CARRIER_DETECT) { - GError *error = NULL; - guint32 ifflags = 0; - - /* Only listen to netlink for cards that support carrier detect */ - priv->monitor = nm_netlink_monitor_get (); - - priv->link_connected_id = g_signal_connect (priv->monitor, "carrier-on", - G_CALLBACK (carrier_on), - self); - priv->link_disconnected_id = g_signal_connect (priv->monitor, "carrier-off", - G_CALLBACK (carrier_off), - self); - - /* Get initial link state */ - if (!nm_netlink_monitor_get_flags_sync (priv->monitor, - nm_device_get_ifindex (NM_DEVICE (self)), - &ifflags, - &error)) { - nm_log_warn (LOGD_HW | LOGD_ETHER, - "(%s): couldn't get initial carrier state: (%d) %s", - nm_device_get_iface (NM_DEVICE (self)), - error ? error->code : -1, - (error && error->message) ? error->message : "unknown"); - g_clear_error (&error); - } else - priv->carrier = !!(ifflags & IFF_LOWER_UP); - - nm_log_info (LOGD_HW | LOGD_ETHER, - "(%s): carrier is %s", - nm_device_get_iface (NM_DEVICE (self)), - priv->carrier ? "ON" : "OFF"); - - /* Request link state again just in case an error occurred getting the - * initial link state. - */ - if (!nm_netlink_monitor_request_status (priv->monitor, &error)) { - nm_log_warn (LOGD_HW | LOGD_ETHER, - "(%s): couldn't request carrier state: (%d) %s", - nm_device_get_iface (NM_DEVICE (self)), - error ? error->code : -1, - (error && error->message) ? error->message : "unknown"); - g_clear_error (&error); - } - } else { - nm_log_info (LOGD_HW | LOGD_ETHER, - "(%s): driver '%s' does not support carrier detection.", - nm_device_get_iface (self), - nm_device_get_driver (self)); - priv->carrier = TRUE; + // FIXME: Convert this into a no-export property so type can be specified + // when the device is created. + itype = nm_system_get_iface_type (nm_device_get_ifindex (self), nm_device_get_iface (self)); + g_assert (itype == NM_IFACE_TYPE_UNSPEC); + + nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self))); + + /* s390 stuff */ + _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); } return object; @@ -496,7 +286,6 @@ device_state_changed (NMDevice *device, NMDeviceStateReason reason, gpointer user_data) { - switch (new_state) { case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_FAILED: @@ -544,24 +333,6 @@ real_take_down (NMDevice *dev) } } -static gboolean -real_hw_is_up (NMDevice *device) -{ - return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); -} - -static gboolean -real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) -{ - return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); -} - -static void -real_hw_take_down (NMDevice *dev) -{ - nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); -} - NMDevice * nm_device_ethernet_new (const char *udi, const char *iface, @@ -572,82 +343,24 @@ nm_device_ethernet_new (const char *udi, g_return_val_if_fail (driver != NULL, NULL); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_IFACE, iface, - NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_TYPE_DESC, "Ethernet", - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "Ethernet", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, NULL); } - -/* - * nm_device_ethernet_get_address - * - * Get a device's hardware address - * - */ -void -nm_device_ethernet_get_address (NMDeviceEthernet *self, struct ether_addr *addr) -{ - NMDeviceEthernetPrivate *priv; - - g_return_if_fail (self != NULL); - g_return_if_fail (addr != NULL); - - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - memcpy (addr, &priv->hw_addr, sizeof (priv->hw_addr)); -} - -/* Returns speed in Mb/s */ -static guint32 -nm_device_ethernet_get_speed (NMDeviceEthernet *self) -{ - int fd; - struct ifreq ifr; - struct ethtool_cmd edata = { - .cmd = ETHTOOL_GSET, - }; - guint32 speed = 0; - - g_return_val_if_fail (self != NULL, 0); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); - return 0; - } - - memset (&ifr, 0, sizeof (struct ifreq)); - strncpy (ifr.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - ifr.ifr_data = (char *) &edata; - - if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) - goto out; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - speed = edata.speed; -#else - speed = ethtool_cmd_speed (&edata); -#endif - - if (speed == G_MAXUINT16 || speed == G_MAXUINT32) - speed = 0; - -out: - close (fd); - return speed; -} - static void _update_hw_addr (NMDeviceEthernet *self, const guint8 *addr) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const guint8 *current_addr; g_return_if_fail (addr != NULL); - if (memcmp (&priv->hw_addr, addr, ETH_ALEN)) { - memcpy (&priv->hw_addr, addr, ETH_ALEN); + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)); + if (memcmp (current_addr, addr, ETH_ALEN)) { + nm_device_wired_set_hwaddr (NM_DEVICE_WIRED (self), addr, ETH_ALEN); g_object_notify (G_OBJECT (self), NM_DEVICE_ETHERNET_HW_ADDRESS); } } @@ -656,7 +369,7 @@ static gboolean _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) { NMDevice *dev = NM_DEVICE (self); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const guint8 *current_addr; const char *iface; char *mac_str = NULL; gboolean success = FALSE; @@ -665,18 +378,18 @@ _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) iface = nm_device_get_iface (dev); - mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - /* Do nothing if current MAC is same */ - if (!memcmp (&priv->hw_addr, addr, ETH_ALEN)) { + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)); + if (!memcmp (current_addr, addr, ETH_ALEN)) { nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): no MAC address change needed", iface); - g_free (mac_str); return TRUE; } + mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + /* Can't change MAC address while device is up */ - real_hw_take_down (dev); + nm_device_hw_take_down (dev, FALSE); success = nm_system_iface_set_mac (nm_device_get_ip_ifindex (dev), (struct ether_addr *) addr); if (success) { @@ -688,7 +401,7 @@ _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): failed to %s MAC address to %s", iface, detail, mac_str); } - real_hw_bring_up (dev, NULL); + nm_device_hw_bring_up (dev, FALSE, NULL); g_free (mac_str); return success; @@ -697,28 +410,17 @@ _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) static void real_update_hw_address (NMDevice *dev) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); - struct ifreq req; - int fd; - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); - return; - } + const guint8 *hw_addr; + guint8 old_addr[ETH_ALEN]; - memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + memcpy (old_addr, hw_addr, ETH_ALEN); - errno = 0; - if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) { - nm_log_err (LOGD_HW | LOGD_ETHER, - "(%s) failed to read hardware address (error %d)", - nm_device_get_iface (dev), errno); - } else - _update_hw_addr (self, (const guint8 *) &req.ifr_hwaddr.sa_data); + NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->update_hw_address (dev); - close (fd); + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + if (memcmp (old_addr, hw_addr, ETH_ALEN)) + g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_HW_ADDRESS); } static void @@ -748,10 +450,13 @@ real_update_permanent_hw_address (NMDevice *dev) errno = 0; ret = ioctl (fd, SIOCETHTOOL, &req); if ((ret < 0) || !nm_ethernet_address_is_valid ((struct ether_addr *) epaddr->data)) { + const guint8 *current_addr; + nm_log_err (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", nm_device_get_iface (dev), errno); /* Fall back to current address */ - memcpy (epaddr->data, &priv->hw_addr, ETH_ALEN); + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)); + memcpy (epaddr->data, current_addr, ETH_ALEN); } if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { @@ -767,6 +472,7 @@ real_update_initial_hw_address (NMDevice *dev) { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const guint8 *current_addr; char *mac_str = NULL; guint8 *addr = priv->initial_hw_addr; guint8 zero[ETH_ALEN] = {0,0,0,0,0,0}; @@ -774,11 +480,12 @@ real_update_initial_hw_address (NMDevice *dev) /* This sets initial MAC address from current MAC address. It should only * be called from NMDevice constructor() to really get the initial address. */ - if (!memcmp (&priv->hw_addr, &zero, ETH_ALEN)) + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)); + if (!memcmp (current_addr, &zero, ETH_ALEN)) real_update_hw_address (dev); - if (memcmp (&priv->initial_hw_addr, &priv->hw_addr, ETH_ALEN)) - memcpy (&priv->initial_hw_addr, &priv->hw_addr, ETH_ALEN); + if (memcmp (&priv->initial_hw_addr, current_addr, ETH_ALEN)) + memcpy (&priv->initial_hw_addr, current_addr, ETH_ALEN); mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); @@ -808,34 +515,6 @@ real_get_generic_capabilities (NMDevice *dev) } static gboolean -real_can_interrupt_activation (NMDevice *dev) -{ - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); - gboolean interrupt = FALSE; - - /* Devices that support carrier detect can interrupt activation - * if the link becomes inactive. - */ - if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_CARRIER_DETECT) { - if (NM_DEVICE_ETHERNET_GET_PRIVATE (self)->carrier == FALSE) - interrupt = TRUE; - } - return interrupt; -} - -static gboolean -real_is_available (NMDevice *dev) -{ - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); - - /* Can't do anything if there isn't a carrier */ - if (!NM_DEVICE_ETHERNET_GET_PRIVATE (self)->carrier) - return FALSE; - - return TRUE; -} - -static gboolean match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); @@ -868,74 +547,97 @@ match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_m return TRUE; } +static gboolean +match_ethernet_connection (NMDevice *device, NMConnection *connection, + gboolean check_blacklist, GError **error) +{ + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + NMSettingWired *s_wired; + + s_wired = nm_connection_get_setting_wired (connection); + + if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { + /* NOP */ + } else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { + if (!s_wired) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INVALID, + "The connection was not a valid wired connection."); + return FALSE; + } + } else { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, + "The connection was not a wired, bond, or PPPoE connection."); + return FALSE; + } + + if (s_wired) { + const GByteArray *mac; + gboolean try_mac = TRUE; + const GSList *mac_blacklist, *mac_blacklist_iter; + + if (!match_subchans (self, s_wired, &try_mac)) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's s390 subchannels did not match this device."); + return FALSE; + } + + mac = nm_setting_wired_get_mac_address (s_wired); + if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's MAC address did not match this device."); + return FALSE; + } + + if (!check_blacklist) + return TRUE; + + /* Check for MAC address blacklist */ + mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); + for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; + mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { + struct ether_addr addr; + + if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { + g_warn_if_reached (); + return FALSE; + } + if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's MAC address (%s) is blacklisted in %s.", + (char *) mac_blacklist_iter->data, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + } + + return TRUE; +} + static NMConnection * real_get_best_auto_connection (NMDevice *dev, GSList *connections, char **specific_object) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); GSList *iter; for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); NMSettingConnection *s_con; - NMSettingWired *s_wired; - const char *connection_type; - gboolean is_pppoe = FALSE; - const GSList *mac_blacklist, *mac_blacklist_iter; - gboolean mac_blacklist_found = FALSE; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); - connection_type = nm_setting_connection_get_connection_type (s_con); - if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) - is_pppoe = TRUE; - - if (!is_pppoe && strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)) - continue; - if (!nm_setting_connection_get_autoconnect (s_con)) - continue; - - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); - /* Wired setting optional for PPPoE */ - if (!is_pppoe && !s_wired) - continue; - - if (s_wired) { - const GByteArray *mac; - gboolean try_mac = TRUE; - - if (!match_subchans (self, s_wired, &try_mac)) - continue; - - mac = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) - continue; - - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { - g_warn_if_reached (); - continue; - } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) { - mac_blacklist_found = TRUE; - break; - } - } - /* Found device MAC address in the blacklist - do not use this connection */ - if (mac_blacklist_found) - continue; - } - - return connection; + if ( nm_setting_connection_get_autoconnect (s_con) + && match_ethernet_connection (dev, connection, TRUE, NULL)) + return connection; } + return NULL; } @@ -1096,21 +798,21 @@ time_out: static NMSupplicantConfig * build_supplicant_config (NMDeviceEthernet *self) { - const char *con_path; + const char *con_uuid; NMSupplicantConfig *config = NULL; NMSetting8021x *security; NMConnection *connection; - connection = nm_act_request_get_connection (nm_device_get_act_request (NM_DEVICE (self))); - g_return_val_if_fail (connection, NULL); - con_path = nm_connection_get_path (connection); + connection = nm_device_get_connection (NM_DEVICE (self)); + g_assert (connection); + con_uuid = nm_connection_get_uuid (connection); config = nm_supplicant_config_new (); if (!config) return NULL; - security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); - if (!nm_supplicant_config_add_setting_8021x (config, security, con_path, TRUE)) { + security = nm_connection_get_setting_802_1x (connection); + if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, TRUE)) { nm_log_warn (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); g_object_unref (config); config = NULL; @@ -1353,16 +1055,19 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage1_prepare (dev, reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + req = nm_device_get_act_request (NM_DEVICE (self)); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); - s_wired = NM_SETTING_WIRED (device_get_setting (dev, NM_TYPE_SETTING_WIRED)); - g_assert (s_wired); + s_wired = NM_SETTING_WIRED (device_get_setting (dev, NM_TYPE_SETTING_WIRED)); + g_assert (s_wired); - /* Set device MAC address if the connection wants to change it */ - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - _set_hw_addr (self, (const guint8 *) cloned_mac->data, "set"); + /* Set device MAC address if the connection wants to change it */ + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (cloned_mac && (cloned_mac->len == ETH_ALEN)) + _set_hw_addr (self, (const guint8 *) cloned_mac->data, "set"); + } return ret; } @@ -1376,8 +1081,9 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - connection = nm_act_request_get_connection (nm_device_get_act_request (NM_DEVICE (self))); - security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + connection = nm_device_get_connection (NM_DEVICE (self)); + g_assert (connection); + security = nm_connection_get_setting_802_1x (connection); if (!security) { nm_log_err (LOGD_DEVICE, "Invalid or missing 802.1X security"); *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; @@ -1434,19 +1140,17 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ static void ppp_ip4_config (NMPPPManager *ppp_manager, - const char *iface, - NMIP4Config *config, - gpointer user_data) + const char *iface, + NMIP4Config *config, + gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); /* Ignore PPP IP4 events that come in after initial configuration */ - if (nm_device_get_state (device) != NM_DEVICE_STATE_IP_CONFIG) - return; - - nm_device_set_ip_iface (device, iface); - NM_DEVICE_ETHERNET_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config); - nm_device_activate_schedule_stage4_ip4_config_get (device); + if (nm_device_activate_ip4_state_in_conf (device)) { + nm_device_set_ip_iface (device, iface); + nm_device_activate_schedule_ip4_config_result (device, config); + } } static NMActStageReturn @@ -1465,7 +1169,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas connection = nm_act_request_get_connection (req); g_assert (req); - s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); + s_pppoe = nm_connection_get_setting_pppoe (connection); g_assert (s_pppoe); priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE (self))); @@ -1519,7 +1223,9 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } static NMActStageReturn -real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) +real_act_stage3_ip4_config_start (NMDevice *device, + NMIP4Config **out_config, + NMDeviceStateReason *reason) { NMSettingConnection *s_con; const char *connection_type; @@ -1533,61 +1239,29 @@ real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) return pppoe_stage3_ip4_config_start (NM_DEVICE_ETHERNET (device), reason); - return NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage3_ip4_config_start (device, reason); + return NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage3_ip4_config_start (device, out_config, reason); } -static NMActStageReturn -real_act_stage4_get_ip4_config (NMDevice *device, - NMIP4Config **config, - NMDeviceStateReason *reason) +static void +real_ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMActStageReturn ret; - - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - if (!priv->ppp_manager) { - /* Regular ethernet connection. */ - - /* Chain up to parent */ - ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage4_get_ip4_config (device, config, reason); - - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - NMConnection *connection; - NMSettingWired *s_wired; - guint32 mtu; - - connection = nm_act_request_get_connection (nm_device_get_act_request (device)); - g_assert (connection); - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); - g_assert (s_wired); - - /* MTU override */ - mtu = nm_setting_wired_get_mtu (s_wired); - if (mtu) - nm_ip4_config_set_mtu (*config, mtu); - } - } else { - NMConnection *connection; - NMSettingIP4Config *s_ip4; - - /* PPPoE */ - *config = priv->pending_ip4_config; - priv->pending_ip4_config = NULL; + NMConnection *connection; + NMSettingWired *s_wired; + guint32 mtu; - /* Merge user-defined overrides into the IP4Config to be applied */ - connection = nm_act_request_get_connection (nm_device_get_act_request (device)); - g_assert (connection); - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - nm_utils_merge_ip4_config (*config, s_ip4); + /* MTU only set for plain ethernet */ + if (NM_DEVICE_ETHERNET_GET_PRIVATE (device)->ppp_manager) + return; - ret = NM_ACT_STAGE_RETURN_SUCCESS; - } + connection = nm_device_get_connection (device); + g_assert (connection); + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); - return ret; + /* MTU override */ + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) + nm_ip4_config_set_mtu (config, mtu); } static void @@ -1620,79 +1294,7 @@ real_check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingConnection *s_con; - NMSettingWired *s_wired; - const char *connection_type; - gboolean is_pppoe = FALSE; - const GByteArray *mac; - gboolean try_mac = TRUE; - const GSList *mac_blacklist, *mac_blacklist_iter; - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); - - connection_type = nm_setting_connection_get_connection_type (s_con); - if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME) - && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) { - g_set_error (error, - NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, - "The connection was not a wired or PPPoE connection."); - return FALSE; - } - - if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) - is_pppoe = TRUE; - - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); - /* Wired setting is optional for PPPoE */ - if (!is_pppoe && !s_wired) { - g_set_error (error, - NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INVALID, - "The connection was not a valid wired connection."); - return FALSE; - } - - if (s_wired) { - if (!match_subchans (self, s_wired, &try_mac)) { - g_set_error (error, - NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, - "The connection's s390 subchannels did not match this device."); - return FALSE; - } - - mac = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) { - g_set_error (error, - NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, - "The connection's MAC address did not match this device."); - return FALSE; - } - - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { - g_warn_if_reached (); - continue; - } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) { - g_set_error (error, - NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, - "The connection's MAC address (%s) is blacklisted in %s.", - (char *) mac_blacklist_iter->data, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); - return FALSE; - } - } - } - - // FIXME: check bitrate against device capabilities - - return TRUE; + return match_ethernet_connection (device, connection, TRUE, error); } static gboolean @@ -1707,7 +1309,7 @@ real_complete_connection (NMDevice *device, NMSettingPPPOE *s_pppoe; const GByteArray *setting_mac; - s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); + s_pppoe = nm_connection_get_setting_pppoe (connection); /* We can't telepathically figure out the service name or username, so if * those weren't given, we can't complete the connection. @@ -1725,7 +1327,7 @@ real_complete_connection (NMDevice *device, NULL, s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); @@ -1764,7 +1366,7 @@ spec_match_list (NMDevice *device, const GSList *specs) char *hwaddr; gboolean matched; - hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr); + hwaddr = nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER); matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); @@ -1774,164 +1376,80 @@ spec_match_list (NMDevice *device, const GSList *specs) return matched; } -static gboolean -wired_match_config (NMDevice *self, NMConnection *connection) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingWired *s_wired; - const GByteArray *s_ether; - gboolean try_mac = TRUE; - - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); - if (!s_wired) - return FALSE; - - if (!match_subchans (NM_DEVICE_ETHERNET (self), s_wired, &try_mac)) - return FALSE; - - /* MAC address check */ - s_ether = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && s_ether && memcmp (s_ether->data, priv->perm_hw_addr, ETH_ALEN)) - return FALSE; - - return TRUE; -} - -static gboolean -ip4_match_config (NMDevice *self, NMConnection *connection) -{ - NMSettingIP4Config *s_ip4; - int i, num; - GSList *leases, *iter; - NMDHCPManager *dhcp_mgr; - const char *method; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) - return FALSE; - - /* Get any saved leases that apply to this connection */ - dhcp_mgr = nm_dhcp_manager_get (); - leases = nm_dhcp_manager_get_lease_config (dhcp_mgr, - nm_device_get_iface (self), - nm_connection_get_uuid (connection)); - g_object_unref (dhcp_mgr); - - method = nm_setting_ip4_config_get_method (s_ip4); - if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - gboolean found = FALSE; - - /* Find at least one lease's address on the device */ - for (iter = leases; iter; iter = g_slist_next (iter)) { - NMIP4Config *ip4_config = iter->data; - NMIP4Address *addr = nm_ip4_config_get_address (ip4_config, 0); - struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; - - if (addr && nm_netlink_find_address (nm_device_get_ip_ifindex (self), - AF_INET, - &tmp, - nm_ip4_address_get_prefix (addr))) { - found = TRUE; /* Yay, device has same address as a lease */ - break; - } - } - g_slist_foreach (leases, (GFunc) g_object_unref, NULL); - g_slist_free (leases); - return found; - } else { - /* Maybe the connection used to be DHCP and there are stale leases; ignore them */ - g_slist_foreach (leases, (GFunc) g_object_unref, NULL); - g_slist_free (leases); - } - - /* 'shared' and 'link-local' aren't supported methods because 'shared' - * requires too much iptables and dnsmasq state to be reclaimed, and - * avahi-autoipd isn't smart enough to allow the link-local address to be - * determined at any point other than when it was first assigned. - */ - if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) - return FALSE; - - /* Everything below for static addressing */ - - /* Find all IP4 addresses of this connection on the device */ - num = nm_setting_ip4_config_get_num_addresses (s_ip4); - for (i = 0; i < num; i++) { - NMIP4Address *addr = nm_setting_ip4_config_get_address (s_ip4, i); - struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; - - if (!nm_netlink_find_address (nm_device_get_ip_ifindex (self), - AF_INET, - &tmp, - nm_ip4_address_get_prefix (addr))) - return FALSE; - } - - /* Success; all the connection's static IP addresses are assigned to the device */ - return TRUE; -} - static NMConnection * connection_match_config (NMDevice *self, const GSList *connections) { - GSList *iter; - NMSettingConnection *s_con; + const GSList *iter; + GSList *ether_matches; + NMConnection *match; - for (iter = (GSList *) connections; iter; iter = g_slist_next (iter)) { + /* First narrow @connections down to those that match in their + * NMSettingWired configuration. + */ + ether_matches = NULL; + for (iter = connections; iter; iter = iter->next) { NMConnection *candidate = NM_CONNECTION (iter->data); - s_con = (NMSettingConnection *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRED_SETTING_NAME)) - continue; - /* Can't assume 802.1x or PPPoE connections; they have too much state * that's impossible to get on-the-fly from PPPoE or the supplicant. */ - if ( nm_connection_get_setting (candidate, NM_TYPE_SETTING_802_1X) - || nm_connection_get_setting (candidate, NM_TYPE_SETTING_PPPOE)) + if ( nm_connection_get_setting_802_1x (candidate) + || nm_connection_get_setting_pppoe (candidate)) continue; - if (!wired_match_config (self, candidate)) + if (!match_ethernet_connection (self, candidate, FALSE, NULL)) continue; - if (!ip4_match_config (self, candidate)) - continue; - - return candidate; + ether_matches = g_slist_prepend (ether_matches, candidate); } - return NULL; + /* Now pass those to the super method, which will check IP config */ + ether_matches = g_slist_reverse (ether_matches); + match = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_match_config (self, ether_matches); + g_slist_free (ether_matches); + + return match; } -static void -dispose (GObject *object) +static gboolean +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + NMSettingWired *s_wired; + const guint8 *devaddr; + const GByteArray *mac = NULL; + int devtype; - if (priv->disposed) { - G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); - return; - } + devtype = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (device)); + devaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)); + g_return_val_if_fail (devaddr != NULL, FALSE); - priv->disposed = TRUE; + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) + mac = nm_setting_wired_get_mac_address (s_wired); - if (priv->link_connected_id) { - g_signal_handler_disconnect (priv->monitor, priv->link_connected_id); - priv->link_connected_id = 0; - } - if (priv->link_disconnected_id) { - g_signal_handler_disconnect (priv->monitor, priv->link_disconnected_id); - priv->link_disconnected_id = 0; - } + if (mac) { + g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, devaddr, mac->len) == 0) + return TRUE; + } else if (fail_if_no_hwaddr == FALSE) + return TRUE; - carrier_action_defer_clear (self); + return FALSE; +} - if (priv->monitor) { - g_object_unref (priv->monitor); - priv->monitor = NULL; - } +static void +dispose (GObject *object) +{ + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); g_free (priv->subchan1); g_free (priv->subchan2); @@ -1947,19 +1465,21 @@ get_property (GObject *object, guint prop_id, { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const guint8 *current_addr; switch (prop_id) { case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->hw_addr)); + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (current_addr, ARPHRD_ETHER)); break; case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); break; case PROP_SPEED: - g_value_set_uint (value, nm_device_ethernet_get_speed (self)); + g_value_set_uint (value, nm_device_wired_get_speed (NM_DEVICE_WIRED (self))); break; case PROP_CARRIER: - g_value_set_boolean (value, priv->carrier); + g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (self))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1993,28 +1513,24 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) object_class->set_property = set_property; parent_class->get_generic_capabilities = real_get_generic_capabilities; - parent_class->hw_is_up = real_hw_is_up; - parent_class->hw_bring_up = real_hw_bring_up; - parent_class->hw_take_down = real_hw_take_down; parent_class->is_up = real_is_up; parent_class->bring_up = real_bring_up; parent_class->take_down = real_take_down; - parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->update_hw_address = real_update_hw_address; parent_class->update_permanent_hw_address = real_update_permanent_hw_address; parent_class->update_initial_hw_address = real_update_initial_hw_address; parent_class->get_best_auto_connection = real_get_best_auto_connection; - parent_class->is_available = real_is_available; parent_class->check_connection_compatible = real_check_connection_compatible; parent_class->complete_connection = real_complete_connection; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; - parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; + parent_class->ip4_config_pre_commit = real_ip4_config_pre_commit; parent_class->deactivate = real_deactivate; parent_class->spec_match_list = spec_match_list; parent_class->connection_match_config = connection_match_config; + parent_class->hwaddr_matches = hwaddr_matches; /* properties */ g_object_class_install_property diff --git a/src/nm-device-ethernet.h b/src/nm-device-ethernet.h index b9e2afd4..deb0feca 100644 --- a/src/nm-device-ethernet.h +++ b/src/nm-device-ethernet.h @@ -23,9 +23,8 @@ #define NM_DEVICE_ETHERNET_H #include <glib-object.h> -#include <net/ethernet.h> -#include "nm-device.h" +#include "nm-device-wired.h" G_BEGIN_DECLS @@ -36,17 +35,24 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) #define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) +typedef enum +{ + NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED = 0, /*< nick=ConnectionNotWired >*/ + NM_ETHERNET_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMEthernetError; + #define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address" #define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_CARRIER "carrier" typedef struct { - NMDevice parent; + NMDeviceWired parent; } NMDeviceEthernet; typedef struct { - NMDeviceClass parent; + NMDeviceWiredClass parent; /* Signals */ void (*properties_changed) (NMDeviceEthernet *device, GHashTable *properties); @@ -60,9 +66,6 @@ NMDevice *nm_device_ethernet_new (const char *udi, const char *iface, const char *driver); -void nm_device_ethernet_get_address (NMDeviceEthernet *dev, - struct ether_addr *addr); - G_END_DECLS #endif /* NM_DEVICE_ETHERNET_H */ diff --git a/src/nm-device-factory.h b/src/nm-device-factory.h new file mode 100644 index 00000000..8a4f4467 --- /dev/null +++ b/src/nm-device-factory.h @@ -0,0 +1,91 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_FACTORY_H +#define NM_DEVICE_FACTORY_H + +#include <glib.h> +#include <glib-object.h> +#include <gudev/gudev.h> + +#include "NetworkManager.h" + +/* WARNING: this file is private API between NetworkManager and its internal + * device plugins. Its API can change at any time and is not guaranteed to be + * stable. NM and device plugins are distributed together and this API is + * not meant to enable third-party plugins. + */ + +/** + * nm_device_factory_create_device: + * @device: GUdev device object representing the device + * @devpath: sysfs path of the device + * @ifname: interface name of the device + * @driver: driver of the device + * @error: error for failure information + * + * Creates a #NMDevice subclass if the given information represents a device + * the factory is capable of creating. If the information does represent a + * device the factory is capable of creating, but the device could not be + * created, %NULL should be returned and @error should be set. If the + * factory is not capable of creating a device with the given information + * (ie, the factory creates Ethernet devices but the information represents + * a WiFi device) it should return %NULL and leave @error untouched. + * + * Returns: the device object (a subclass of #NMDevice) or %NULL + */ +GObject *nm_device_factory_create_device (GUdevDevice *device, + const char *devpath, + const char *ifname, + const char *driver, + GError **error); + +/* Should match nm_device_factory() */ +typedef GObject * (*NMDeviceFactoryCreateFunc) (GUdevDevice *device, + const char *devpath, + const char *ifname, + const char *driver, + GError **error); + +/** + * nm_device_factory_get_priority: + * + * Returns the priority of this plugin. Higher numbers mean a higher priority. + * + * Returns: plugin priority + */ +guint32 nm_device_factory_get_priority (void); + +typedef guint32 (*NMDeviceFactoryPriorityFunc) (void); + +/** + * nm_device_factory_get_type: + * + * Returns the type of device this factory can create. Only one factory for + * each type of device is allowed. + * + * Returns: the %NMDeviceType + */ +NMDeviceType nm_device_factory_get_type (void); + +typedef NMDeviceType (*NMDeviceFactoryTypeFunc) (void); + +#endif /* NM_DEVICE_FACTORY_H */ + diff --git a/src/nm-device-infiniband.c b/src/nm-device-infiniband.c new file mode 100644 index 00000000..5e43f060 --- /dev/null +++ b/src/nm-device-infiniband.c @@ -0,0 +1,517 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include <glib/gi18n.h> + +#include <linux/if_infiniband.h> +#include <netinet/ether.h> + +#include "nm-device-infiniband.h" +#include "nm-logging.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-enum-types.h" + +#include "nm-device-infiniband-glue.h" + + +G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE_WIRED) + +#define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate)) + +#define NM_INFINIBAND_ERROR (nm_infiniband_error_quark ()) + +typedef struct { + int dummy; +} NMDeviceInfinibandPrivate; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + + LAST_PROP +}; + +static GQuark +nm_infiniband_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-infiniband-error"); + return quark; +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMDeviceInfinibandPrivate *priv; + NMDevice *self; + + object = G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + self = NM_DEVICE (object); + priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (self); + + nm_log_dbg (LOGD_HW | LOGD_INFINIBAND, "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self))); + + return object; +} + +static void +nm_device_infiniband_init (NMDeviceInfiniband * self) +{ +} + +NMDevice * +nm_device_infiniband_new (const char *udi, + const char *iface, + const char *driver) +{ + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (driver != NULL, NULL); + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "InfiniBand", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, + NULL); +} + + +static void +real_update_hw_address (NMDevice *dev) +{ + const guint8 *hw_addr; + guint8 old_addr[INFINIBAND_ALEN]; + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + memcpy (old_addr, hw_addr, INFINIBAND_ALEN); + + NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->update_hw_address (dev); + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + if (memcmp (old_addr, hw_addr, INFINIBAND_ALEN)) + g_object_notify (G_OBJECT (dev), NM_DEVICE_INFINIBAND_HW_ADDRESS); +} + +static guint32 +real_get_generic_capabilities (NMDevice *dev) +{ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED; +} + +static NMConnection * +real_get_best_auto_connection (NMDevice *dev, + GSList *connections, + char **specific_object) +{ + GSList *iter; + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + NMSettingInfiniband *s_infiniband; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) + continue; + if (!nm_setting_connection_get_autoconnect (s_con)) + continue; + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) + continue; + + if (s_infiniband) { + const guint8 *hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + const GByteArray *mac; + + mac = nm_setting_infiniband_get_mac_address (s_infiniband); + if (mac && memcmp (mac->data, hwaddr, INFINIBAND_ALEN)) + continue; + } + + return connection; + } + return NULL; +} + +static NMActStageReturn +real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +{ + NMActRequest *req; + NMConnection *connection; + NMSettingInfiniband *s_infiniband; + const char *transport_mode; + char *mode_path, *mode_value; + gboolean ok; + + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + req = nm_device_get_act_request (dev); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + s_infiniband = nm_connection_get_setting_infiniband (connection); + g_assert (s_infiniband); + + transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); + + mode_path = g_strdup_printf ("/sys/class/net/%s/mode", nm_device_get_iface (dev)); + if (!g_file_test (mode_path, G_FILE_TEST_EXISTS)) { + g_free (mode_path); + + if (!strcmp (transport_mode, "datagram")) + return NM_ACT_STAGE_RETURN_SUCCESS; + else { + *reason = NM_DEVICE_STATE_REASON_INFINIBAND_MODE; + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + mode_value = g_strdup_printf ("%s\n", transport_mode); + ok = nm_utils_do_sysctl (mode_path, mode_value); + g_free (mode_value); + g_free (mode_path); + + if (!ok) { + *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->act_stage1_prepare (dev, reason); +} + +static void +real_ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) +{ + NMConnection *connection; + NMSettingInfiniband *s_infiniband; + guint32 mtu; + + connection = nm_device_get_connection (self); + g_assert (connection); + s_infiniband = nm_connection_get_setting_infiniband (connection); + g_assert (s_infiniband); + + /* MTU override */ + mtu = nm_setting_infiniband_get_mtu (s_infiniband); + if (mtu) + nm_ip4_config_set_mtu (config, mtu); +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + NMSettingInfiniband *s_infiniband; + const GByteArray *mac; + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { + g_set_error (error, + NM_INFINIBAND_ERROR, + NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND, + "The connection was not an InfiniBand connection."); + return FALSE; + } + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) { + g_set_error (error, + NM_INFINIBAND_ERROR, NM_INFINIBAND_ERROR_CONNECTION_INVALID, + "The connection was not a valid infiniband connection."); + return FALSE; + } + + if (s_infiniband) { + const guint8 *hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)); + + mac = nm_setting_infiniband_get_mac_address (s_infiniband); + if (mac && memcmp (mac->data, hwaddr, INFINIBAND_ALEN)) { + g_set_error (error, + NM_INFINIBAND_ERROR, + NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's MAC address did not match this device."); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMSettingInfiniband *s_infiniband; + const GByteArray *setting_mac; + const guint8 *hwaddr; + + nm_utils_complete_generic (connection, + NM_SETTING_INFINIBAND_SETTING_NAME, + existing_connections, + _("InfiniBand connection %d"), + NULL, + TRUE); + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) { + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); + nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); + } + + hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)); + setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband); + if (setting_mac) { + /* Make sure the setting MAC (if any) matches the device's MAC */ + if (memcmp (setting_mac->data, hwaddr, INFINIBAND_ALEN)) { + g_set_error_literal (error, + NM_SETTING_INFINIBAND_ERROR, + NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY, + NM_SETTING_INFINIBAND_MAC_ADDRESS); + return FALSE; + } + } else { + GByteArray *mac; + + /* Lock the connection to this device by default */ + mac = g_byte_array_sized_new (INFINIBAND_ALEN); + g_byte_array_append (mac, hwaddr, INFINIBAND_ALEN); + g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + } + + if (!nm_setting_infiniband_get_transport_mode (s_infiniband)) + g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + + return TRUE; +} + +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + char *hwaddr; + gboolean matched; + + hwaddr = nm_utils_hwaddr_ntoa (nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)), ARPHRD_INFINIBAND); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + +static gboolean +infiniband_match_config (NMDevice *self, NMConnection *connection) +{ + NMSettingInfiniband *s_infiniband; + const GByteArray *s_mac; + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) + return FALSE; + + /* MAC address check */ + s_mac = nm_setting_infiniband_get_mac_address (s_infiniband); + if (s_mac && memcmp (s_mac->data, nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (self)), INFINIBAND_ALEN)) + return FALSE; + + return TRUE; +} + +static NMConnection * +connection_match_config (NMDevice *self, const GSList *connections) +{ + const GSList *iter; + GSList *infiniband_matches; + NMConnection *match; + + /* First narrow @connections down to those that match in their + * NMSettingInfiniband configuration. + */ + infiniband_matches = NULL; + for (iter = connections; iter; iter = iter->next) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if (!nm_connection_is_type (candidate, NM_SETTING_INFINIBAND_SETTING_NAME)) + continue; + if (!infiniband_match_config (self, candidate)) + continue; + + infiniband_matches = g_slist_prepend (infiniband_matches, candidate); + } + + /* Now pass those to the super method, which will check IP config */ + infiniband_matches = g_slist_reverse (infiniband_matches); + match = NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->connection_match_config (self, infiniband_matches); + g_slist_free (infiniband_matches); + + return match; +} + +static gboolean +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) +{ + NMSettingInfiniband *s_ib; + const guint8 *devaddr; + const GByteArray *mac = NULL; + int devtype; + + devtype = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (device)); + devaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)); + g_return_val_if_fail (devaddr != NULL, FALSE); + + s_ib = nm_connection_get_setting_infiniband (connection); + if (s_ib) + mac = nm_setting_infiniband_get_mac_address (s_ib); + + if (mac) { + g_return_val_if_fail (mac->len == INFINIBAND_ALEN, FALSE); + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == INFINIBAND_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, devaddr, mac->len) == 0) + return TRUE; + } else if (fail_if_no_hwaddr == FALSE) + return TRUE; + + return FALSE; +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + const guint8 *current_addr; + + switch (prop_id) { + case PROP_HW_ADDRESS: + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (object)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (current_addr, ARPHRD_INFINIBAND)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceInfinibandPrivate)); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->set_property = set_property; + + parent_class->get_generic_capabilities = real_get_generic_capabilities; + parent_class->update_hw_address = real_update_hw_address; + parent_class->get_best_auto_connection = real_get_best_auto_connection; + parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; + + parent_class->act_stage1_prepare = real_act_stage1_prepare; + parent_class->ip4_config_pre_commit = real_ip4_config_pre_commit; + parent_class->spec_match_list = spec_match_list; + parent_class->connection_match_config = connection_match_config; + parent_class->hwaddr_matches = hwaddr_matches; + + /* properties */ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_INFINIBAND_HW_ADDRESS, + "Active MAC Address", + "Currently set hardware MAC address", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_INFINIBAND_CARRIER, + "Carrier", + "Carrier", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDeviceInfinibandClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_infiniband_object_info); + + dbus_g_error_domain_register (NM_INFINIBAND_ERROR, NULL, NM_TYPE_INFINIBAND_ERROR); +} diff --git a/src/nm-device-infiniband.h b/src/nm-device-infiniband.h new file mode 100644 index 00000000..fe88c901 --- /dev/null +++ b/src/nm-device-infiniband.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_INFINIBAND_H +#define NM_DEVICE_INFINIBAND_H + +#include <glib-object.h> + +#include "nm-device-wired.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type ()) +#define NM_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) +#define NM_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) +#define NM_IS_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_IS_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_DEVICE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) + +typedef enum { + NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND = 0, /*< nick=ConnectionNotInfiniband >*/ + NM_INFINIBAND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMInfinibandError; + +#define NM_DEVICE_INFINIBAND_HW_ADDRESS "hw-address" +#define NM_DEVICE_INFINIBAND_CARRIER "carrier" + +typedef struct { + NMDeviceWired parent; +} NMDeviceInfiniband; + +typedef struct { + NMDeviceWiredClass parent; + + /* Signals */ + void (*properties_changed) (NMDeviceInfiniband *device, GHashTable *properties); +} NMDeviceInfinibandClass; + + +GType nm_device_infiniband_get_type (void); + +NMDevice *nm_device_infiniband_new (const char *udi, + const char *iface, + const char *driver); + +G_END_DECLS + +#endif /* NM_DEVICE_INFINIBAND_H */ diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c deleted file mode 100644 index fb471f57..00000000 --- a/src/nm-device-interface.c +++ /dev/null @@ -1,433 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. - */ - -#include <dbus/dbus-glib.h> - -#include "nm-marshal.h" -#include "nm-setting-connection.h" -#include "nm-device-interface.h" -#include "nm-logging.h" -#include "nm-properties-changed-signal.h" -#include "nm-rfkill.h" - -static void impl_device_disconnect (NMDeviceInterface *device, - DBusGMethodInvocation *context); - -#include "nm-device-interface-glue.h" - -GQuark -nm_device_interface_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-device-interface-error"); - return quark; -} - -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_device_interface_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection is already activating. */ - ENUM_ENTRY (NM_DEVICE_INTERFACE_ERROR_CONNECTION_ACTIVATING, "ConnectionActivating"), - /* Connection is invalid for this device. */ - ENUM_ENTRY (NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Operation could not be performed because the device is not active. */ - ENUM_ENTRY (NM_DEVICE_INTERFACE_ERROR_NOT_ACTIVE, "NotActive"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMDeviceInterfaceError", values); - } - return etype; -} - - -static void -nm_device_interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - - /* Properties */ - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_DEVICE_INTERFACE_UDI, - "UDI", - "Unique Device Identifier", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_DEVICE_INTERFACE_IFACE, - "Interface", - "Interface", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_DEVICE_INTERFACE_IP_IFACE, - "IP Interface", - "IP Interface", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_DEVICE_INTERFACE_DRIVER, - "Driver", - "Driver", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_DEVICE_INTERFACE_CAPABILITIES, - "Capabilities", - "Capabilities", - 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_DEVICE_INTERFACE_IP4_ADDRESS, - "IP4 address", - "IP4 address", - 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READWRITE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boxed (NM_DEVICE_INTERFACE_IP4_CONFIG, - "IP4 Config", - "IP4 Config", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boxed (NM_DEVICE_INTERFACE_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boxed (NM_DEVICE_INTERFACE_IP6_CONFIG, - "IP6 Config", - "IP6 Config", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boxed (NM_DEVICE_INTERFACE_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_DEVICE_INTERFACE_STATE, - "State", - "State", - 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boxed (NM_DEVICE_INTERFACE_ACTIVE_CONNECTION, - "ActiveConnection", - "ActiveConnection", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_DEVICE_INTERFACE_DEVICE_TYPE, - "DeviceType", - "DeviceType", - 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); - - g_object_interface_install_property - (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_MANAGED, - "Managed", - "Managed", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_FIRMWARE_MISSING, - "FirmwareMissing", - "Firmware missing", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_DEVICE_INTERFACE_TYPE_DESC, - "Type Description", - "Device type description", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); - - g_object_interface_install_property - (g_iface, g_param_spec_uint (NM_DEVICE_INTERFACE_RFKILL_TYPE, - "Rfkill Type", - "Type of rfkill switch (if any) supported by this device", - RFKILL_TYPE_WLAN, - RFKILL_TYPE_MAX, - RFKILL_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); - - g_object_interface_install_property - (g_iface, - g_param_spec_int (NM_DEVICE_INTERFACE_IFINDEX, - "Ifindex", - "Ifindex", - 0, G_MAXINT, 0, - G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT)); - - /* Signals */ - g_signal_new ("state-changed", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceInterface, state_changed), - NULL, NULL, - _nm_marshal_VOID__UINT_UINT_UINT, - G_TYPE_NONE, 3, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); - - g_signal_new (NM_DEVICE_INTERFACE_DISCONNECT_REQUEST, - iface_type, - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - dbus_g_object_type_install_info (iface_type, - &dbus_glib_nm_device_interface_object_info); - - dbus_g_error_domain_register (NM_DEVICE_INTERFACE_ERROR, - NULL, - NM_TYPE_DEVICE_INTERFACE_ERROR); - - initialized = TRUE; -} - - -GType -nm_device_interface_get_type (void) -{ - static GType device_interface_type = 0; - - if (!device_interface_type) { - const GTypeInfo device_interface_info = { - sizeof (NMDeviceInterface), /* class_size */ - nm_device_interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - device_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "NMDeviceInterface", - &device_interface_info, 0); - - g_type_interface_add_prerequisite (device_interface_type, G_TYPE_OBJECT); - } - - return device_interface_type; -} - -/* FIXME: This should be public and nm_device_get_iface() should be removed. */ -static char * -nm_device_interface_get_iface (NMDeviceInterface *device) -{ - char *iface = NULL; - - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), NULL); - - g_object_get (device, NM_DEVICE_INTERFACE_IFACE, &iface, NULL); - - return iface; -} - -gboolean -nm_device_interface_check_connection_compatible (NMDeviceInterface *device, - NMConnection *connection, - GError **error) -{ - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (error != NULL, FALSE); - g_return_val_if_fail (*error == NULL, FALSE); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_compatible) - return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_compatible (device, connection, error); - return TRUE; -} - -gboolean -nm_device_interface_activate (NMDeviceInterface *device, - NMActRequest *req, - GError **error) -{ - gboolean success; - NMConnection *connection; - char *iface; - - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); - - connection = nm_act_request_get_connection (req); - g_assert (connection); - - iface = nm_device_interface_get_iface (device); - nm_log_info (LOGD_DEVICE, "Activation (%s) starting connection '%s'", iface, - nm_connection_get_id (connection)); - g_free (iface); - - success = NM_DEVICE_INTERFACE_GET_INTERFACE (device)->activate (device, req, error); - if (!success) - g_assert (*error); - - return success; -} - -gboolean -nm_device_interface_disconnect (NMDeviceInterface *device, - GError **error) -{ - gboolean success = FALSE; - - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - - switch (nm_device_interface_get_state (device)) { - case NM_DEVICE_STATE_UNKNOWN: - case NM_DEVICE_STATE_UNMANAGED: - case NM_DEVICE_STATE_UNAVAILABLE: - case NM_DEVICE_STATE_DISCONNECTED: - g_set_error_literal (error, - NM_DEVICE_INTERFACE_ERROR, - NM_DEVICE_INTERFACE_ERROR_NOT_ACTIVE, - "Cannot disconnect an inactive device."); - break; - default: - success = NM_DEVICE_INTERFACE_GET_INTERFACE (device)->disconnect (device, error); - break; - } - - return success; -} - -static void -impl_device_disconnect (NMDeviceInterface *device, - DBusGMethodInvocation *context) -{ - g_signal_emit_by_name (device, NM_DEVICE_INTERFACE_DISCONNECT_REQUEST, context); -} - -void -nm_device_interface_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) -{ - g_return_if_fail (NM_IS_DEVICE_INTERFACE (device)); - - NM_DEVICE_INTERFACE_GET_INTERFACE (device)->deactivate (device, reason); -} - -NMDeviceState -nm_device_interface_get_state (NMDeviceInterface *device) -{ - NMDeviceState state; - - g_object_get (G_OBJECT (device), "state", &state, NULL); - return state; -} - -gboolean -nm_device_interface_spec_match_list (NMDeviceInterface *device, - const GSList *specs) -{ - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list) - return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list (device, specs); - return FALSE; -} - -NMConnection * -nm_device_interface_connection_match_config (NMDeviceInterface *device, - const GSList *connections) -{ - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), NULL); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->connection_match_config) - return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->connection_match_config (device, connections); - return NULL; -} - -gboolean -nm_device_interface_can_assume_connections (NMDeviceInterface *device) -{ - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->can_assume_connections) - return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->can_assume_connections (device); - return FALSE; -} - -void -nm_device_interface_set_enabled (NMDeviceInterface *device, gboolean enabled) -{ - g_return_if_fail (NM_IS_DEVICE_INTERFACE (device)); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->set_enabled) - NM_DEVICE_INTERFACE_GET_INTERFACE (device)->set_enabled (device, enabled); -} - -gboolean -nm_device_interface_get_enabled (NMDeviceInterface *device) -{ - g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE); - - if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->get_enabled) - return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->get_enabled (device); - return TRUE; -} - diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h deleted file mode 100644 index 560cdfe5..00000000 --- a/src/nm-device-interface.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. - */ - -#ifndef NM_DEVICE_INTERFACE_H -#define NM_DEVICE_INTERFACE_H - -#include <glib-object.h> -#include "NetworkManager.h" -#include "nm-connection.h" -#include "nm-activation-request.h" - -#define NM_TYPE_DEVICE_INTERFACE (nm_device_interface_get_type ()) -#define NM_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface)) -#define NM_IS_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INTERFACE)) -#define NM_DEVICE_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface)) - -#define IS_ACTIVATING_STATE(state) \ - (state > NM_DEVICE_STATE_DISCONNECTED && state < NM_DEVICE_STATE_ACTIVATED) - -typedef enum -{ - NM_DEVICE_INTERFACE_ERROR_CONNECTION_ACTIVATING = 0, - NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID, - NM_DEVICE_INTERFACE_ERROR_NOT_ACTIVE, -} NMDeviceInterfaceError; - -#define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ()) -#define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ()) - -#define NM_DEVICE_INTERFACE_DISCONNECT_REQUEST "disconnect-request" - -#define NM_DEVICE_INTERFACE_UDI "udi" -#define NM_DEVICE_INTERFACE_IFACE "interface" -#define NM_DEVICE_INTERFACE_IP_IFACE "ip-interface" -#define NM_DEVICE_INTERFACE_DRIVER "driver" -#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" -#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" -#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" -#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" -#define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-config" -#define NM_DEVICE_INTERFACE_DHCP6_CONFIG "dhcp6-config" -#define NM_DEVICE_INTERFACE_STATE "state" -#define NM_DEVICE_INTERFACE_ACTIVE_CONNECTION "active-connection" -#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ -#define NM_DEVICE_INTERFACE_MANAGED "managed" -#define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing" -#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */ - -typedef enum { - NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, - - NM_DEVICE_INTERFACE_PROP_UDI = NM_DEVICE_INTERFACE_PROP_FIRST, - NM_DEVICE_INTERFACE_PROP_IFACE, - NM_DEVICE_INTERFACE_PROP_IP_IFACE, - NM_DEVICE_INTERFACE_PROP_DRIVER, - NM_DEVICE_INTERFACE_PROP_CAPABILITIES, - NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS, - NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, - NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG, - NM_DEVICE_INTERFACE_PROP_IP6_CONFIG, - NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG, - NM_DEVICE_INTERFACE_PROP_STATE, - NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION, - NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, - NM_DEVICE_INTERFACE_PROP_MANAGED, - NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING, - NM_DEVICE_INTERFACE_PROP_TYPE_DESC, - NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE, - NM_DEVICE_INTERFACE_PROP_IFINDEX, -} NMDeviceInterfaceProp; - - -typedef struct _NMDeviceInterface NMDeviceInterface; - -struct _NMDeviceInterface { - GTypeInterface g_iface; - - /* Methods */ - gboolean (*check_connection_compatible) (NMDeviceInterface *device, - NMConnection *connection, - GError **error); - - gboolean (*activate) (NMDeviceInterface *device, - NMActRequest *req, - GError **error); - - void (*deactivate) (NMDeviceInterface *device, NMDeviceStateReason reason); - gboolean (*disconnect) (NMDeviceInterface *device, GError **error); - - gboolean (*spec_match_list) (NMDeviceInterface *device, const GSList *specs); - - NMConnection * (*connection_match_config) (NMDeviceInterface *device, const GSList *specs); - - gboolean (*can_assume_connections) (NMDeviceInterface *device); - - void (*set_enabled) (NMDeviceInterface *device, gboolean enabled); - - gboolean (*get_enabled) (NMDeviceInterface *device); - - /* Signals */ - void (*state_changed) (NMDeviceInterface *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason); -}; - -GQuark nm_device_interface_error_quark (void); -GType nm_device_interface_error_get_type (void); - -gboolean nm_device_interface_disconnect (NMDeviceInterface *device, GError **error); - -GType nm_device_interface_get_type (void); - -gboolean nm_device_interface_check_connection_compatible (NMDeviceInterface *device, - NMConnection *connection, - GError **error); - -gboolean nm_device_interface_activate (NMDeviceInterface *device, - NMActRequest *req, - GError **error); - -void nm_device_interface_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason); - -NMDeviceState nm_device_interface_get_state (NMDeviceInterface *device); - -gboolean nm_device_interface_spec_match_list (NMDeviceInterface *device, - const GSList *specs); - -NMConnection * nm_device_interface_connection_match_config (NMDeviceInterface *device, - const GSList *connections); - -gboolean nm_device_interface_can_assume_connections (NMDeviceInterface *device); - -gboolean nm_device_interface_get_enabled (NMDeviceInterface *device); - -void nm_device_interface_set_enabled (NMDeviceInterface *device, gboolean enabled); - -#endif /* NM_DEVICE_INTERFACE_H */ diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c index 076bfa49..7f81e981 100644 --- a/src/nm-device-modem.c +++ b/src/nm-device-modem.c @@ -21,7 +21,6 @@ #include <glib.h> #include "nm-device-modem.h" -#include "nm-device-interface.h" #include "nm-modem.h" #include "nm-modem-cdma.h" #include "nm-modem-gsm.h" @@ -31,10 +30,7 @@ #include "nm-marshal.h" #include "nm-logging.h" -static void device_interface_init (NMDeviceInterface *iface_class); - -G_DEFINE_TYPE_EXTENDED (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) +G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) #define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MODEM, NMDeviceModemPrivate)) @@ -60,7 +56,7 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; -static void real_set_enabled (NMDeviceInterface *device, gboolean enabled); +static void real_set_enabled (NMDevice *device, gboolean enabled); /*****************************************************************************/ @@ -69,17 +65,19 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); - switch (nm_device_interface_get_state (NM_DEVICE_INTERFACE (device))) { + switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: case NM_DEVICE_STATE_NEED_AUTH: - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_ACTIVATED: nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); break; case NM_DEVICE_STATE_IP_CONFIG: - if (nm_device_ip_config_should_fail (device, FALSE)) { + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + if (nm_device_activate_ip4_state_in_conf (device)) + nm_device_activate_schedule_ip4_config_timeout (device); + else { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -99,7 +97,7 @@ modem_prepare_result (NMModem *modem, NMDevice *device = NM_DEVICE (user_data); NMDeviceState state; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); + state = nm_device_get_state (device); g_return_if_fail (state == NM_DEVICE_STATE_PREPARE); if (success) @@ -140,10 +138,8 @@ modem_ip4_config_result (NMModem *self, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); - NMDeviceState state; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); - g_return_if_fail (state == NM_DEVICE_STATE_IP_CONFIG); + g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { nm_log_warn (LOGD_MB | LOGD_IP4, "retrieving IP4 configuration failed: (%d) %s", @@ -155,7 +151,7 @@ modem_ip4_config_result (NMModem *self, if (iface) nm_device_set_ip_iface (device, iface); - nm_device_activate_schedule_stage4_ip4_config_get (device); + nm_device_activate_schedule_ip4_config_result (device, config); } } @@ -165,7 +161,7 @@ modem_enabled_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) NMDeviceModem *self = NM_DEVICE_MODEM (user_data); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - real_set_enabled (NM_DEVICE_INTERFACE (self), nm_modem_get_mm_enabled (priv->modem)); + real_set_enabled (NM_DEVICE (self), nm_modem_get_mm_enabled (priv->modem)); g_signal_emit (G_OBJECT (self), signals[ENABLE_CHANGED], 0); } @@ -275,7 +271,9 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } static NMActStageReturn -real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) +real_act_stage3_ip4_config_start (NMDevice *device, + NMIP4Config **out_config, + NMDeviceStateReason *reason) { return nm_modem_stage3_ip4_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, @@ -284,27 +282,26 @@ real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) } static NMActStageReturn -real_act_stage4_get_ip4_config (NMDevice *device, - NMIP4Config **config, - NMDeviceStateReason *reason) +real_act_stage3_ip6_config_start (NMDevice *device, + NMIP6Config **out_config, + NMDeviceStateReason *reason) { - return nm_modem_stage4_get_ip4_config (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), - config, - reason); + return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, + device, + NM_DEVICE_CLASS (nm_device_modem_parent_class), + reason); } /*****************************************************************************/ static gboolean -real_get_enabled (NMDeviceInterface *device) +real_get_enabled (NMDevice *device) { return nm_modem_get_mm_enabled (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem); } static void -real_set_enabled (NMDeviceInterface *device, gboolean enabled) +real_set_enabled (NMDevice *device, gboolean enabled) { NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); @@ -314,7 +311,7 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) nm_modem_set_mm_enabled (priv->modem, enabled); if (enabled == FALSE) { - state = nm_device_interface_get_state (device); + state = nm_device_get_state (NM_DEVICE (device)); if (state == NM_DEVICE_STATE_ACTIVATED) { nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_DISCONNECTED, @@ -348,12 +345,12 @@ nm_device_modem_new (NMModem *modem, const char *driver) } return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MODEM, - NM_DEVICE_INTERFACE_UDI, nm_modem_get_path (modem), - NM_DEVICE_INTERFACE_IFACE, nm_modem_get_iface (modem), - NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_TYPE_DESC, type_desc, - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM, - NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WWAN, + NM_DEVICE_UDI, nm_modem_get_path (modem), + NM_DEVICE_IFACE, nm_modem_get_iface (modem), + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, type_desc, + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM, + NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WWAN, NM_DEVICE_MODEM_MODEM, modem, NM_DEVICE_MODEM_CAPABILITIES, caps, NM_DEVICE_MODEM_CURRENT_CAPABILITIES, caps, @@ -361,13 +358,6 @@ nm_device_modem_new (NMModem *modem, const char *driver) } static void -device_interface_init (NMDeviceInterface *iface_class) -{ - iface_class->get_enabled = real_get_enabled; - iface_class->set_enabled = real_set_enabled; -} - -static void nm_device_modem_init (NMDeviceModem *self) { g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), self); @@ -469,7 +459,9 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->act_stage1_prepare = real_act_stage1_prepare; device_class->act_stage2_config = real_act_stage2_config; device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; - device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; + device_class->act_stage3_ip6_config_start = real_act_stage3_ip6_config_start; + device_class->get_enabled = real_get_enabled; + device_class->set_enabled = real_set_enabled; /* Properties */ g_object_class_install_property diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index ddd5198e..f6390c16 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -31,16 +31,18 @@ #include <netinet/in.h> #include <string.h> #include <net/ethernet.h> -#include <iwlib.h> +#include <netinet/ether.h> #include <sys/stat.h> #include <sys/wait.h> #include <signal.h> #include <unistd.h> +#include <linux/if.h> +#include <sys/ioctl.h> +#include <errno.h> #include "nm-device.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" -#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-utils.h" #include "nm-logging.h" @@ -51,6 +53,8 @@ #include "nm-setting-olpc-mesh.h" #include "nm-system.h" #include "nm-manager.h" +#include "nm-enum-types.h" +#include "wifi-utils.h" /* This is a bug; but we can't really change API now... */ #include "NetworkManagerVPN.h" @@ -58,8 +62,6 @@ #include "nm-device-olpc-mesh-glue.h" -static void nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid); - G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) #define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) @@ -82,15 +84,7 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef enum -{ - NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH = 0, - NM_OLPC_MESH_ERROR_CONNECTION_INVALID, - NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, -} NMOlpcMeshError; - #define NM_OLPC_MESH_ERROR (nm_olpc_mesh_error_quark ()) -#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ()) struct _NMDeviceOlpcMeshPrivate @@ -101,8 +95,7 @@ struct _NMDeviceOlpcMeshPrivate GByteArray * ssid; - gint8 num_freqs; - guint32 freqs[IW_MAX_FREQUENCIES]; + WifiData * wifi_data; gboolean up; @@ -120,29 +113,6 @@ nm_olpc_mesh_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_olpc_mesh_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a wireless connection. */ - ENUM_ENTRY (NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "ConnectionNotMesh"), - /* Connection was not a valid wireless connection. */ - ENUM_ENTRY (NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMOlpcMeshError", values); - } - return etype; -} - static guint32 real_get_generic_capabilities (NMDevice *dev) { @@ -161,44 +131,6 @@ nm_device_olpc_mesh_init (NMDeviceOlpcMesh * self) memset (&(priv->hw_addr), 0, sizeof (struct ether_addr)); } -static guint32 iw_freq_to_uint32 (struct iw_freq *freq) -{ - if (freq->e == 0) { - /* Some drivers report channel not frequency. Convert to a - * frequency; but this assumes that the device is in b/g mode. - */ - if ((freq->m >= 1) && (freq->m <= 13)) - return 2407 + (5 * freq->m); - else if (freq->m == 14) - return 2484; - } - - return (guint32) (((double) freq->m) * pow (10, freq->e) / 1000000); -} - - -/* Until a new wireless-tools comes out that has the defs and the structure, - * need to copy them here. - */ -/* Scan capability flags - in (struct iw_range *)->scan_capa */ -#define NM_IW_SCAN_CAPA_NONE 0x00 -#define NM_IW_SCAN_CAPA_ESSID 0x01 - -struct iw_range_with_scan_capa -{ - guint32 throughput; - guint32 min_nwid; - guint32 max_nwid; - guint16 old_num_channels; - guint8 old_num_frequency; - - guint8 scan_capa; -/* don't need the rest... */ -}; - - - - static GObject* constructor (GType type, guint n_construct_params, @@ -208,11 +140,6 @@ constructor (GType type, GObjectClass *klass; NMDeviceOlpcMesh *self; NMDeviceOlpcMeshPrivate *priv; - const char *iface; - int fd; - struct iw_range range; - struct iwreq wrq; - int i; klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class); object = klass->constructor (type, n_construct_params, construct_params); @@ -226,46 +153,19 @@ constructor (GType type, nm_device_get_iface (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); - iface = nm_device_get_iface (NM_DEVICE (self)); - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - goto error; - - memset (&wrq, 0, sizeof (struct iwreq)); - memset (&range, 0, sizeof (struct iw_range)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - wrq.u.data.pointer = (caddr_t) ⦥ - wrq.u.data.length = sizeof (struct iw_range); - - if (ioctl (fd, SIOCGIWRANGE, &wrq) < 0) { - nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed", + priv->wifi_data = wifi_utils_init (nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self)), + FALSE); + if (priv->wifi_data == NULL) { + nm_log_warn (LOGD_HW | LOGD_OLPC_MESH, "(%s): failed to initialize WiFi driver", nm_device_get_iface (NM_DEVICE (self))); - goto error; - } - - if ((wrq.u.data.length < 300) || (range.we_version_compiled < 21)) { - nm_log_info (LOGD_HW | LOGD_WIFI, - "(%s): driver WEXT version too old (got %d, expected >= 21)", - nm_device_get_iface (NM_DEVICE (self)), - range.we_version_compiled); - goto error; + g_object_unref (object); + return NULL; } - priv->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); - for (i = 0; i < priv->num_freqs; i++) - priv->freqs[i] = iw_freq_to_uint32 (&range.freq[i]); - - close (fd); - /* shorter timeout for mesh connectivity */ nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); return object; - -error: - if (fd >= 0) - close (fd); - g_object_unref (object); - return NULL; } static gboolean @@ -331,7 +231,7 @@ real_check_connection_compatible (NMDevice *device, NMSettingConnection *s_con; NMSettingOlpcMesh *s_mesh; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_OLPC_MESH_SETTING_NAME)) { @@ -341,7 +241,7 @@ real_check_connection_compatible (NMDevice *device, return FALSE; } - s_mesh = NM_SETTING_OLPC_MESH (nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH)); + s_mesh = nm_connection_get_setting_olpc_mesh (connection); if (!s_mesh) { g_set_error (error, NM_OLPC_MESH_ERROR, NM_OLPC_MESH_ERROR_CONNECTION_INVALID, @@ -364,7 +264,7 @@ real_complete_connection (NMDevice *device, NMSettingOlpcMesh *s_mesh; GByteArray *tmp; - s_mesh = (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH); + s_mesh = nm_connection_get_setting_olpc_mesh (connection); if (!s_mesh) { s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new (); nm_connection_add_setting (connection, NM_SETTING (s_mesh)); @@ -414,131 +314,6 @@ nm_device_olpc_mesh_get_address (NMDeviceOlpcMesh *self, memcpy (addr, &(priv->hw_addr), sizeof (struct ether_addr)); } -static int -create_socket_with_request (NMDevice *self, struct iwreq *req) -{ - int sk; - const char * iface; - - g_return_val_if_fail (self != NULL, -1); - - sk = socket (AF_INET, SOCK_DGRAM, 0); - if (sk == -1) { - nm_log_err (LOGD_OLPC_MESH, "Couldn't create socket: %d.", errno); - return -1; - } - - memset (req, 0, sizeof (struct iwreq)); - iface = nm_device_get_iface (NM_DEVICE (self)); - strncpy (req->ifr_name, iface, IFNAMSIZ); - - return sk; -} - -static guint32 -nm_device_olpc_mesh_get_channel (NMDeviceOlpcMesh *self) -{ - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - int sk; - struct iwreq req; - int ret = 0; - int i; - guint32 freq; - - sk = create_socket_with_request (NM_DEVICE (self), &req); - if (sk == -1) - return 0; - - if ((ioctl (sk, SIOCGIWFREQ, &req)) != 0) { - nm_log_warn (LOGD_OLPC_MESH, "(%s): failed to get channel (errno: %d)", - nm_device_get_iface (NM_DEVICE (self)), errno); - goto out; - } - - freq = iw_freq_to_uint32 (&req.u.freq); - - for (i = 0 ; i < priv->num_freqs; i++) { - if (freq == priv->freqs[i]) - break; - } - if (i < priv->num_freqs) - ret = i + 1; - -out: - if (sk >= 0) - close (sk); - return ret; -} - -static void -nm_device_olpc_mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) -{ - int sk; - struct iwreq req; - - if (nm_device_olpc_mesh_get_channel (self) == channel) - return; - - sk = create_socket_with_request (NM_DEVICE (self), &req); - if (sk < 0) - return; - - if (channel > 0) { - req.u.freq.flags = IW_FREQ_FIXED; - req.u.freq.e = 0; - req.u.freq.m = channel; - } - - if (ioctl (sk, SIOCSIWFREQ, &req) != 0) { - nm_log_warn (LOGD_OLPC_MESH, "(%s): failed to set to channel %d (errno: %d)", - nm_device_get_iface (NM_DEVICE (self)), channel, errno); - } else - g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL); - - close (sk); -} - -static void -nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid) -{ - int sk; - struct iwreq wrq; - const char * iface; - guint32 len = 0; - char buf[IW_ESSID_MAX_SIZE + 1]; - - g_return_if_fail (self != NULL); - - sk = socket (AF_INET, SOCK_DGRAM, 0); - if (sk == -1) { - nm_log_err (LOGD_OLPC_MESH, "Couldn't create socket: %d.", errno); - return; - } - - iface = nm_device_get_iface (NM_DEVICE (self)); - - memset (buf, 0, sizeof (buf)); - if (ssid) { - len = ssid->len; - memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len)); - } - wrq.u.essid.pointer = (caddr_t) buf; - wrq.u.essid.length = len; - wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */ - - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - if (ioctl (sk, SIOCSIWESSID, &wrq) < 0) { - if (errno != ENODEV) { - nm_log_err (LOGD_OLPC_MESH, "(%s): error setting SSID to '%s': %s", - iface, - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(null)", - strerror (errno)); - } - } - - close (sk); -} - /****************************************************************************/ static void @@ -605,30 +380,38 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_SUCCESS; } +static void +_mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) +{ + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); + + if (wifi_utils_get_mesh_channel (priv->wifi_data) != channel) { + if (wifi_utils_set_mesh_channel (priv->wifi_data, channel)) + g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL); + } +} + static NMActStageReturn real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); NMConnection *connection; NMSettingOlpcMesh *s_mesh; - NMActRequest *req; guint32 channel; const GByteArray *anycast_addr_array; guint8 *anycast_addr = NULL; - req = nm_device_get_act_request (dev); - g_assert (req); - - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (dev); g_assert (connection); - s_mesh = NM_SETTING_OLPC_MESH (nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH)); + s_mesh = nm_connection_get_setting_olpc_mesh (connection); g_assert (s_mesh); channel = nm_setting_olpc_mesh_get_channel (s_mesh); if (channel != 0) - nm_device_olpc_mesh_set_channel (self, channel); - nm_device_olpc_mesh_set_ssid (self, nm_setting_olpc_mesh_get_ssid (s_mesh)); + _mesh_set_channel (self, channel); + wifi_utils_set_mesh_ssid (priv->wifi_data, nm_setting_olpc_mesh_get_ssid (s_mesh)); anycast_addr_array = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); if (anycast_addr_array) @@ -651,6 +434,9 @@ dispose (GObject *object) } priv->dispose_has_run = TRUE; + if (priv->wifi_data) + wifi_utils_deinit (priv->wifi_data); + device_cleanup (self); manager = nm_manager_get (); @@ -672,7 +458,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: nm_device_olpc_mesh_get_address (device, &hw_addr); - g_value_take_string (value, nm_ether_ntop (&hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&hw_addr, ARPHRD_ETHER)); break; case PROP_COMPANION: if (priv->companion) @@ -681,7 +467,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boxed (value, "/"); break; case PROP_ACTIVE_CHANNEL: - g_value_set_uint (value, nm_device_olpc_mesh_get_channel (device)); + g_value_set_uint (value, wifi_utils_get_mesh_channel (priv->wifi_data)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -810,9 +596,7 @@ static gboolean companion_scan_allowed_cb (NMDeviceWifi *companion, gpointer user_data) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceState state; - - g_object_get (G_OBJECT (self), NM_DEVICE_INTERFACE_STATE, &state, NULL); + NMDeviceState state = nm_device_get_state (NM_DEVICE (self)); /* Don't allow the companion to scan while configuring the mesh interface */ return (state < NM_DEVICE_STATE_PREPARE) || (state > NM_DEVICE_STATE_IP_CONFIG); @@ -822,9 +606,7 @@ static gboolean companion_autoconnect_allowed_cb (NMDeviceWifi *companion, gpointer user_data) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceState state; - - g_object_get (G_OBJECT (self), NM_DEVICE_INTERFACE_STATE, &state, NULL); + NMDeviceState state = nm_device_get_state (NM_DEVICE (self)); /* Don't allow the companion to autoconnect while a mesh connection is * active */ @@ -961,11 +743,11 @@ nm_device_olpc_mesh_new (const char *udi, g_return_val_if_fail (driver != NULL, NULL); obj = g_object_new (NM_TYPE_DEVICE_OLPC_MESH, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_IFACE, iface, - NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 OLPC Mesh", - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "802.11 OLPC Mesh", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH, NULL); if (obj == NULL) return NULL; diff --git a/src/nm-device-olpc-mesh.h b/src/nm-device-olpc-mesh.h index bcc03e57..9d42ecfa 100644 --- a/src/nm-device-olpc-mesh.h +++ b/src/nm-device-olpc-mesh.h @@ -42,6 +42,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OLPC_MESH)) #define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) +typedef enum +{ + NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH = 0, /*< nick=ConnectionNotMesh >*/ + NM_OLPC_MESH_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMOlpcMeshError; + #define NM_DEVICE_OLPC_MESH_HW_ADDRESS "hw-address" #define NM_DEVICE_OLPC_MESH_COMPANION "companion" #define NM_DEVICE_OLPC_MESH_BITRATE "bitrate" diff --git a/src/nm-device-private.h b/src/nm-device-private.h index a7d238b1..9b78db12 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -24,26 +24,47 @@ #include "nm-device.h" +/* This file should only be used by subclasses of NMDevice */ + +enum NMActStageReturn { + NM_ACT_STAGE_RETURN_FAILURE = 0, + NM_ACT_STAGE_RETURN_SUCCESS, + NM_ACT_STAGE_RETURN_POSTPONE, + NM_ACT_STAGE_RETURN_STOP /* This activation chain is done */ +}; + void nm_device_set_ip_iface (NMDevice *self, const char *iface); void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device); -void nm_device_state_changed (NMDevice *device, - NMDeviceState state, - NMDeviceStateReason reason); - gboolean nm_device_hw_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmware); void nm_device_hw_take_down (NMDevice *self, gboolean block); -void nm_device_handle_autoip4_event (NMDevice *self, - const char *event, - const char *address); - gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6); -gboolean nm_device_get_firmware_missing (NMDevice *self); - void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); +guint32 nm_device_get_capabilities (NMDevice *dev); +guint32 nm_device_get_type_capabilities (NMDevice *dev); + +void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); +void nm_device_activate_schedule_stage2_device_config (NMDevice *device); + +void nm_device_activate_schedule_ip4_config_result(NMDevice *device, NMIP4Config *config); +void nm_device_activate_schedule_ip4_config_timeout (NMDevice *device); + +void nm_device_activate_schedule_ip6_config_result (NMDevice *device, NMIP6Config *config); +void nm_device_activate_schedule_ip6_config_timeout (NMDevice *device); + +gboolean nm_device_activate_ip4_state_in_conf (NMDevice *device); +gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device); + +void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); +void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); + +gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); + +gboolean nm_device_match_ip_config (NMDevice *device, NMConnection *connection); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device-vlan.c b/src/nm-device-vlan.c new file mode 100644 index 00000000..14be849f --- /dev/null +++ b/src/nm-device-vlan.c @@ -0,0 +1,803 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2011 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include <glib/gi18n.h> + +#include <sys/socket.h> +#include <linux/if.h> +#include <netinet/ether.h> + +#include "nm-device-vlan.h" +#include "nm-logging.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-netlink-monitor.h" +#include "nm-enum-types.h" +#include "nm-system.h" + +#include "nm-device-vlan-glue.h" + + +G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate)) + +#define NM_VLAN_ERROR (nm_vlan_error_quark ()) + +typedef struct { + gboolean disposed; + + NMDevice *parent; + guint parent_state_id; + + guint vlan_id; + + guint8 hw_addr[NM_UTILS_HWADDR_LEN_MAX]; + guint hw_addr_len; + + gboolean carrier; + NMNetlinkMonitor *monitor; + gulong link_connected_id; + gulong link_disconnected_id; + guint carrier_action_defer_id; +} NMDeviceVlanPrivate; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_VLAN_ID, + + LAST_PROP +}; + +static void +set_carrier (NMDeviceVlan *self, + const gboolean carrier, + const gboolean defer_action); + +/******************************************************************/ + +static GQuark +nm_vlan_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-vlan-error"); + return quark; +} + +/******************************************************************/ + +static guint32 +real_get_generic_capabilities (NMDevice *dev) +{ + /* We assume VLAN interfaces always support carrier detect */ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED; +} + +static gboolean +get_carrier_sync (NMDeviceVlan *self) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + GError *error = NULL; + guint32 ifflags = 0; + + /* Get initial link state */ + if (!nm_netlink_monitor_get_flags_sync (priv->monitor, + nm_device_get_ip_ifindex (NM_DEVICE (self)), + &ifflags, + &error)) { + nm_log_warn (LOGD_HW | LOGD_DEVICE, + "(%s): couldn't get carrier state: (%d) %s", + nm_device_get_ip_iface (NM_DEVICE (self)), + error ? error->code : -1, + (error && error->message) ? error->message : "unknown"); + g_clear_error (&error); + } + + return !!(ifflags & IFF_LOWER_UP); +} + +static gboolean +real_hw_is_up (NMDevice *device) +{ + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); +} + +static gboolean +real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) +{ + gboolean success = FALSE, carrier; + guint i = 20; + + while (i-- > 0 && !success) { + success = nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); + g_usleep (50); + } + + if (success) { + /* Block a bit to make sure the carrier comes on; it's delayed a bit + * after setting the interface up. + */ + i = 20; + while (i-- > 0) { + carrier = get_carrier_sync (NM_DEVICE_VLAN (dev)); + set_carrier (NM_DEVICE_VLAN (dev), carrier, carrier ? FALSE : TRUE); + if (carrier) + break; + g_usleep (100); + } + } + return success; +} + +static void +real_hw_take_down (NMDevice *dev) +{ + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); +} + +static void +real_update_hw_address (NMDevice *dev) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (dev); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + struct rtnl_link *rtnl; + struct nl_addr *addr; + + rtnl = nm_netlink_index_to_rtnl_link (nm_device_get_ip_ifindex (dev)); + if (!rtnl) { + nm_log_err (LOGD_HW | LOGD_DEVICE, + "(%s) failed to read hardware address (error %d)", + nm_device_get_iface (dev), errno); + return; + } + + addr = rtnl_link_get_addr (rtnl); + if (!addr) { + nm_log_err (LOGD_HW | LOGD_DEVICE, + "(%s) no hardware address?", + nm_device_get_iface (dev)); + goto out; + } + + if (nl_addr_get_len (addr) > sizeof (priv->hw_addr)) { + nm_log_err (LOGD_HW | LOGD_DEVICE, + "(%s) hardware address is wrong length (got %d max %zd)", + nm_device_get_iface (dev), + nl_addr_get_len (addr), + sizeof (priv->hw_addr)); + } else { + priv->hw_addr_len = nl_addr_get_len (addr); + memcpy (&priv->hw_addr, nl_addr_get_binary_addr (addr), priv->hw_addr_len); + g_object_notify (G_OBJECT (self), NM_DEVICE_VLAN_HW_ADDRESS); + } + +out: + rtnl_link_put (rtnl); +} + +static gboolean +real_can_interrupt_activation (NMDevice *dev) +{ + /* Can interrupt activation if the carrier drops while activating */ + return NM_DEVICE_VLAN_GET_PRIVATE (dev)->carrier ? FALSE : TRUE; +} + +static gboolean +real_is_available (NMDevice *dev) +{ + return NM_DEVICE_VLAN_GET_PRIVATE (dev)->carrier ? TRUE : FALSE; +} + +/******************************************************************/ + +static gboolean +match_parent (NMDeviceVlan *self, const char *parent, GError **error) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + g_return_val_if_fail (parent != NULL, FALSE); + + if (nm_utils_is_uuid (parent)) { + NMActRequest *parent_req; + NMConnection *parent_connection; + + /* If the parent is a UUID, the connection matches if our parent + * device has that connection activated. + */ + + parent_req = nm_device_get_act_request (priv->parent); + if (!parent_req) { + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "Parent interface not active; could not match UUID"); + return FALSE; + } + + parent_connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (parent_req)); + if (!parent_connection) { + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "Parent interface had no connection; could not match UUID"); + return FALSE; + } + if (g_strcmp0 (parent, nm_connection_get_uuid (parent_connection)) != 0) { + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "Parent interface UUID did not match connection UUID"); + return FALSE; + } + } else { + /* interface name */ + if (g_strcmp0 (parent, nm_device_get_ip_iface (priv->parent)) != 0) { + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "Parent interface name did not match connection"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +match_vlan_connection (NMDeviceVlan *self, NMConnection *connection, GError **error) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + NMSettingVlan *s_vlan; + const char *parent, *iface = NULL; + + s_vlan = nm_connection_get_setting_vlan (connection); + if (!s_vlan) { + g_set_error (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "The connection was not a VLAN connection."); + return FALSE; + } + + if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id) { + g_set_error (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "The connection's VLAN ID did not match the device's VLAN ID."); + return FALSE; + } + + /* Check parent interface; could be an interface name or a UUID */ + parent = nm_setting_vlan_get_parent (s_vlan); + if (parent) { + if (!match_parent (self, parent, error)) + return FALSE; + } else { + /* Parent could be a MAC address in a hardware-specific setting */ + if (!nm_device_hwaddr_matches (priv->parent, connection, NULL, 0, TRUE)) { + g_set_error (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "Failed to match the VLAN parent interface via hardware address."); + return FALSE; + } + } + + /* Ensure the interface name matches. If not specified we assume a match + * since both the parent interface and the VLAN ID matched by the time we + * get here. + */ + iface = nm_connection_get_virtual_iface_name (connection); + if (iface) { + if (g_strcmp0 (nm_device_get_ip_iface (NM_DEVICE (self)), iface) != 0) { + g_set_error (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "The VLAN connection virtual interface name did not match."); + return FALSE; + } + } + + return TRUE; +} + +static NMConnection * +real_get_best_auto_connection (NMDevice *dev, + GSList *connections, + char **specific_object) +{ + GSList *iter; + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + if ( nm_setting_connection_get_autoconnect (s_con) + && match_vlan_connection (NM_DEVICE_VLAN (dev), connection, NULL)) + return connection; + } + return NULL; +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + return match_vlan_connection (NM_DEVICE_VLAN (device), connection, error); +} + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + NMSettingVlan *s_vlan; + + nm_utils_complete_generic (connection, + NM_SETTING_VLAN_SETTING_NAME, + existing_connections, + _("VLAN connection %d"), + NULL, + TRUE); + + s_vlan = nm_connection_get_setting_vlan (connection); + if (!s_vlan) { + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "A 'vlan' setting is required."); + return FALSE; + } + + /* If there's no VLAN interface, no parent, and no hardware address in the + * settings, then there's not enough information to complete the setting. + */ + if (!nm_setting_vlan_get_parent (s_vlan)) { + if (!nm_device_hwaddr_matches (priv->parent, connection, NULL, 0, TRUE)) { + /* FIXME: put priv->hw_addr into the connection in the appropriate + * hardware-specific setting. + */ + g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + "The 'vlan' setting had no interface name, parent, or hardware address."); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + char *hwaddr; + gboolean matched; + int itype = nm_utils_hwaddr_type (priv->hw_addr_len); + + hwaddr = nm_utils_hwaddr_ntoa (priv->hw_addr, itype); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + +static gboolean +vlan_match_config (NMDevice *device, NMConnection *connection) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + NMSettingVlan *s_vlan; + const char *ifname, *parent; + gboolean fail_if_no_hwaddr = FALSE; + + s_vlan = nm_connection_get_setting_vlan (connection); + if (!s_vlan) + return FALSE; + + /* Interface name */ + ifname = nm_setting_vlan_get_interface_name (s_vlan); + if (g_strcmp0 (ifname, nm_device_get_ip_iface (device)) != 0) + return FALSE; + + if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id) + return FALSE; + + parent = nm_setting_vlan_get_parent (s_vlan); + if (parent) { + if (!match_parent (NM_DEVICE_VLAN (device), parent, NULL)) + return FALSE; + } else { + /* If there's no parent and no interface name given, then the only way + * we have to identify the VLAN interface the connection matches is + * a hardware-specific setting's hardware address property, so we want + * to fail the match below if we there is none. + */ + if (ifname == NULL) + fail_if_no_hwaddr = TRUE; + } + + /* MAC address check; we ask the parent to check our own MAC address, + * because only the parent knows what kind of NMSetting the MAC + * address will be in. The VLAN device shouldn't have to know what kind + * of interface the parent is. + */ + if (!nm_device_hwaddr_matches (priv->parent, connection, priv->hw_addr, priv->hw_addr_len, fail_if_no_hwaddr)) + return FALSE; + + return TRUE; +} + +static NMConnection * +connection_match_config (NMDevice *self, const GSList *connections) +{ + const GSList *iter; + + /* First narrow @connections down to those that match in their + * NMSettingVlan configuration. + */ + for (iter = connections; iter; iter = iter->next) { + NMConnection *candidate = iter->data; + + if (!nm_connection_is_type (candidate, NM_SETTING_VLAN_SETTING_NAME)) + continue; + if (!vlan_match_config (self, candidate)) + continue; + if (!nm_device_match_ip_config (self, candidate)) + continue; + + return candidate; + } + return NULL; +} + +/******************************************************************/ + +static void +carrier_action_defer_clear (NMDeviceVlan *self) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + if (priv->carrier_action_defer_id) { + g_source_remove (priv->carrier_action_defer_id); + priv->carrier_action_defer_id = 0; + } +} + +static gboolean +carrier_action_defer_cb (gpointer user_data) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + NMDeviceState state; + + priv->carrier_action_defer_id = 0; + + state = nm_device_get_state (NM_DEVICE (self)); + if (state == NM_DEVICE_STATE_UNAVAILABLE) { + if (priv->carrier) + nm_device_queue_state (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + } else if (state >= NM_DEVICE_STATE_DISCONNECTED) { + if (!priv->carrier) + nm_device_queue_state (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); + } + return FALSE; +} + +static void +set_carrier (NMDeviceVlan *self, + const gboolean carrier, + const gboolean defer_action) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + NMDeviceState state; + + if (priv->carrier == carrier) + return; + + /* Clear any previous deferred action */ + carrier_action_defer_clear (self); + + priv->carrier = carrier; + g_object_notify (G_OBJECT (self), NM_DEVICE_VLAN_CARRIER); + + state = nm_device_get_state (NM_DEVICE (self)); + nm_log_info (LOGD_HW | LOGD_DEVICE, + "(%s): carrier now %s (device state %d%s)", + nm_device_get_iface (NM_DEVICE (self)), + carrier ? "ON" : "OFF", + state, + defer_action ? ", deferring action for 4 seconds" : ""); + + if (defer_action) + priv->carrier_action_defer_id = g_timeout_add_seconds (4, carrier_action_defer_cb, self); + else + carrier_action_defer_cb (self); +} + +static void +carrier_on (NMNetlinkMonitor *monitor, int idx, NMDevice *device) +{ + /* Make sure signal is for us */ + if (idx == nm_device_get_ifindex (device)) + set_carrier (NM_DEVICE_VLAN (device), TRUE, FALSE); +} + +static void +carrier_off (NMNetlinkMonitor *monitor, int idx, NMDevice *device) +{ + NMDeviceState state; + gboolean defer = FALSE; + + /* Make sure signal is for us */ + if (idx == nm_device_get_ifindex (device)) { + /* Defer carrier-off event actions while connected by a few seconds + * so that tripping over a cable, power-cycling a switch, or breaking + * off the RJ45 locking tab isn't so catastrophic. + */ + state = nm_device_get_state (device); + if (state > NM_DEVICE_STATE_DISCONNECTED) + defer = TRUE; + + set_carrier (NM_DEVICE_VLAN (device), FALSE, defer); + } +} + +static void +carrier_watch_init (NMDeviceVlan *self) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + priv->monitor = nm_netlink_monitor_get (); + priv->link_connected_id = g_signal_connect (priv->monitor, "carrier-on", + G_CALLBACK (carrier_on), + self); + priv->link_disconnected_id = g_signal_connect (priv->monitor, "carrier-off", + G_CALLBACK (carrier_off), + self); + + priv->carrier = get_carrier_sync (NM_DEVICE_VLAN (self)); + + nm_log_info (LOGD_HW | LOGD_DEVICE, "(%s): carrier is %s", + nm_device_get_iface (NM_DEVICE (self)), + priv->carrier ? "ON" : "OFF"); + + /* Request link state again just in case an error occurred getting the + * initial link state. + */ + nm_netlink_monitor_request_status (priv->monitor); +} + +/******************************************************************/ + +static void +parent_state_changed (NMDevice *parent, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); + + if (new_state < NM_DEVICE_STATE_DISCONNECTED) { + /* If the parent becomes unavailable or unmanaged so does the VLAN */ + nm_device_state_changed (NM_DEVICE (self), new_state, reason); + } else if ( new_state == NM_DEVICE_STATE_DISCONNECTED + && old_state < NM_DEVICE_STATE_DISCONNECTED) { + /* Mark VLAN interface as available/disconnected when the parent + * becomes available as a result of carrier changes or becoming + * initialized. + */ + nm_device_state_changed (NM_DEVICE (self), new_state, reason); + } +} + +/******************************************************************/ + +NMDevice * +nm_device_vlan_new (const char *udi, const char *iface, NMDevice *parent) +{ + NMDevice *device; + + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (parent != NULL, NULL); + + device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "8021q", + NM_DEVICE_TYPE_DESC, "VLAN", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, + NULL); + if (device) { + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + int ifindex = nm_device_get_ifindex (device); + int parent_ifindex = -1, itype; + int vlan_id; + + itype = nm_system_get_iface_type (ifindex, iface); + g_assert (itype == NM_IFACE_TYPE_VLAN); + + if (!nm_system_get_iface_vlan_info (ifindex, &parent_ifindex, &vlan_id)) { + nm_log_warn (LOGD_DEVICE, "(%s): failed to get VLAN interface info.", iface); + g_object_unref (device); + return NULL; + } + priv->vlan_id = vlan_id; + + if ( parent_ifindex < 0 + || parent_ifindex != nm_device_get_ip_ifindex (parent) + || priv->vlan_id < 0) { + nm_log_warn (LOGD_DEVICE, "(%s): VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", + iface, parent_ifindex, priv->vlan_id); + g_object_unref (device); + return NULL; + } + + priv->parent = g_object_ref (parent); + priv->parent_state_id = g_signal_connect (priv->parent, + "state-changed", + G_CALLBACK (parent_state_changed), + device); + + carrier_watch_init (NM_DEVICE_VLAN (device)); + + nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", iface, ifindex); + nm_log_info (LOGD_HW | LOGD_ETHER, "(%s): VLAN ID %d with parent %s", + iface, priv->vlan_id, nm_device_get_iface (parent)); + } + + return device; +} + +static void +nm_device_vlan_init (NMDeviceVlan * self) +{ +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + char *hwaddr; + + switch (prop_id) { + case PROP_HW_ADDRESS: + hwaddr = nm_utils_hwaddr_ntoa (priv->hw_addr, nm_utils_hwaddr_type (priv->hw_addr_len)); + g_value_take_string (value, hwaddr); + break; + case PROP_CARRIER: + g_value_set_boolean (value, priv->carrier); + break; + case PROP_VLAN_ID: + g_value_set_uint (value, priv->vlan_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_VLAN_ID: + priv->vlan_id = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (object); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + if (priv->disposed) { + G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + + if (priv->link_connected_id) + g_signal_handler_disconnect (priv->monitor, priv->link_connected_id); + if (priv->link_disconnected_id) + g_signal_handler_disconnect (priv->monitor, priv->link_disconnected_id); + carrier_action_defer_clear (self); + + g_object_unref (priv->monitor); + + g_signal_handler_disconnect (priv->parent, priv->parent_state_id); + g_object_unref (priv->parent); +} + +static void +nm_device_vlan_class_init (NMDeviceVlanClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceVlanPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + parent_class->get_generic_capabilities = real_get_generic_capabilities; + parent_class->update_hw_address = real_update_hw_address; + parent_class->hw_is_up = real_hw_is_up; + parent_class->hw_bring_up = real_hw_bring_up; + parent_class->hw_take_down = real_hw_take_down; + parent_class->can_interrupt_activation = real_can_interrupt_activation; + parent_class->is_available = real_is_available; + + parent_class->get_best_auto_connection = real_get_best_auto_connection; + parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; + parent_class->spec_match_list = spec_match_list; + parent_class->connection_match_config = connection_match_config; + + /* properties */ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, + "Active MAC Address", + "Currently set hardware MAC address", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER, + "Carrier", + "Carrier", + FALSE, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_VLAN_ID, + g_param_spec_uint (NM_DEVICE_VLAN_ID, + "VLAN ID", + "VLAN ID", + 0, 4095, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDeviceVlanClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_vlan_object_info); + + dbus_g_error_domain_register (NM_VLAN_ERROR, NULL, NM_TYPE_VLAN_ERROR); +} diff --git a/src/nm-device-vlan.h b/src/nm-device-vlan.h new file mode 100644 index 00000000..7c5fa24c --- /dev/null +++ b/src/nm-device-vlan.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_VLAN_H +#define NM_DEVICE_VLAN_H + +#include <glib-object.h> + +#include "nm-device-wired.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type ()) +#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) +#define NM_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) +#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VLAN)) +#define NM_DEVICE_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) + +typedef enum { + NM_VLAN_ERROR_CONNECTION_NOT_VLAN = 0, /*< nick=ConnectionNotVlan >*/ + NM_VLAN_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMVlanError; + +#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address" +#define NM_DEVICE_VLAN_CARRIER "carrier" +#define NM_DEVICE_VLAN_ID "vlan-id" + +typedef struct { + NMDevice parent; +} NMDeviceVlan; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*properties_changed) (NMDeviceVlan *device, GHashTable *properties); +} NMDeviceVlanClass; + + +GType nm_device_vlan_get_type (void); + +NMDevice *nm_device_vlan_new (const char *udi, + const char *iface, + NMDevice *parent); + +G_END_DECLS + +#endif /* NM_DEVICE_VLAN_H */ diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 9695c077..ed964a57 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -25,7 +25,6 @@ #include <netinet/in.h> #include <string.h> #include <net/ethernet.h> -#include <iwlib.h> #include <sys/stat.h> #include <sys/wait.h> #include <signal.h> @@ -34,11 +33,12 @@ #include <linux/ethtool.h> #include <sys/ioctl.h> #include <netinet/ether.h> +#include <net/if.h> +#include <errno.h> #include "nm-glib-compat.h" #include "nm-device.h" #include "nm-device-wifi.h" -#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-utils.h" #include "nm-logging.h" @@ -57,6 +57,8 @@ #include "nm-setting-ip6-config.h" #include "nm-system.h" #include "nm-settings-connection.h" +#include "nm-enum-types.h" +#include "wifi-utils.h" static gboolean impl_device_get_access_points (NMDeviceWifi *device, GPtrArray **aps, @@ -72,10 +74,7 @@ static gboolean impl_device_get_access_points (NMDeviceWifi *device, #define WIRELESS_SECRETS_TRIES "wireless-secrets-tries" -static void device_interface_init (NMDeviceInterface *iface_class); - -G_DEFINE_TYPE_EXTENDED (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) +G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) #define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate)) @@ -106,7 +105,7 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -#define SUP_SIG_ID_LEN 5 +#define SUP_SIG_ID_LEN 6 typedef struct Supplicant { NMSupplicantManager *mgr; @@ -132,12 +131,7 @@ struct _NMDeviceWifiPrivate { guint ipw_rfkill_id; RfKillState ipw_rfkill_state; - GByteArray * ssid; gint8 invalid_strength_counter; - iwqual max_qual; - - gint8 num_freqs; - guint32 freqs[IW_MAX_FREQUENCIES]; GSList * ap_list; NMAccessPoint * current_ap; @@ -147,20 +141,18 @@ struct _NMDeviceWifiPrivate { glong scheduled_scan_time; guint8 scan_interval; /* seconds */ guint pending_scan_id; + guint scanlist_cull_id; Supplicant supplicant; + WifiData * wifi_data; guint32 failed_link_count; guint periodic_source_id; guint link_timeout_id; - /* Static options from driver */ - guint32 capabilities; - gboolean has_scan_capa_ssid; + NMDeviceWifiCapabilities capabilities; }; -static guint32 nm_device_wifi_get_frequency (NMDeviceWifi *self); - static gboolean request_wireless_scan (gpointer user_data); static void schedule_scan (NMDeviceWifi *self, gboolean backoff); @@ -178,9 +170,19 @@ static void supplicant_iface_state_cb (NMSupplicantInterface *iface, gpointer user_data); static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface, + const char *object_path, GHashTable *properties, NMDeviceWifi * self); +static void supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface, + const char *object_path, + GHashTable *properties, + NMDeviceWifi *self); + +static void supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, + const char *object_path, + NMDeviceWifi *self); + static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface, gboolean success, NMDeviceWifi * self); @@ -189,21 +191,11 @@ static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface, GParamSpec * pspec, NMDeviceWifi * self); -static guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self); - -static void cull_scan_list (NMDeviceWifi *self); +static void schedule_scanlist_cull (NMDeviceWifi *self); /*****************************************************************/ -typedef enum { - NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, - NM_WIFI_ERROR_CONNECTION_INVALID, - NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, - NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, -} NMWifiError; - #define NM_WIFI_ERROR (nm_wifi_error_quark ()) -#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) static GQuark nm_wifi_error_quark (void) @@ -214,31 +206,6 @@ nm_wifi_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_wifi_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a wireless connection. */ - ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS, "ConnectionNotWireless"), - /* Connection was not a valid wireless connection. */ - ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - /* Given access point was not in this device's scan list. */ - ENUM_ENTRY (NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "AccessPointNotFound"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMWifiError", values); - } - return etype; -} - /*****************************************************************/ /* IPW rfkill handling (until 2.6.33) */ @@ -301,319 +268,12 @@ ipw_rfkill_state_work (gpointer user_data) /*****************************************************************/ -/* - * wireless_qual_to_percent - * - * Convert an iw_quality structure from SIOCGIWSTATS into a magical signal - * strength percentage. - * - */ -static int -wireless_qual_to_percent (const struct iw_quality *qual, - const struct iw_quality *max_qual) -{ - int percent = -1; - int level_percent = -1; - - g_return_val_if_fail (qual != NULL, -1); - g_return_val_if_fail (max_qual != NULL, -1); - - nm_log_dbg (LOGD_WIFI, - "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X", - (__s8) qual->qual, qual->qual, qual->qual, - (__s8) qual->level, qual->level, qual->level, - (__s8) qual->noise, qual->noise, qual->noise, - qual->updated, - (__s8) max_qual->qual, max_qual->qual, max_qual->qual, - (__s8) max_qual->level, max_qual->level, max_qual->level, - (__s8) max_qual->noise, max_qual->noise, max_qual->noise, - max_qual->updated); - - /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is. - * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be - * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers - * are free to use whatever they want to calculate "Link Quality". - */ - if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID)) - percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual)); - - /* If the driver doesn't specify a complete and valid quality, we have two options: - * - * 1) dBm: driver must specify max_qual->level = 0, and have valid values for - * qual->level and (qual->noise OR max_qual->noise) - * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for - * qual->level and max_qual->level - * - * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise, - * If drivers don't conform to it, they are wrong and need to be fixed. - */ - - if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */ - && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */ - && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */ - || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */ - ) { - /* Absolute power values (dBm) */ - - /* Reasonable fallbacks for dumb drivers that don't specify either level. */ - #define FALLBACK_NOISE_FLOOR_DBM -90 - #define FALLBACK_SIGNAL_MAX_DBM -20 - int max_level = FALLBACK_SIGNAL_MAX_DBM; - int noise = FALLBACK_NOISE_FLOOR_DBM; - int level = qual->level - 0x100; - - level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); - - if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID)) - noise = qual->noise - 0x100; - else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) - noise = max_qual->noise - 0x100; - noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); - - /* A sort of signal-to-noise ratio calculation */ - level_percent = (int)(100 - 70 *( - ((double)max_level - (double)level) / - ((double)max_level - (double)noise))); - nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", - level_percent, max_level, level, noise); - } else if ( (max_qual->level != 0) - && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */ - && !(qual->updated & IW_QUAL_LEVEL_INVALID)) { - /* Relative power values (RSSI) */ - - int level = qual->level; - - /* Signal level is relavtive (0 -> max_qual->level) */ - level = CLAMP (level, 0, max_qual->level); - level_percent = (int)(100 * ((double)level / (double)max_qual->level)); - nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.", - level_percent, max_qual->level, level); - } else if (percent == -1) { - nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy."); - } - - /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */ - if ((percent < 1) && (level_percent >= 0)) - percent = level_percent; - - nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).", - percent, CLAMP (percent, 0, 100)); - return (CLAMP (percent, 0, 100)); -} - - -/* - * nm_device_wifi_update_signal_strength - * - * Update the device's idea of the strength of its connection to the - * current access point. - * - */ -static void -nm_device_wifi_update_signal_strength (NMDeviceWifi *self, - NMAccessPoint *ap) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); - int fd, percent = -1; - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd >= 0) { - struct iwreq wrq; - struct iw_statistics stats; - - memset (&stats, 0, sizeof (stats)); - - wrq.u.data.pointer = &stats; - wrq.u.data.length = sizeof (stats); - wrq.u.data.flags = 1; /* Clear updated flag */ - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - - if (ioctl (fd, SIOCGIWSTATS, &wrq) == 0) - percent = wireless_qual_to_percent (&stats.qual, &priv->max_qual); - close (fd); - } - - /* Try to smooth out the strength. Atmel cards, for example, will give no strength - * one second and normal strength the next. - */ - if (percent >= 0 || ++priv->invalid_strength_counter > 3) { - nm_ap_set_strength (ap, (gint8) percent); - priv->invalid_strength_counter = 0; - } -} - - -static gboolean -wireless_get_range (NMDeviceWifi *self, - struct iw_range *range, - guint32 *response_len) -{ - int fd, i = 26; - gboolean success = FALSE; - const char *iface; - struct iwreq wrq; - - g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), FALSE); - g_return_val_if_fail (range != NULL, FALSE); - - iface = nm_device_get_iface (NM_DEVICE (self)); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_err (LOGD_HW, "(%s): couldn't open control socket.", iface); - return FALSE; - } - - memset (&wrq, 0, sizeof (struct iwreq)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - wrq.u.data.pointer = (caddr_t) range; - wrq.u.data.length = sizeof (struct iw_range); - - /* Need to give some drivers time to recover after suspend/resume - * (ex ipw3945 takes a few seconds to talk to its regulatory daemon; - * see rh bz#362421) - */ - while (i-- > 0) { - if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0) { - if (response_len) - *response_len = wrq.u.data.length; - success = TRUE; - break; - } else if (errno != EAGAIN) { - nm_log_err (LOGD_HW | LOGD_WIFI, - "(%s): couldn't get driver range information (%d).", - iface, errno); - break; - } - - g_usleep (G_USEC_PER_SEC / 4); - } - - if (i <= 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, - "(%s): driver took too long to respond to IWRANGE query.", - iface); - } - - close (fd); - return success; -} - static guint32 real_get_generic_capabilities (NMDevice *dev) { - int fd, err; - guint32 caps = NM_DEVICE_CAP_NONE; - struct iwreq wrq; - const char *iface = nm_device_get_iface (dev); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_err (LOGD_HW, "(%s): couldn't open control socket.", iface); - return NM_DEVICE_CAP_NONE; - } - - /* Cards that don't scan aren't supported */ - memset (&wrq, 0, sizeof (struct iwreq)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - err = ioctl (fd, SIOCSIWSCAN, &wrq); - close (fd); - if ((err < 0) && (errno == EOPNOTSUPP)) - caps = NM_DEVICE_CAP_NONE; - else - caps |= NM_DEVICE_CAP_NM_SUPPORTED; - - return caps; -} - -#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \ - NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \ - NM_WIFI_DEVICE_CAP_WPA | \ - NM_WIFI_DEVICE_CAP_RSN) - -static guint32 -get_wireless_capabilities (NMDeviceWifi *self, iwrange *range) -{ - guint32 caps = NM_WIFI_DEVICE_CAP_NONE; - const char * iface; - - g_return_val_if_fail (self != NULL, NM_WIFI_DEVICE_CAP_NONE); - g_return_val_if_fail (range != NULL, NM_WIFI_DEVICE_CAP_NONE); - - iface = nm_device_get_iface (NM_DEVICE (self)); - - /* All drivers should support WEP by default */ - caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104; - - if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) - caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP; - - if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) - caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP; - - if (range->enc_capa & IW_ENC_CAPA_WPA) - caps |= NM_WIFI_DEVICE_CAP_WPA; - - if (range->enc_capa & IW_ENC_CAPA_WPA2) - caps |= NM_WIFI_DEVICE_CAP_RSN; - - /* Check for cipher support but not WPA support */ - if ( (caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) - && !(caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))) { - nm_log_warn (LOGD_WIFI, "%s: device supports WPA ciphers but not WPA protocol; " - "WPA unavailable.", iface); - caps &= ~WPA_CAPS; - } - - /* Check for WPA support but not cipher support */ - if ( (caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN)) - && !(caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))) { - nm_log_warn (LOGD_WIFI, "%s: device supports WPA protocol but not WPA ciphers; " - "WPA unavailable.", iface); - caps &= ~WPA_CAPS; - } - - return caps; -} - - -static guint32 iw_freq_to_uint32 (struct iw_freq *freq) -{ - if (freq->e == 0) { - /* Some drivers report channel not frequency. Convert to a - * frequency; but this assumes that the device is in b/g mode. - */ - if ((freq->m >= 1) && (freq->m <= 13)) - return 2407 + (5 * freq->m); - else if (freq->m == 14) - return 2484; - } - - return (guint32) (((double) freq->m) * pow (10, freq->e) / 1000000); + return NM_DEVICE_CAP_NM_SUPPORTED; } - -/* Until a new wireless-tools comes out that has the defs and the structure, - * need to copy them here. - */ -/* Scan capability flags - in (struct iw_range *)->scan_capa */ -#define NM_IW_SCAN_CAPA_NONE 0x00 -#define NM_IW_SCAN_CAPA_ESSID 0x01 - -struct iw_range_with_scan_capa -{ - guint32 throughput; - guint32 min_nwid; - guint32 max_nwid; - guint16 old_num_channels; - guint8 old_num_frequency; - - guint8 scan_capa; -/* don't need the rest... */ -}; - - static GObject* constructor (GType type, guint n_construct_params, @@ -623,11 +283,6 @@ constructor (GType type, GObjectClass *klass; NMDeviceWifi *self; NMDeviceWifiPrivate *priv; - struct iw_range range; - struct iw_range_with_scan_capa *scan_capa_range; - guint32 response_len = 0; - gboolean success; - int i; klass = G_OBJECT_CLASS (nm_device_wifi_parent_class); object = klass->constructor (type, n_construct_params, construct_params); @@ -641,52 +296,22 @@ constructor (GType type, nm_device_get_iface (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); - memset (&range, 0, sizeof (struct iw_range)); - success = wireless_get_range (NM_DEVICE_WIFI (object), &range, &response_len); - if (!success) { - nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed", + priv->wifi_data = wifi_utils_init (nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self)), + TRUE); + if (priv->wifi_data == NULL) { + nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s): failed to initialize WiFi driver", nm_device_get_iface (NM_DEVICE (self))); - goto error; - } - - if ((response_len < 300) || (range.we_version_compiled < 21)) { - nm_log_info (LOGD_HW | LOGD_WIFI, - "(%s): driver WEXT version too old (got %d, expected >= 21)", - nm_device_get_iface (NM_DEVICE (self)), - range.we_version_compiled); - goto error; + g_object_unref (object); + return NULL; } + priv->capabilities = wifi_utils_get_caps (priv->wifi_data); - priv->max_qual.qual = range.max_qual.qual; - priv->max_qual.level = range.max_qual.level; - priv->max_qual.noise = range.max_qual.noise; - priv->max_qual.updated = range.max_qual.updated; - - priv->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); - for (i = 0; i < priv->num_freqs; i++) - priv->freqs[i] = iw_freq_to_uint32 (&range.freq[i]); - - /* Check for the ability to scan specific SSIDs. Until the scan_capa - * field gets added to wireless-tools, need to work around that by casting - * to the custom structure. - */ - scan_capa_range = (struct iw_range_with_scan_capa *) ⦥ - if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { - priv->has_scan_capa_ssid = TRUE; - nm_log_info (LOGD_HW | LOGD_WIFI, - "(%s): driver supports SSID scans (scan_capa 0x%02X).", - nm_device_get_iface (NM_DEVICE (self)), - scan_capa_range->scan_capa); - } else { - nm_log_info (LOGD_HW | LOGD_WIFI, - "(%s): driver does not support SSID scans (scan_capa 0x%02X).", - nm_device_get_iface (NM_DEVICE (self)), - scan_capa_range->scan_capa); + if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) { + nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s): driver supports Access Point (AP) mode", + nm_device_get_iface (NM_DEVICE (self))); } - /* 802.11 wireless-specific capabilities */ - priv->capabilities = get_wireless_capabilities (self, &range); - /* Connect to the supplicant manager */ priv->supplicant.mgr = nm_supplicant_manager_get (); g_assert (priv->supplicant.mgr); @@ -708,10 +333,6 @@ constructor (GType type, priv->ipw_rfkill_state = nm_device_wifi_get_ipw_rfkill_state (self); return object; - -error: - g_object_unref (object); - return NULL; } static gboolean @@ -748,6 +369,18 @@ supplicant_interface_acquire (NMDeviceWifi *self) priv->supplicant.sig_ids[i++] = id; id = g_signal_connect (priv->supplicant.iface, + NM_SUPPLICANT_INTERFACE_BSS_UPDATED, + G_CALLBACK (supplicant_iface_bss_updated_cb), + self); + priv->supplicant.sig_ids[i++] = id; + + id = g_signal_connect (priv->supplicant.iface, + NM_SUPPLICANT_INTERFACE_BSS_REMOVED, + G_CALLBACK (supplicant_iface_bss_removed_cb), + self); + priv->supplicant.sig_ids[i++] = id; + + id = g_signal_connect (priv->supplicant.iface, NM_SUPPLICANT_INTERFACE_SCAN_DONE, G_CALLBACK (supplicant_iface_scan_done_cb), self); @@ -808,6 +441,11 @@ supplicant_interface_release (NMDeviceWifi *self) } memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids)); + if (priv->scanlist_cull_id) { + g_source_remove (priv->scanlist_cull_id); + priv->scanlist_cull_id = 0; + } + if (priv->supplicant.iface) { /* Tell the supplicant to disconnect from the current AP */ nm_supplicant_interface_disconnect (priv->supplicant.iface); @@ -817,7 +455,6 @@ supplicant_interface_release (NMDeviceWifi *self) } } - static NMAccessPoint * get_ap_by_path (NMDeviceWifi *self, const char *path) { @@ -825,7 +462,20 @@ get_ap_by_path (NMDeviceWifi *self, const char *path) GSList *iter; for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { - if (strcmp (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0) + if (g_strcmp0 (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0) + return NM_AP (iter->data); + } + return NULL; +} + +static NMAccessPoint * +get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->ap_list; iter && path; iter = g_slist_next (iter)) { + if (g_strcmp0 (path, nm_ap_get_supplicant_path (NM_AP (iter->data))) == 0) return NM_AP (iter->data); } return NULL; @@ -839,16 +489,16 @@ get_active_ap (NMDeviceWifi *self, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); const char *iface = nm_device_get_iface (NM_DEVICE (self)); struct ether_addr bssid; - const GByteArray *ssid; + GByteArray *ssid; GSList *iter; int i = 0; - NMAccessPoint *match_nofreq = NULL; + NMAccessPoint *match_nofreq = NULL, *active_ap = NULL; gboolean found_a_band = FALSE; gboolean found_bg_band = FALSE; NM80211Mode devmode; guint32 devfreq; - nm_device_wifi_get_bssid (self, &bssid); + wifi_utils_get_bssid (priv->wifi_data, &bssid); nm_log_dbg (LOGD_WIFI, "(%s): active BSSID: %02x:%02x:%02x:%02x:%02x:%02x", iface, bssid.ether_addr_octet[0], bssid.ether_addr_octet[1], @@ -858,15 +508,15 @@ get_active_ap (NMDeviceWifi *self, if (!nm_ethernet_address_is_valid (&bssid)) return NULL; - ssid = nm_device_wifi_get_ssid (self); + ssid = wifi_utils_get_ssid (priv->wifi_data); nm_log_dbg (LOGD_WIFI, "(%s): active SSID: %s%s%s", iface, ssid ? "'" : "", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", ssid ? "'" : ""); - devmode = nm_device_wifi_get_mode (self); - devfreq = nm_device_wifi_get_frequency (self); + devmode = wifi_utils_get_mode (priv->wifi_data); + devfreq = wifi_utils_get_freq (priv->wifi_data); /* When matching hidden APs, do a second pass that ignores the SSID check, * because NM might not yet know the SSID of the hidden AP in the scan list @@ -930,7 +580,8 @@ get_active_ap (NMDeviceWifi *self, // FIXME: handle security settings here too nm_log_dbg (LOGD_WIFI, " matched"); - return ap; + active_ap = ap; + goto done; } } @@ -943,9 +594,10 @@ get_active_ap (NMDeviceWifi *self, * is uncommon though, and the frequency check penalizes closed drivers we * can't fix. Because we're not total dicks, ignore the frequency condition * if the associated BSSID/SSID exists only in one band since that's most - * likely the AP we want. + * likely the AP we want. Sometimes wl.o returns a frequency of 0, so if + * we can't match the AP based on frequency at all, just give up. */ - if (match_nofreq && (found_a_band != found_bg_band)) { + if (match_nofreq && ((found_a_band != found_bg_band) || (devfreq == 0))) { const struct ether_addr *ap_bssid = nm_ap_get_address (match_nofreq); const GByteArray *ap_ssid = nm_ap_get_ssid (match_nofreq); @@ -957,11 +609,15 @@ get_active_ap (NMDeviceWifi *self, ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); - return match_nofreq; + active_ap = match_nofreq; } nm_log_dbg (LOGD_WIFI, " No matching AP found."); - return NULL; + +done: + if (ssid) + g_byte_array_free (ssid, TRUE); + return active_ap; } static void @@ -1038,7 +694,7 @@ periodic_update (NMDeviceWifi *self) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMAccessPoint *new_ap; - guint32 new_rate; + guint32 new_rate, percent; /* In IBSS mode, most newer firmware/drivers do "BSS coalescing" where * multiple IBSS stations using the same SSID will eventually switch to @@ -1051,7 +707,7 @@ periodic_update (NMDeviceWifi *self) if (priv->current_ap && (nm_ap_get_mode (priv->current_ap) == NM_802_11_MODE_ADHOC)) { struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; - nm_device_wifi_get_bssid (self, &bssid); + wifi_utils_get_bssid (priv->wifi_data, &bssid); /* 0x02 means "locally administered" and should be OR-ed into * the first byte of IBSS BSSIDs. */ @@ -1061,8 +717,16 @@ periodic_update (NMDeviceWifi *self) } new_ap = get_active_ap (self, NULL, FALSE); - if (new_ap) - nm_device_wifi_update_signal_strength (self, new_ap); + if (new_ap) { + /* Try to smooth out the strength. Atmel cards, for example, will give no strength + * one second and normal strength the next. + */ + percent = wifi_utils_get_qual (priv->wifi_data); + if (percent >= 0 || ++priv->invalid_strength_counter > 3) { + nm_ap_set_strength (new_ap, (gint8) percent); + priv->invalid_strength_counter = 0; + } + } if ((new_ap || priv->current_ap) && (new_ap != priv->current_ap)) { const struct ether_addr *new_bssid = NULL; @@ -1073,13 +737,13 @@ periodic_update (NMDeviceWifi *self) if (new_ap) { new_bssid = nm_ap_get_address (new_ap); - new_addr = nm_ether_ntop (new_bssid); + new_addr = nm_utils_hwaddr_ntoa (new_bssid, ARPHRD_ETHER); new_ssid = nm_ap_get_ssid (new_ap); } if (priv->current_ap) { old_bssid = nm_ap_get_address (priv->current_ap); - old_addr = nm_ether_ntop (old_bssid); + old_addr = nm_utils_hwaddr_ntoa (old_bssid, ARPHRD_ETHER); old_ssid = nm_ap_get_ssid (priv->current_ap); } @@ -1095,7 +759,7 @@ periodic_update (NMDeviceWifi *self) set_current_ap (self, new_ap); } - new_rate = nm_device_wifi_get_bitrate (self); + new_rate = wifi_utils_get_rate (priv->wifi_data); if (new_rate != priv->rate) { priv->rate = new_rate; g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_BITRATE); @@ -1305,7 +969,37 @@ real_deactivate (NMDevice *dev) /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. */ - nm_device_wifi_set_mode (self, NM_802_11_MODE_INFRA); + wifi_utils_set_mode (priv->wifi_data, NM_802_11_MODE_INFRA); +} + +static gboolean +is_adhoc_wpa (NMConnection *connection) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char *mode, *key_mgmt; + + /* The kernel doesn't support Ad-Hoc WPA connections well at this time, + * and turns them into open networks. It's been this way since at least + * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. + */ + + s_wifi = nm_connection_get_setting_wireless (connection); + g_return_val_if_fail (s_wifi != NULL, FALSE); + + mode = nm_setting_wireless_get_mode (s_wifi); + if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) != 0) + return FALSE; + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (!s_wsec) + return FALSE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + if (g_strcmp0 (key_mgmt, "wpa-none") != 0) + return FALSE; + + return TRUE; } static gboolean @@ -1320,7 +1014,15 @@ real_check_connection_compatible (NMDevice *device, const GByteArray *mac; const GSList *mac_blacklist, *mac_blacklist_iter; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + if (is_adhoc_wpa (connection)) { + g_set_error_literal (error, + NM_WIFI_ERROR, + NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, + "WPA Ad-Hoc disabled due to kernel bugs"); + return FALSE; + } + + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) { @@ -1330,7 +1032,7 @@ real_check_connection_compatible (NMDevice *device, return FALSE; } - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { g_set_error (error, NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INVALID, @@ -1525,6 +1227,18 @@ real_complete_connection (NMDevice *device, return FALSE; } + /* The kernel doesn't support Ad-Hoc WPA connections well at this time, + * and turns them into open networks. It's been this way since at least + * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. + */ + if (is_adhoc_wpa (connection)) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + "WPA Ad-Hoc disabled due to kernel bugs"); + return FALSE; + } + g_assert (ssid); str_ssid = nm_utils_ssid_to_utf8 (ssid); format = g_strdup_printf ("%s %%d", str_ssid); @@ -1552,8 +1266,11 @@ real_complete_connection (NMDevice *device, GByteArray *mac; const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - /* Lock the connection to this device by default */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + /* Lock the connection to this device by default if it uses a + * permanent MAC address (ie not a 'locally administered' one) + */ + if ( !(priv->perm_hw_addr[0] & 0x02) + && memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { mac = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); @@ -1614,7 +1331,7 @@ real_get_best_auto_connection (NMDevice *dev, NMSettingIP4Config *s_ip4; const char *method = NULL; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if (s_con == NULL) continue; if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) @@ -1622,7 +1339,7 @@ real_get_best_auto_connection (NMDevice *dev, if (!nm_setting_connection_get_autoconnect (s_con)) continue; - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) continue; @@ -1650,7 +1367,7 @@ real_get_best_auto_connection (NMDevice *dev, continue; /* Use the connection if it's a shared connection */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); @@ -1725,251 +1442,6 @@ impl_device_get_access_points (NMDeviceWifi *self, return TRUE; } -/* - * nm_device_get_mode - * - * Get managed/infrastructure/adhoc mode on a device - * - */ -NM80211Mode -nm_device_wifi_get_mode (NMDeviceWifi *self) -{ - int fd; - NM80211Mode mode = NM_802_11_MODE_UNKNOWN; - const char *iface; - struct iwreq wrq; - - g_return_val_if_fail (self != NULL, NM_802_11_MODE_UNKNOWN); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - goto out; - - memset (&wrq, 0, sizeof (struct iwreq)); - iface = nm_device_get_iface (NM_DEVICE (self)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - - if (ioctl (fd, SIOCGIWMODE, &wrq) == 0) { - switch (wrq.u.mode) { - case IW_MODE_ADHOC: - mode = NM_802_11_MODE_ADHOC; - break; - case IW_MODE_INFRA: - mode = NM_802_11_MODE_INFRA; - break; - default: - break; - } - } else { - if (errno != ENODEV) - nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s): error %d getting card mode", iface, errno); - } - close (fd); - -out: - return mode; -} - - -/* - * nm_device_wifi_set_mode - * - * Set managed/infrastructure/adhoc mode on a device - * - */ -gboolean -nm_device_wifi_set_mode (NMDeviceWifi *self, const NM80211Mode mode) -{ - int fd; - const char *iface; - gboolean success = FALSE; - struct iwreq wrq; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail ((mode == NM_802_11_MODE_INFRA) || (mode == NM_802_11_MODE_ADHOC), FALSE); - - if (nm_device_wifi_get_mode (self) == mode) - return TRUE; - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - goto out; - - memset (&wrq, 0, sizeof (struct iwreq)); - switch (mode) { - case NM_802_11_MODE_ADHOC: - wrq.u.mode = IW_MODE_ADHOC; - break; - case NM_802_11_MODE_INFRA: - wrq.u.mode = IW_MODE_INFRA; - break; - default: - goto out; - } - - iface = nm_device_get_iface (NM_DEVICE (self)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - - if (ioctl (fd, SIOCSIWMODE, &wrq) < 0) { - if (errno != ENODEV) - nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting mode %d", iface, mode); - } else - success = TRUE; - close (fd); - -out: - return success; -} - - -/* - * nm_device_wifi_get_frequency - * - * Get current frequency - * - */ -static guint32 -nm_device_wifi_get_frequency (NMDeviceWifi *self) -{ - int fd; - guint32 freq = 0; - const char *iface; - struct iwreq wrq; - - g_return_val_if_fail (self != NULL, 0); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - return 0; - - memset (&wrq, 0, sizeof (struct iwreq)); - iface = nm_device_get_iface (NM_DEVICE (self)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - - if (ioctl (fd, SIOCGIWFREQ, &wrq) < 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, - "(%s): error getting frequency: %s", - iface, strerror (errno)); - } else - freq = iw_freq_to_uint32 (&wrq.u.freq); - - close (fd); - return freq; -} - -/* - * nm_device_wifi_get_ssid - * - * If a device is wireless, return the ssid that it is attempting - * to use. - */ -const GByteArray * -nm_device_wifi_get_ssid (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv; - int sk; - struct iwreq wrq; - char ssid[IW_ESSID_MAX_SIZE + 2]; - guint32 len; - - g_return_val_if_fail (self != NULL, NULL); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - sk = socket (AF_INET, SOCK_DGRAM, 0); - if (sk == -1) { - nm_log_err (LOGD_HW, "couldn't create socket: %d.", errno); - return NULL; - } - - memset (ssid, 0, sizeof (ssid)); - wrq.u.essid.pointer = (caddr_t) &ssid; - wrq.u.essid.length = sizeof (ssid); - wrq.u.essid.flags = 0; - strncpy (wrq.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - - if (ioctl (sk, SIOCGIWESSID, &wrq) < 0) { - nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): couldn't get SSID: %d", - nm_device_get_iface (NM_DEVICE (self)), errno); - goto out; - } - - if (priv->ssid) { - g_byte_array_free (priv->ssid, TRUE); - priv->ssid = NULL; - } - - len = wrq.u.essid.length; - if (!nm_utils_is_empty_ssid ((guint8 *) ssid, len)) { - priv->ssid = g_byte_array_sized_new (len); - g_byte_array_append (priv->ssid, (const guint8 *) ssid, len); - } - -out: - close (sk); - return priv->ssid; -} - - -/* - * nm_device_wifi_get_bitrate - * - * For wireless devices, get the bitrate to broadcast/receive at. - * Returned value is rate in Kb/s. - * - */ -static guint32 -nm_device_wifi_get_bitrate (NMDeviceWifi *self) -{ - int err = -1, fd; - struct iwreq wrq; - - g_return_val_if_fail (self != NULL, 0); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - return 0; - - memset (&wrq, 0, sizeof (wrq)); - strncpy (wrq.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - err = ioctl (fd, SIOCGIWRATE, &wrq); - close (fd); - - return ((err == 0) ? wrq.u.bitrate.value / 1000 : 0); -} - -/* - * nm_device_get_bssid - * - * If a device is wireless, get the access point's ethernet address - * that the card is associated with. - */ -void -nm_device_wifi_get_bssid (NMDeviceWifi *self, - struct ether_addr *bssid) -{ - int fd; - struct iwreq wrq; - - g_return_if_fail (self != NULL); - g_return_if_fail (bssid != NULL); - - memset (bssid, 0, sizeof (struct ether_addr)); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_err (LOGD_WIFI, "failed to open control socket."); - return; - } - - memset (&wrq, 0, sizeof (wrq)); - strncpy (wrq.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - if (ioctl (fd, SIOCGIWAP, &wrq) == 0) - memcpy (bssid->ether_addr_octet, &(wrq.u.ap_addr.sa_data), ETH_ALEN); - - close (fd); -} - - static gboolean scanning_allowed (NMDeviceWifi *self) { @@ -2020,7 +1492,7 @@ scanning_allowed (NMDeviceWifi *self) /* Don't scan when a shared connection is active; it makes drivers mad */ connection = nm_act_request_get_connection (req); - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) ip4_method = nm_setting_ip4_config_get_method (s_ip4); @@ -2031,7 +1503,7 @@ scanning_allowed (NMDeviceWifi *self) * intra-ESS roaming (which requires periodic scanning) isn't being * used due to the specific AP lock. (bgo #513820) */ - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); bssid = nm_setting_wireless_get_bssid (s_wifi); if (bssid && bssid->len == ETH_ALEN) @@ -2174,15 +1646,10 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, if (check_scanning_allowed (self)) schedule_scan (self, TRUE); -#if 0 - if (num_results == 0) { - /* ensure that old APs get culled, which otherwise only - * happens when there are actual scan results to process. - */ - cull_scan_list (self); - ap_list_dump (self); - } -#endif + /* Ensure that old APs get removed, which otherwise only + * happens when there are new BSSes. + */ + schedule_scanlist_cull (self); } @@ -2217,9 +1684,7 @@ merge_scanned_ap (NMDeviceWifi *self, gboolean strict_match = TRUE; NMAccessPoint *current_ap = NULL; - /* Let the manager try to fill in the SSID from seen-bssids lists - * if it can - */ + /* Let the manager try to fill in the SSID from seen-bssids lists */ bssid = nm_ap_get_address (merge_ap); ssid = nm_ap_get_ssid (merge_ap); if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { @@ -2252,7 +1717,9 @@ merge_scanned_ap (NMDeviceWifi *self, if (current_ap && nm_ap_get_fake (current_ap)) strict_match = FALSE; - found_ap = nm_ap_match_in_list (merge_ap, priv->ap_list, strict_match); + found_ap = get_ap_by_supplicant_path (self, nm_ap_get_supplicant_path (merge_ap)); + if (!found_ap) + found_ap = nm_ap_match_in_list (merge_ap, priv->ap_list, strict_match); if (found_ap) { nm_log_dbg (LOGD_WIFI_SCAN, "(%s): merging AP '%s' " MAC_FMT " (%p) with existing (%p)", nm_device_get_iface (NM_DEVICE (self)), @@ -2261,6 +1728,7 @@ merge_scanned_ap (NMDeviceWifi *self, merge_ap, found_ap); + nm_ap_set_supplicant_path (found_ap, nm_ap_get_supplicant_path (merge_ap)); nm_ap_set_flags (found_ap, nm_ap_get_flags (merge_ap)); nm_ap_set_wpa_flags (found_ap, nm_ap_get_wpa_flags (merge_ap)); nm_ap_set_rsn_flags (found_ap, nm_ap_get_rsn_flags (merge_ap)); @@ -2289,25 +1757,18 @@ merge_scanned_ap (NMDeviceWifi *self, } } -static void +#define WPAS_REMOVED_TAG "supplicant-removed" + +static gboolean cull_scan_list (NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv; - GTimeVal cur_time; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + GTimeVal now; GSList *outdated_list = NULL; GSList *elt; - NMActRequest *req; - const char *cur_ap_path = NULL; guint32 removed = 0, total = 0; - g_return_if_fail (self != NULL); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - g_get_current_time (&cur_time); - - req = nm_device_get_act_request (NM_DEVICE (self)); - if (req) - cur_ap_path = nm_act_request_get_specific_object (req); + priv->scanlist_cull_id = 0; nm_log_dbg (LOGD_WIFI_SCAN, "(%s): checking scan list for outdated APs", nm_device_get_iface (NM_DEVICE (self))); @@ -2315,19 +1776,27 @@ cull_scan_list (NMDeviceWifi *self) /* Walk the access point list and remove any access points older than * three times the inactive scan interval. */ + g_get_current_time (&now); for (elt = priv->ap_list; elt; elt = g_slist_next (elt), total++) { - NMAccessPoint * ap = NM_AP (elt->data); - const glong ap_time = nm_ap_get_last_seen (ap); - gboolean keep = FALSE; - const guint prune_interval_s = SCAN_INTERVAL_MAX * 3; + NMAccessPoint *ap = elt->data; + const guint prune_interval_s = SCAN_INTERVAL_MAX * 3; - /* Don't ever prune the AP we're currently associated with */ - if (cur_ap_path && !strcmp (cur_ap_path, nm_ap_get_dbus_path (ap))) - keep = TRUE; - if (nm_ap_get_fake (ap)) - keep = TRUE; + /* Don't cull the associated AP or manually created APs */ + if (ap == priv->current_ap || nm_ap_get_fake (ap)) + continue; + + /* Don't cull APs still known to the supplicant. Since the supplicant + * doesn't yet emit property updates for "last seen" we have to rely + * on changing signal strength for updating "last seen". But if the + * AP's strength doesn't change we won't get any updates for the AP, + * and we'll end up here even if the AP was still found by the + * supplicant in the last scan. + */ + if ( nm_ap_get_supplicant_path (ap) + && g_object_get_data (G_OBJECT (ap), WPAS_REMOVED_TAG) == NULL) + continue; - if (!keep && (ap_time + prune_interval_s < cur_time.tv_sec)) + if (nm_ap_get_last_seen (ap) + prune_interval_s < now.tv_sec) outdated_list = g_slist_append (outdated_list, ap); } @@ -2358,10 +1827,26 @@ cull_scan_list (NMDeviceWifi *self) nm_log_dbg (LOGD_WIFI_SCAN, "(%s): removed %d APs (of %d)", nm_device_get_iface (NM_DEVICE (self)), removed, total); + + ap_list_dump (self); + + return FALSE; +} + +static void +schedule_scanlist_cull (NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + /* Cull the scan list after the last request for it has come in */ + if (priv->scanlist_cull_id) + g_source_remove (priv->scanlist_cull_id); + priv->scanlist_cull_id = g_timeout_add_seconds (4, (GSourceFunc) cull_scan_list, self); } static void supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, + const char *object_path, GHashTable *properties, NMDeviceWifi *self) { @@ -2377,22 +1862,65 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, if (state <= NM_DEVICE_STATE_UNAVAILABLE) return; - ap = nm_ap_new_from_properties (properties); + ap = nm_ap_new_from_properties (object_path, properties); if (ap) { nm_ap_dump (ap, "New AP: "); /* Add the AP to the device's AP list */ merge_scanned_ap (self, ap); g_object_unref (ap); - - /* Remove outdated access points */ - cull_scan_list (self); - - ap_list_dump (self); } else { nm_log_warn (LOGD_WIFI_SCAN, "(%s): invalid AP properties received", nm_device_get_iface (NM_DEVICE (self))); } + + /* Remove outdated access points */ + schedule_scanlist_cull (self); +} + +static void +supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface, + const char *object_path, + GHashTable *properties, + NMDeviceWifi *self) +{ + NMDeviceState state; + NMAccessPoint *ap; + GTimeVal now; + + g_return_if_fail (self != NULL); + g_return_if_fail (object_path != NULL); + g_return_if_fail (properties != NULL); + + /* Ignore new APs when unavailable or unamnaged */ + state = nm_device_get_state (NM_DEVICE (self)); + if (state <= NM_DEVICE_STATE_UNAVAILABLE) + return; + + /* Update the AP's last-seen property */ + ap = get_ap_by_supplicant_path (self, object_path); + if (ap) { + g_get_current_time (&now); + nm_ap_set_last_seen (ap, now.tv_sec); + } + + /* Remove outdated access points */ + schedule_scanlist_cull (self); +} + +static void +supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, + const char *object_path, + NMDeviceWifi *self) +{ + NMAccessPoint *ap; + + g_return_if_fail (self != NULL); + g_return_if_fail (object_path != NULL); + + ap = get_ap_by_supplicant_path (self, object_path); + if (ap) + g_object_set_data (G_OBJECT (ap), WPAS_REMOVED_TAG, GUINT_TO_POINTER (TRUE)); } @@ -2921,23 +2449,6 @@ remove_supplicant_timeouts (NMDeviceWifi *self) remove_link_timeout (self); } -static guint32 -find_supported_frequency (NMDeviceWifi *self, const guint32 *freqs) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int i; - - for (i = 0; i < priv->num_freqs; i++) { - while (*freqs) { - if (priv->freqs[i] == *freqs) - return *freqs; - freqs++; - } - } - - return 0; -} - static NMSupplicantConfig * build_supplicant_config (NMDeviceWifi *self, NMConnection *connection, @@ -2951,7 +2462,7 @@ build_supplicant_config (NMDeviceWifi *self, g_return_val_if_fail (self != NULL, NULL); - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wireless != NULL, NULL); config = nm_supplicant_config_new (); @@ -2970,9 +2481,9 @@ build_supplicant_config (NMDeviceWifi *self, adhoc_freq = nm_ap_get_freq (ap); if (!adhoc_freq) { if (g_strcmp0 (band, "a") == 0) - adhoc_freq = find_supported_frequency (self, a_freqs); + adhoc_freq = wifi_utils_find_freq (priv->wifi_data, a_freqs); else - adhoc_freq = find_supported_frequency (self, bg_freqs); + adhoc_freq = wifi_utils_find_freq (priv->wifi_data, bg_freqs); } if (!adhoc_freq) { @@ -2987,22 +2498,22 @@ build_supplicant_config (NMDeviceWifi *self, s_wireless, nm_ap_get_broadcast (ap), adhoc_freq, - priv->has_scan_capa_ssid)) { + wifi_utils_can_scan_ssid (priv->wifi_data))) { nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); goto error; } - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); if (s_wireless_sec) { NMSetting8021x *s_8021x; - const char *con_path = nm_connection_get_path (connection); + const char *con_uuid = nm_connection_get_uuid (connection); - g_assert (con_path); - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_assert (con_uuid); + s_8021x = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_wireless_security (config, s_wireless_sec, s_8021x, - con_path)) { + con_uuid)) { nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to " "supplicant config."); goto error; @@ -3135,8 +2646,18 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) connection = nm_act_request_get_connection (req); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* The kernel doesn't support Ad-Hoc WPA connections well at this time, + * and turns them into open networks. It's been this way since at least + * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. + */ + if (is_adhoc_wpa (connection)) { + nm_log_warn (LOGD_WIFI, "Ad-Hoc WPA disabled due to kernel bugs"); + *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + /* Set spoof MAC to the interface */ - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); g_assert (s_wireless); cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); @@ -3177,7 +2698,7 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap); } - nm_act_request_set_specific_object (req, nm_ap_get_dbus_path (ap)); + nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap)); done: set_current_ap (self, ap); @@ -3212,7 +2733,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) connection = nm_act_request_get_connection (req); g_assert (connection); - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); g_assert (s_wireless); /* If we need secrets, get them */ @@ -3287,38 +2808,22 @@ out: return ret; } -static NMActStageReturn -real_act_stage4_get_ip4_config (NMDevice *dev, - NMIP4Config **config, - NMDeviceStateReason *reason) +static void +real_ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) { - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - NMDeviceClass *parent_class; - - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - - /* Chain up to parent */ - parent_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class); - ret = parent_class->act_stage4_get_ip4_config (dev, config, reason); - - if ((ret == NM_ACT_STAGE_RETURN_SUCCESS) && *config) { - NMConnection *connection; - NMSettingWireless *s_wireless; - guint32 mtu; - - connection = nm_act_request_get_connection (nm_device_get_act_request (dev)); - g_assert (connection); - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); - g_assert (s_wireless); + NMConnection *connection; + NMSettingWireless *s_wifi; + guint32 mtu; - /* MTU override */ - mtu = nm_setting_wireless_get_mtu (s_wireless); - if (mtu) - nm_ip4_config_set_mtu (*config, mtu); - } + connection = nm_device_get_connection (device); + g_assert (connection); + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); - return ret; + /* MTU override */ + mtu = nm_setting_wireless_get_mtu (s_wifi); + if (mtu) + nm_ip4_config_set_mtu (config, mtu); } static gboolean @@ -3398,55 +2903,45 @@ handle_ip_config_timeout (NMDeviceWifi *self, static NMActStageReturn -real_act_stage4_ip4_config_timeout (NMDevice *dev, - NMIP4Config **config, - NMDeviceStateReason *reason) +real_act_stage4_ip4_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) { - NMActRequest *req; NMConnection *connection; NMSettingIP4Config *s_ip4; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - req = nm_device_get_act_request (dev); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (dev); g_assert (connection); - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) may_fail = nm_setting_ip4_config_get_may_fail (s_ip4); ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, config, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, reason); return ret; } static NMActStageReturn -real_act_stage4_ip6_config_timeout (NMDevice *dev, - NMIP6Config **config, - NMDeviceStateReason *reason) +real_act_stage4_ip6_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) { - NMActRequest *req; NMConnection *connection; NMSettingIP6Config *s_ip6; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - req = nm_device_get_act_request (dev); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (dev); g_assert (connection); - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) may_fail = nm_setting_ip6_config_get_may_fail (s_ip6); ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, config, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, reason); return ret; } @@ -3483,13 +2978,13 @@ activation_success_handler (NMDevice *dev) * But if activation was successful, the card will know the BSSID. Grab * the BSSID off the card and fill in the BSSID of the activation AP. */ - nm_device_wifi_get_bssid (self, &bssid); + wifi_utils_get_bssid (priv->wifi_data, &bssid); if (!nm_ethernet_address_is_valid (nm_ap_get_address (ap))) nm_ap_set_address (ap, &bssid); if (!nm_ap_get_freq (ap)) - nm_ap_set_freq (ap, nm_device_wifi_get_frequency (self)); + nm_ap_set_freq (ap, wifi_utils_get_freq (priv->wifi_data)); if (!nm_ap_get_max_bitrate (ap)) - nm_ap_set_max_bitrate (ap, nm_device_wifi_get_bitrate (self)); + nm_ap_set_max_bitrate (ap, wifi_utils_get_rate (priv->wifi_data)); tmp_ap = get_active_ap (self, ap, TRUE); if (tmp_ap) { @@ -3503,7 +2998,8 @@ activation_success_handler (NMDevice *dev) if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) nm_ap_set_ssid (tmp_ap, nm_ap_get_ssid (ap)); - nm_act_request_set_specific_object (req, nm_ap_get_dbus_path (tmp_ap)); + nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), + nm_ap_get_dbus_path (tmp_ap)); priv->ap_list = g_slist_remove (priv->ap_list, ap); g_object_unref (ap); @@ -3526,13 +3022,9 @@ activation_failure_handler (NMDevice *dev) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMAccessPoint *ap; const GByteArray * ssid; - NMActRequest *req; NMConnection *connection; - req = nm_device_get_act_request (dev); - g_assert (req); - - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (dev); g_assert (connection); /* Clear wireless secrets tries on failure */ @@ -3583,13 +3075,42 @@ spec_match_list (NMDevice *device, const GSList *specs) char *hwaddr; gboolean matched; - hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr); + hwaddr = nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER); matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); return matched; } +static gboolean +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + NMSettingWireless *s_wifi; + const GByteArray *mac = NULL; + + s_wifi = nm_connection_get_setting_wireless (connection); + if (s_wifi) + mac = nm_setting_wireless_get_mac_address (s_wifi); + + if (mac) { + g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, priv->hw_addr, mac->len) == 0) + return TRUE; + } else if (fail_if_no_hwaddr == FALSE) + return TRUE; + + return FALSE; +} + static void device_state_changed (NMDevice *device, NMDeviceState new_state, @@ -3632,12 +3153,6 @@ device_state_changed (NMDevice *device, * the device is now ready to use. */ if (priv->enabled && (nm_device_get_firmware_missing (device) == FALSE)) { - gboolean success; - struct iw_range range; - - /* Wait for some drivers like ipw3945 to come back to life */ - success = wireless_get_range (self, &range, NULL); - if (!priv->supplicant.iface) supplicant_interface_acquire (self); } @@ -3676,13 +3191,13 @@ nm_device_wifi_get_activation_ap (NMDeviceWifi *self) if (!req) return NULL; - ap_path = nm_act_request_get_specific_object (req); + ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); return ap_path ? get_ap_by_path (self, ap_path) : NULL; } static void -real_set_enabled (NMDeviceInterface *device, gboolean enabled) +real_set_enabled (NMDevice *device, gboolean enabled) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); @@ -3697,7 +3212,7 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) nm_device_get_iface (NM_DEVICE (device)), enabled ? "enabled" : "disabled"); - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + state = nm_device_get_state (NM_DEVICE (self)); if (state < NM_DEVICE_STATE_UNAVAILABLE) { nm_log_dbg (LOGD_WIFI, "(%s): %s blocked by UNMANAGED state", enabled ? "enable" : "disable", @@ -3706,8 +3221,7 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) } if (enabled) { - gboolean no_firmware = FALSE, success; - struct iw_range range; + gboolean no_firmware = FALSE; if (state != NM_DEVICE_STATE_UNAVAILABLE) nm_log_warn (LOGD_CORE, "not in expected unavailable state!"); @@ -3725,9 +3239,6 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) return; } - /* Wait for some drivers like ipw3945 to come back to life */ - success = wireless_get_range (self, &range, NULL); - /* Re-initialize the supplicant interface and wait for it to be ready */ if (priv->supplicant.iface) supplicant_interface_release (self); @@ -3755,22 +3266,16 @@ nm_device_wifi_new (const char *udi, g_return_val_if_fail (driver != NULL, NULL); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIFI, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_IFACE, iface, - NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 WiFi", - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI, - NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WLAN, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "802.11 WiFi", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI, + NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN, NULL); } static void -device_interface_init (NMDeviceInterface *iface_class) -{ - iface_class->set_enabled = real_set_enabled; -} - -static void nm_device_wifi_init (NMDeviceWifi * self) { g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), NULL); @@ -3802,14 +3307,12 @@ dispose (GObject *object) priv->supplicant.mgr = NULL; } - if (priv->ssid) { - g_byte_array_free (priv->ssid, TRUE); - priv->ssid = NULL; - } - set_current_ap (self, NULL); remove_all_aps (self); + if (priv->wifi_data) + wifi_utils_deinit (priv->wifi_data); + g_free (priv->ipw_rfkill_path); if (priv->ipw_rfkill_id) { g_source_remove (priv->ipw_rfkill_id); @@ -3828,13 +3331,13 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->hw_addr, ARPHRD_ETHER)); break; case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); break; case PROP_MODE: - g_value_set_uint (value, nm_device_wifi_get_mode (device)); + g_value_set_uint (value, wifi_utils_get_mode (priv->wifi_data)); break; case PROP_BITRATE: g_value_set_uint (value, priv->rate); @@ -3906,15 +3409,17 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->is_available = real_is_available; parent_class->check_connection_compatible = real_check_connection_compatible; parent_class->complete_connection = real_complete_connection; + parent_class->set_enabled = real_set_enabled; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; - parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; + parent_class->ip4_config_pre_commit = real_ip4_config_pre_commit; parent_class->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout; parent_class->act_stage4_ip6_config_timeout = real_act_stage4_ip6_config_timeout; parent_class->deactivate = real_deactivate; parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->spec_match_list = spec_match_list; + parent_class->hwaddr_matches = hwaddr_matches; klass->scanning_allowed = scanning_allowed; diff --git a/src/nm-device-wifi.h b/src/nm-device-wifi.h index 31ac5ad5..1e665fc3 100644 --- a/src/nm-device-wifi.h +++ b/src/nm-device-wifi.h @@ -41,6 +41,12 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) #define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +typedef enum { + NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, /*< nick=ConnectionNotWireless >*/ + NM_WIFI_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, /*< nick=AccessPointNotFound >*/ +} NMWifiError; #define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" #define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" @@ -88,14 +94,6 @@ NMDevice *nm_device_wifi_new (const char *udi, void nm_device_wifi_get_address (NMDeviceWifi *dev, struct ether_addr *addr); -void nm_device_wifi_get_bssid (NMDeviceWifi *dev, struct ether_addr *bssid); - -const GByteArray * nm_device_wifi_get_ssid (NMDeviceWifi *self); - -gboolean nm_device_wifi_set_mode (NMDeviceWifi *self, const NM80211Mode mode); - -NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *self); - NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self); RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self); diff --git a/src/nm-device-wired.c b/src/nm-device-wired.c new file mode 100644 index 00000000..a476faad --- /dev/null +++ b/src/nm-device-wired.c @@ -0,0 +1,595 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "config.h" +#include <glib.h> +#include <sys/socket.h> +#include <linux/if.h> +#include <linux/if_infiniband.h> +#include <netinet/ether.h> +#include <linux/sockios.h> +#include <linux/version.h> +#include <linux/ethtool.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include "nm-device-wired.h" +#include "nm-device-private.h" +#include "nm-dhcp-manager.h" +#include "nm-logging.h" +#include "nm-netlink-monitor.h" +#include "nm-netlink-utils.h" +#include "nm-system.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" + + +G_DEFINE_TYPE (NMDeviceWired, nm_device_wired, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIRED_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIRED, NMDeviceWiredPrivate)) + +#define NM_DEVICE_WIRED_LOG_LEVEL(dev) ((nm_device_get_device_type (dev) == NM_DEVICE_TYPE_INFINIBAND) ? LOGD_INFINIBAND : LOGD_ETHER) + +typedef struct { + guint8 hw_addr[NM_UTILS_HWADDR_LEN_MAX]; /* Currently set MAC address */ + guint hw_addr_type; + guint hw_addr_len; + gboolean carrier; + guint32 speed; + + NMNetlinkMonitor * monitor; + gulong link_connected_id; + gulong link_disconnected_id; + guint carrier_action_defer_id; + +} NMDeviceWiredPrivate; + + +/* Returns speed in Mb/s */ +static guint32 +ethtool_get_speed (NMDeviceWired *self) +{ + int fd; + struct ifreq ifr; + struct ethtool_cmd edata = { + .cmd = ETHTOOL_GSET, + }; + guint32 speed = 0; + + g_return_val_if_fail (self != NULL, 0); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_warn (LOGD_HW, "couldn't open control socket."); + return 0; + } + + memset (&ifr, 0, sizeof (struct ifreq)); + strncpy (ifr.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); + ifr.ifr_data = (char *) &edata; + + if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) + goto out; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + speed = edata.speed; +#else + speed = ethtool_cmd_speed (&edata); +#endif + + if (speed == G_MAXUINT16 || speed == G_MAXUINT32) + speed = 0; + +out: + close (fd); + return speed; +} + +static void +set_speed (NMDeviceWired *self, const guint32 speed) +{ + NMDeviceWiredPrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + if (priv->speed == speed) + return; + + priv->speed = speed; + g_object_notify (G_OBJECT (self), "speed"); + + nm_log_dbg (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): speed is now %d Mb/s", + nm_device_get_iface (NM_DEVICE (self)), + speed); +} + +static void +carrier_action_defer_clear (NMDeviceWired *self) +{ + NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + + if (priv->carrier_action_defer_id) { + g_source_remove (priv->carrier_action_defer_id); + priv->carrier_action_defer_id = 0; + } +} + +static gboolean +carrier_action_defer_cb (gpointer user_data) +{ + NMDeviceWired *self = NM_DEVICE_WIRED (user_data); + NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + NMDeviceState state; + + priv->carrier_action_defer_id = 0; + + state = nm_device_get_state (NM_DEVICE (self)); + if (state == NM_DEVICE_STATE_UNAVAILABLE) { + if (priv->carrier) + nm_device_queue_state (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + } else if (state >= NM_DEVICE_STATE_DISCONNECTED) { + if (!priv->carrier) + nm_device_queue_state (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); + } + + return FALSE; +} + +static void +set_carrier (NMDeviceWired *self, + const gboolean carrier, + const gboolean defer_action) +{ + NMDeviceWiredPrivate *priv; + NMDeviceState state; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + if (priv->carrier == carrier) + return; + + /* Clear any previous deferred action */ + carrier_action_defer_clear (self); + + priv->carrier = carrier; + g_object_notify (G_OBJECT (self), "carrier"); + + state = nm_device_get_state (NM_DEVICE (self)); + nm_log_info (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): carrier now %s (device state %d%s)", + nm_device_get_iface (NM_DEVICE (self)), + carrier ? "ON" : "OFF", + state, + defer_action ? ", deferring action for 4 seconds" : ""); + + if (defer_action) + priv->carrier_action_defer_id = g_timeout_add_seconds (4, carrier_action_defer_cb, self); + else + carrier_action_defer_cb (self); +} + +static void +carrier_on (NMNetlinkMonitor *monitor, + int idx, + gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWired *self = NM_DEVICE_WIRED (device); + guint32 caps; + + /* Make sure signal is for us */ + if (idx == nm_device_get_ifindex (device)) { + /* Ignore spurious netlink messages */ + caps = nm_device_get_capabilities (device); + if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) + return; + + set_carrier (self, TRUE, FALSE); + set_speed (self, ethtool_get_speed (self)); + } +} + +static void +carrier_off (NMNetlinkMonitor *monitor, + int idx, + gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWired *self = NM_DEVICE_WIRED (device); + guint32 caps; + + /* Make sure signal is for us */ + if (idx == nm_device_get_ifindex (device)) { + NMDeviceState state; + gboolean defer = FALSE; + + /* Ignore spurious netlink messages */ + caps = nm_device_get_capabilities (device); + if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) + return; + + /* Defer carrier-off event actions while connected by a few seconds + * so that tripping over a cable, power-cycling a switch, or breaking + * off the RJ45 locking tab isn't so catastrophic. + */ + state = nm_device_get_state (device); + if (state > NM_DEVICE_STATE_DISCONNECTED) + defer = TRUE; + + set_carrier (self, FALSE, defer); + } +} + +static gboolean +get_carrier_sync (NMDeviceWired *self) +{ + NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + GError *error = NULL; + guint32 ifflags = 0; + + /* Get initial link state */ + if (!nm_netlink_monitor_get_flags_sync (priv->monitor, + nm_device_get_ip_ifindex (NM_DEVICE (self)), + &ifflags, + &error)) { + nm_log_warn (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): couldn't get carrier state: (%d) %s", + nm_device_get_ip_iface (NM_DEVICE (self)), + error ? error->code : -1, + (error && error->message) ? error->message : "unknown"); + g_clear_error (&error); + } + + return !!(ifflags & IFF_LOWER_UP); +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMDeviceWiredPrivate *priv; + NMDevice *self; + guint32 caps; + + object = G_OBJECT_CLASS (nm_device_wired_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + self = NM_DEVICE (object); + priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + + nm_log_dbg (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self))); + + if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_ETHERNET) { + priv->hw_addr_type = ARPHRD_ETHER; + priv->hw_addr_len = ETH_ALEN; + } else if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_INFINIBAND) { + priv->hw_addr_type = ARPHRD_INFINIBAND; + priv->hw_addr_len = INFINIBAND_ALEN; + } else if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_BOND) { + /* We may not know the hardware address type until a slave is added */ + priv->hw_addr_type = ARPHRD_ETHER; + priv->hw_addr_len = ETH_ALEN; + } else + g_assert_not_reached (); + + caps = nm_device_get_capabilities (self); + if (caps & NM_DEVICE_CAP_CARRIER_DETECT) { + /* Only listen to netlink for cards that support carrier detect */ + priv->monitor = nm_netlink_monitor_get (); + + priv->link_connected_id = g_signal_connect (priv->monitor, "carrier-on", + G_CALLBACK (carrier_on), + self); + priv->link_disconnected_id = g_signal_connect (priv->monitor, "carrier-off", + G_CALLBACK (carrier_off), + self); + + priv->carrier = get_carrier_sync (NM_DEVICE_WIRED (self)); + + nm_log_info (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): carrier is %s", + nm_device_get_iface (NM_DEVICE (self)), + priv->carrier ? "ON" : "OFF"); + + /* Request link state again just in case an error occurred getting the + * initial link state. + */ + nm_netlink_monitor_request_status (priv->monitor); + } else { + nm_log_info (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): driver '%s' does not support carrier detection.", + nm_device_get_iface (self), + nm_device_get_driver (self)); + priv->carrier = TRUE; + } + + return object; +} + +static void +nm_device_wired_init (NMDeviceWired * self) +{ +} + +static gboolean +real_hw_is_up (NMDevice *device) +{ + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); +} + +static gboolean +real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) +{ + gboolean success, carrier; + + success = nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); + if (success) { + carrier = get_carrier_sync (NM_DEVICE_WIRED (dev)); + set_carrier (NM_DEVICE_WIRED (dev), carrier, carrier ? FALSE : TRUE); + } + return success; +} + +static void +real_hw_take_down (NMDevice *dev) +{ + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); +} + +static void +real_update_hw_address (NMDevice *dev) +{ + NMDeviceWired *self = NM_DEVICE_WIRED (dev); + NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + struct rtnl_link *rtnl; + struct nl_addr *addr; + + rtnl = nm_netlink_index_to_rtnl_link (nm_device_get_ip_ifindex (dev)); + if (!rtnl) { + nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev), + "(%s) failed to read hardware address (error %d)", + nm_device_get_iface (dev), errno); + return; + } + + addr = rtnl_link_get_addr (rtnl); + if (!addr) { + nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev), + "(%s) no hardware address?", + nm_device_get_iface (dev)); + rtnl_link_put (rtnl); + return; + } + + if (nl_addr_get_len (addr) != priv->hw_addr_len) { + nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev), + "(%s) hardware address is wrong length (expected %d got %d)", + nm_device_get_iface (dev), + priv->hw_addr_len, nl_addr_get_len (addr)); + } else { + memcpy (&priv->hw_addr, nl_addr_get_binary_addr (addr), + priv->hw_addr_len); + } + + rtnl_link_put (rtnl); +} + +static gboolean +real_can_interrupt_activation (NMDevice *dev) +{ + NMDeviceWired *self = NM_DEVICE_WIRED (dev); + gboolean interrupt = FALSE; + + /* Devices that support carrier detect can interrupt activation + * if the link becomes inactive. + */ + if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_CARRIER_DETECT) { + if (NM_DEVICE_WIRED_GET_PRIVATE (self)->carrier == FALSE) + interrupt = TRUE; + } + return interrupt; +} + +static gboolean +real_is_available (NMDevice *dev) +{ + NMDeviceWired *self = NM_DEVICE_WIRED (dev); + + /* Can't do anything if there isn't a carrier */ + if (!NM_DEVICE_WIRED_GET_PRIVATE (self)->carrier) + return FALSE; + + return TRUE; +} + +static NMConnection * +connection_match_config (NMDevice *self, const GSList *connections) +{ + const GSList *iter; + + for (iter = connections; iter; iter = iter->next) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if (!nm_device_match_ip_config (self, candidate)) + continue; + + return candidate; + } + + return NULL; +} + +static void +dispose (GObject *object) +{ + NMDeviceWired *self = NM_DEVICE_WIRED (object); + NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + + if (priv->link_connected_id) { + g_signal_handler_disconnect (priv->monitor, priv->link_connected_id); + priv->link_connected_id = 0; + } + if (priv->link_disconnected_id) { + g_signal_handler_disconnect (priv->monitor, priv->link_disconnected_id); + priv->link_disconnected_id = 0; + } + + carrier_action_defer_clear (self); + + if (priv->monitor) { + g_object_unref (priv->monitor); + priv->monitor = NULL; + } + + G_OBJECT_CLASS (nm_device_wired_parent_class)->dispose (object); +} + +static void +nm_device_wired_class_init (NMDeviceWiredClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceWiredPrivate)); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->dispose = dispose; + + parent_class->hw_is_up = real_hw_is_up; + parent_class->hw_bring_up = real_hw_bring_up; + parent_class->hw_take_down = real_hw_take_down; + parent_class->can_interrupt_activation = real_can_interrupt_activation; + parent_class->update_hw_address = real_update_hw_address; + parent_class->is_available = real_is_available; + parent_class->connection_match_config = connection_match_config; +} + +/** + * nm_device_wired_get_hwaddr: + * @dev: an #NMDeviceWired + * + * Get a device's hardware address + * + * Returns: (transfer none): @dev's hardware address + */ +const guint8 * +nm_device_wired_get_hwaddr (NMDeviceWired *dev) +{ + NMDeviceWiredPrivate *priv; + + g_return_val_if_fail (dev != NULL, NULL); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + return priv->hw_addr; +} + +/** + * nm_device_wired_set_hwaddr: + * @dev: an #NMDeviceWired + * @addr: the new hardware address, @addrlen bytes in length + * @addrlen: the length in bytes of @addr + * + * Sets the device's hardware address. + */ +void +nm_device_wired_set_hwaddr (NMDeviceWired *dev, + const guint8 *addr, + guint addrlen) +{ + NMDeviceWiredPrivate *priv; + + g_return_if_fail (dev != NULL); + g_return_if_fail (addr != NULL); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + g_return_if_fail (addrlen == priv->hw_addr_len); + + memcpy (priv->hw_addr, addr, priv->hw_addr_len); +} + +/** + * nm_device_wired_get_hwaddr_type: + * @dev: an #NMDeviceWired + * + * Get the type of a device's hardware address + * + * Returns: the type of @dev's hardware address + */ +int +nm_device_wired_get_hwaddr_type (NMDeviceWired *dev) +{ + NMDeviceWiredPrivate *priv; + + g_return_val_if_fail (dev != NULL, -1); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + return priv->hw_addr_type; +} + +/** + * nm_device_wired_get_carrier: + * @dev: an #NMDeviceWired + * + * Get @dev's carrier status + * + * Return value: @dev's carrier + */ +gboolean +nm_device_wired_get_carrier (NMDeviceWired *dev) +{ + NMDeviceWiredPrivate *priv; + + g_return_val_if_fail (dev != NULL, FALSE); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + return priv->carrier; +} + +/** + * nm_device_wired_get_speed: + * @dev: an #NMDeviceWired + * + * Get @dev's speed + * + * Return value: @dev's speed in Mb/s + */ +guint32 +nm_device_wired_get_speed (NMDeviceWired *dev) +{ + NMDeviceWiredPrivate *priv; + + g_return_val_if_fail (dev != NULL, 0); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + return priv->speed; +} diff --git a/src/nm-device-wired.h b/src/nm-device-wired.h new file mode 100644 index 00000000..3180ee45 --- /dev/null +++ b/src/nm-device-wired.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef NM_DEVICE_WIRED_H +#define NM_DEVICE_WIRED_H + +#include <glib-object.h> + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIRED (nm_device_wired_get_type ()) +#define NM_DEVICE_WIRED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIRED, NMDeviceWired)) +#define NM_DEVICE_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIRED, NMDeviceWiredClass)) +#define NM_IS_DEVICE_WIRED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIRED)) +#define NM_IS_DEVICE_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIRED)) +#define NM_DEVICE_WIRED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIRED, NMDeviceWiredClass)) + +typedef struct { + NMDevice parent; +} NMDeviceWired; + +typedef struct { + NMDeviceClass parent; + +} NMDeviceWiredClass; + +GType nm_device_wired_get_type (void); + +const guint8 *nm_device_wired_get_hwaddr (NMDeviceWired *dev); +void nm_device_wired_set_hwaddr (NMDeviceWired *dev, + const guint8 *addr, + guint addrlen); +int nm_device_wired_get_hwaddr_type (NMDeviceWired *dev); +gboolean nm_device_wired_get_carrier (NMDeviceWired *dev); +guint32 nm_device_wired_get_speed (NMDeviceWired *dev); + +G_END_DECLS + +#endif /* NM_DEVICE_WIRED_H */ diff --git a/src/nm-device.c b/src/nm-device.c index 95f07e44..1dc94ee9 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -36,9 +36,9 @@ #include <linux/if.h> #include "nm-glib-compat.h" -#include "nm-device-interface.h" #include "nm-device.h" #include "nm-device-private.h" +#include "backends/nm-backend.h" #include "NetworkManagerUtils.h" #include "nm-system.h" #include "nm-dhcp-manager.h" @@ -57,31 +57,91 @@ #include "nm-ip6-manager.h" #include "nm-marshal.h" #include "nm-rfkill.h" +#include "nm-firewall-manager.h" +#include "nm-properties-changed-signal.h" +#include "nm-enum-types.h" +#include "nm-settings-connection.h" -#define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config" -#define NM_ACT_REQUEST_IP6_CONFIG "nm-act-request-ip6-config" +static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); -static void device_interface_init (NMDeviceInterface *device_interface_class); +#include "nm-device-interface-glue.h" -G_DEFINE_TYPE_EXTENDED (NMDevice, nm_device, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, - G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) +#define PENDING_IP4_CONFIG "pending-ip4-config" +#define PENDING_IP6_CONFIG "pending-ip6-config" + +#define DBUS_G_TYPE_UINT_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID)) + +/***********************************************************/ +#define NM_DEVICE_ERROR (nm_device_error_quark ()) + +static GQuark +nm_device_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-device-error"); + return quark; +} + +/***********************************************************/ enum { + STATE_CHANGED, + DISCONNECT_REQUEST, AUTOCONNECT_ALLOWED, LAST_SIGNAL, }; - static guint signals[LAST_SIGNAL] = { 0 }; +enum { + PROP_0, + PROP_UDI, + PROP_IFACE, + PROP_IP_IFACE, + PROP_DRIVER, + PROP_CAPABILITIES, + PROP_IP4_ADDRESS, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_IP6_CONFIG, + PROP_DHCP6_CONFIG, + PROP_STATE, + PROP_STATE_REASON, + PROP_ACTIVE_CONNECTION, + PROP_DEVICE_TYPE, + PROP_MANAGED, + PROP_FIRMWARE_MISSING, + PROP_TYPE_DESC, + PROP_RFKILL_TYPE, + PROP_IFINDEX, + LAST_PROP +}; + +/***********************************************************/ + +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, G_TYPE_OBJECT) + #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) +typedef enum { + IP_NONE = 0, + IP_CONF, + IP_DONE +} IpState; + +typedef struct { + NMDeviceState state; + NMDeviceStateReason reason; + guint id; +} QueuedState; + typedef struct { gboolean disposed; gboolean initialized; NMDeviceState state; - guint failed_to_disconnected_id; - guint unavailable_to_disconnected_id; + NMDeviceStateReason state_reason; + QueuedState queued_state; char * udi; char * path; @@ -104,12 +164,11 @@ typedef struct { gpointer act_source_func; guint act_source6_id; gpointer act_source6_func; + guint act_dep_result_id; + guint act_dep_timeout_id; gulong secrets_updated_id; gulong secrets_failed_id; - gboolean ip4_ready; - gboolean ip6_ready; - /* Generic DHCP stuff */ NMDHCPManager * dhcp_manager; guint32 dhcp_timeout; @@ -117,6 +176,7 @@ typedef struct { /* IP4 configuration info */ NMIP4Config * ip4_config; /* Config from DHCP, PPP, or system config files */ + IpState ip4_state; NMDHCPClient * dhcp4_client; gulong dhcp4_state_sigid; gulong dhcp4_timeout_sigid; @@ -126,45 +186,47 @@ typedef struct { NMDnsMasqManager *dnsmasq_manager; gulong dnsmasq_state_id; + /* Firewall Manager */ + NMFirewallManager *fw_manager; + DBusGProxyCall *fw_call; + /* avahi-autoipd stuff */ GPid aipd_pid; guint aipd_watch; guint aipd_timeout; - guint32 aipd_addr; /* IP6 configuration info */ NMIP6Config * ip6_config; + IpState ip6_state; + NMIP6Manager * ip6_manager; gulong ip6_addrconf_sigid; gulong ip6_config_changed_sigid; gboolean ip6_waiting_for_config; + /* IP6 config from autoconf */ + NMIP6Config * ac_ip6_config; char * ip6_accept_ra_path; - guint32 ip6_accept_ra_save; + gint32 ip6_accept_ra_save; + + /* IPv6 privacy extensions (RFC4941) */ + char * ip6_privacy_tempaddr_path; + gint32 ip6_privacy_tempaddr_save; NMDHCPClient * dhcp6_client; guint32 dhcp6_mode; gulong dhcp6_state_sigid; gulong dhcp6_timeout_sigid; NMDHCP6Config * dhcp6_config; + /* IP6 config from DHCP */ + NMIP6Config * dhcp6_ip6_config; /* inhibit autoconnect feature */ gboolean autoconnect_inhibit; -} NMDevicePrivate; - -static gboolean check_connection_compatible (NMDeviceInterface *device, - NMConnection *connection, - GError **error); -static gboolean nm_device_activate (NMDeviceInterface *device, - NMActRequest *req, - GError **error); -static void nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason); -static gboolean device_disconnect (NMDeviceInterface *device, GError **error); -static gboolean spec_match_list (NMDeviceInterface *device, const GSList *specs); -static NMConnection *connection_match_config (NMDeviceInterface *device, const GSList *connections); -static gboolean can_assume_connections (NMDeviceInterface *device); -static void nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self, int family); + /* master interface for bridge, bond, vlan, etc */ + NMDevice * master; +} NMDevicePrivate; static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason); @@ -180,32 +242,12 @@ static gboolean nm_device_set_ip6_config (NMDevice *dev, gboolean assumed, NMDeviceStateReason *reason); -static NMActStageReturn dhcp6_start (NMDevice *self, - NMConnection *connection, - guint32 dhcp_opt, - NMDeviceStateReason *reason); +static gboolean nm_device_activate_ip6_config_commit (gpointer user_data); -static void addrconf6_cleanup (NMDevice *self); -static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release); static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release); static const char *reason_to_string (NMDeviceStateReason reason); - -static void -device_interface_init (NMDeviceInterface *device_interface_class) -{ - /* interface implementation */ - device_interface_class->check_connection_compatible = check_connection_compatible; - device_interface_class->activate = nm_device_activate; - device_interface_class->deactivate = nm_device_deactivate; - device_interface_class->disconnect = device_disconnect; - device_interface_class->spec_match_list = spec_match_list; - device_interface_class->connection_match_config = connection_match_config; - device_interface_class->can_assume_connections = can_assume_connections; -} - - static void nm_device_init (NMDevice *self) { @@ -214,6 +256,7 @@ nm_device_init (NMDevice *self) priv->type = NM_DEVICE_TYPE_UNKNOWN; priv->capabilities = NM_DEVICE_CAP_NONE; priv->state = NM_DEVICE_STATE_UNMANAGED; + priv->state_reason = NM_DEVICE_STATE_REASON_NONE; priv->dhcp_timeout = 0; priv->rfkill_type = RFKILL_TYPE_UNKNOWN; } @@ -245,14 +288,50 @@ update_accept_ra_save (NMDevice *self) /* Grab the original value of "accept_ra" so we can restore it when NM exits */ priv->ip6_accept_ra_path = new_path; - if (!nm_utils_get_proc_sys_net_value (priv->ip6_accept_ra_path, - ip_iface, - &priv->ip6_accept_ra_save)) { + if (!nm_utils_get_proc_sys_net_value_with_bounds (priv->ip6_accept_ra_path, + ip_iface, + &priv->ip6_accept_ra_save, + 0, 1)) { g_free (priv->ip6_accept_ra_path); priv->ip6_accept_ra_path = NULL; } } +static void +update_ip6_privacy_save (NMDevice *self) +{ + NMDevicePrivate *priv; + const char *ip_iface; + char *new_path; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + ip_iface = nm_device_get_ip_iface (self); + + new_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/use_tempaddr", ip_iface); + g_assert (new_path); + + if (priv->ip6_privacy_tempaddr_path) { + /* If the IP iface is different from before, use the new value */ + if (!strcmp (new_path, priv->ip6_privacy_tempaddr_path)) { + g_free (new_path); + return; + } + g_free (priv->ip6_privacy_tempaddr_path); + } + + /* Grab the original value of "use_tempaddr" so we can restore it when NM exits */ + priv->ip6_privacy_tempaddr_path = new_path; + if (!nm_utils_get_proc_sys_net_value (priv->ip6_privacy_tempaddr_path, + ip_iface, + &priv->ip6_privacy_tempaddr_save)) { + g_free (priv->ip6_privacy_tempaddr_path); + priv->ip6_privacy_tempaddr_path = NULL; + } +} + static GObject* constructor (GType type, guint n_construct_params, @@ -287,18 +366,12 @@ constructor (GType type, goto error; } - if (NM_DEVICE_GET_CLASS (dev)->update_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_hw_address (dev); - - if (NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address (dev); - - if (NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev); - priv->dhcp_manager = nm_dhcp_manager_get (); + priv->fw_manager = nm_firewall_manager_get (); + update_accept_ra_save (dev); + update_ip6_privacy_save (dev); priv->initialized = TRUE; return object; @@ -308,6 +381,24 @@ error: return NULL; } +static void +constructed (GObject *object) +{ + NMDevice *dev = NM_DEVICE (object); + + if (NM_DEVICE_GET_CLASS (dev)->update_hw_address) + NM_DEVICE_GET_CLASS (dev)->update_hw_address (dev); + + if (NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address) + NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address (dev); + + if (NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address) + NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev); + + if (G_OBJECT_CLASS (nm_device_parent_class)->constructed) + G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); +} + static gboolean nm_device_hw_is_up (NMDevice *self) { @@ -412,14 +503,14 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) priv->ip_iface = g_strdup (iface); if (priv->ip_iface) { priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface); - if (!priv->ip_ifindex) { + if (priv->ip_ifindex < 0) { nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", iface); } } /* Emit change notification */ if (g_strcmp0 (old_ip_iface, priv->ip_iface)) - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_IP_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); g_free (old_ip_iface); } @@ -494,6 +585,51 @@ nm_device_get_type_desc (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->type_desc; } +/** + * nm_device_enslave_slave: + * @dev: the master device + * @slave: the slave device to enslave + * + * If @dev is capable of enslaving other devices (ie it's a bridge, bond, etc) + * then this function enslaves @slave. + * + * Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave + * other devices. + */ +gboolean +nm_device_enslave_slave (NMDevice *dev, NMDevice *slave) +{ + g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (slave != NULL, FALSE); + g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); + + if (NM_DEVICE_GET_CLASS (dev)->enslave_slave) + return NM_DEVICE_GET_CLASS (dev)->enslave_slave (dev, slave); + return FALSE; +} + +/** + * nm_device_release_slave: + * @dev: the master device + * @slave: the slave device to release + * + * If @dev is capable of enslaving other devices (ie it's a bridge, bond, etc) + * then this function releases the previously enslaved @slave. + * + * Returns: %TRUE on success, %FALSE on failure, if this device cannot enslave + * other devices, or if @slave was never enslaved. + */ +gboolean +nm_device_release_slave (NMDevice *dev, NMDevice *slave) +{ + g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (slave != NULL, FALSE); + + if (NM_DEVICE_GET_CLASS (dev)->release_slave) + return NM_DEVICE_GET_CLASS (dev)->release_slave (dev, slave); + return FALSE; +} + /* * nm_device_get_act_request * @@ -508,6 +644,13 @@ nm_device_get_act_request (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->act_request; } +NMConnection * +nm_device_get_connection (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + return priv->act_request ? nm_act_request_get_connection (priv->act_request) : NULL; +} gboolean nm_device_is_available (NMDevice *self) @@ -522,6 +665,36 @@ nm_device_is_available (NMDevice *self) return TRUE; } +gboolean +nm_device_get_enabled (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + if (NM_DEVICE_GET_CLASS (self)->get_enabled) + return NM_DEVICE_GET_CLASS (self)->get_enabled (self); + return TRUE; +} + +void +nm_device_set_enabled (NMDevice *self, gboolean enabled) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); + + if (NM_DEVICE_GET_CLASS (self)->set_enabled) + NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled); +} + +RfKillType +nm_device_get_rfkill_type (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + return NM_DEVICE_GET_PRIVATE (self)->rfkill_type; +} + static gboolean autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, GValue *return_accu, @@ -589,9 +762,7 @@ nm_device_complete_connection (NMDevice *self, g_return_val_if_fail (connection != NULL, FALSE); if (!NM_DEVICE_GET_CLASS (self)->complete_connection) { - g_set_error (error, - NM_DEVICE_INTERFACE_ERROR, - NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID, + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CONNECTION_INVALID, "Device class %s had no complete_connection method", G_OBJECT_TYPE_NAME (self)); return FALSE; @@ -605,9 +776,41 @@ nm_device_complete_connection (NMDevice *self, if (success) success = nm_connection_verify (connection, error); + /* If ip6-privacy is unknown, enable it with temporary address preferred */ + if (success) { + NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6 && nm_setting_ip6_config_get_ip6_privacy (s_ip6) == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NULL); + } + return success; } +gboolean +nm_device_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (device != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + if (NM_DEVICE_GET_CLASS (device)->check_connection_compatible) + return NM_DEVICE_GET_CLASS (device)->check_connection_compatible (device, connection, error); + return TRUE; +} + +gboolean +nm_device_can_assume_connections (NMDevice *device) +{ + g_return_val_if_fail (device != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return !!NM_DEVICE_GET_CLASS (device)->connection_match_config; +} + static void dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data) { @@ -679,25 +882,22 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) { - NMActRequest *req; NMConnection *connection; NMSettingIP4Config *s_ip4; NMSettingIP6Config *s_ip6; g_return_val_if_fail (self != NULL, TRUE); - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (self); g_assert (connection); /* Fail the connection if the failed IP method is required to complete */ if (ip6) { - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6)) return TRUE; } else { - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4)) return TRUE; } @@ -705,185 +905,48 @@ nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) return FALSE; } -static void -ip6_addrconf_complete (NMIP6Manager *ip6_manager, - int ifindex, - guint dhcp_opts, - gboolean success, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *req; - NMConnection *connection; - NMActStageReturn ret; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - NMDeviceState state; - - if (ifindex != nm_device_get_ip_ifindex (self)) - return; - req = nm_device_get_act_request (self); - if (!req) - return; - connection = nm_act_request_get_connection (req); - g_assert (connection); - - if (!priv->ip6_waiting_for_config) - return; - - priv->ip6_waiting_for_config = FALSE; - - if (!success) { - nm_device_activate_schedule_stage4_ip6_config_timeout (self); - return; - } - - priv->dhcp6_mode = dhcp_opts; - - /* If addrconf is all that's required, we're done */ - if (priv->dhcp6_mode == IP6_DHCP_OPT_NONE) { - nm_device_activate_schedule_stage4_ip6_config_get (self); - return; - } - - /* If the router said to use DHCP for managed or otherconf, do it */ - - /* Don't re-start DHCPv6 if it's already in progress */ - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - if ((state != NM_DEVICE_STATE_IP_CONFIG) || priv->dhcp6_client) - return; - - nm_log_info (LOGD_DEVICE | LOGD_DHCP6, - "Activation (%s) Stage 3 of 5 (IP Configure Start) starting DHCPv6" - " as requested by IPv6 router...", - priv->iface); - - ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason); - switch (ret) { - case NM_ACT_STAGE_RETURN_SUCCESS: - /* Shouldn't get this, but handle it anyway */ - g_warn_if_reached (); - nm_device_activate_schedule_stage4_ip6_config_get (self); - break; - case NM_ACT_STAGE_RETURN_POSTPONE: - /* Success; wait for DHCPv6 to complete */ - break; - default: - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - break; - } -} - -static void -ip6_config_changed (NMIP6Manager *ip6_manager, - int ifindex, - guint dhcp_opts, - gboolean success, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - if (ifindex != nm_device_get_ip_ifindex (self)) - return; - if (!nm_device_get_act_request (self)) - return; - - /* FIXME: re-run DHCPv6 here to get any new nameservers or whatever */ - - if (!success && (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED)) { - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return; - } - - nm_device_activate_schedule_stage4_ip6_config_get (self); -} - static gboolean ip6_method_matches (NMConnection *connection, const char *match) { NMSettingIP6Config *s_ip6; const char *method = NULL; - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) { method = nm_setting_ip6_config_get_method (s_ip6); g_assert (method); } - /* Treat missing IP6 setting as IGNORE */ - if (!s_ip6 && !strcmp (match, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) + /* Treat missing IP6 setting as AUTO */ + if (!s_ip6 && !strcmp (match, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) return TRUE; return method && !strcmp (method, match); } -static gboolean -addrconf6_setup (NMDevice *self) +static NMActStageReturn +real_act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActRequest *req; - NMConnection *connection; - NMSettingIP6Config *s_ip6; - gboolean success; + NMActiveConnection *master_ac; + NMDevice *master; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; req = nm_device_get_act_request (self); g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); - - if (!priv->ip6_manager) { - priv->ip6_manager = nm_ip6_manager_get (); - priv->ip6_addrconf_sigid = g_signal_connect (priv->ip6_manager, - "addrconf-complete", - G_CALLBACK (ip6_addrconf_complete), - self); - priv->ip6_config_changed_sigid = g_signal_connect (priv->ip6_manager, - "config-changed", - G_CALLBACK (ip6_config_changed), - self); - } - - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); - success = nm_ip6_manager_prepare_interface (priv->ip6_manager, - nm_device_get_ip_ifindex (self), - s_ip6, - priv->ip6_accept_ra_path); - if (success) - priv->ip6_waiting_for_config = TRUE; - - return success; -} - -static void -addrconf6_cleanup (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!priv->ip6_manager) - return; + /* If the interface is going to be a slave, let the master enslave it here */ + master_ac = nm_act_request_get_dependency (req); + if (master_ac && NM_IS_ACT_REQUEST (master_ac)) { + /* FIXME: handle VPNs here too */ - if (priv->ip6_addrconf_sigid) { - g_signal_handler_disconnect (priv->ip6_manager, - priv->ip6_addrconf_sigid); - priv->ip6_addrconf_sigid = 0; - } - if (priv->ip6_config_changed_sigid) { - g_signal_handler_disconnect (priv->ip6_manager, - priv->ip6_config_changed_sigid); - priv->ip6_config_changed_sigid = 0; + master = NM_DEVICE (nm_act_request_get_device (NM_ACT_REQUEST (master_ac))); + g_assert (master); + if (!nm_device_enslave_slave (master, self)) + ret = NM_ACT_STAGE_RETURN_FAILURE; } - nm_ip6_manager_cancel_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self)); - g_object_unref (priv->ip6_manager); - priv->ip6_manager = NULL; -} - -static NMActStageReturn -real_act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason) -{ - return NM_ACT_STAGE_RETURN_SUCCESS; + return ret; } /* @@ -904,7 +967,12 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); - priv->ip4_ready = priv->ip6_ready = FALSE; + if (priv->act_dep_timeout_id) { + g_source_remove (priv->act_dep_timeout_id); + priv->act_dep_timeout_id = 0; + } + + priv->ip4_state = priv->ip6_state = IP_NONE; iface = nm_device_get_iface (self); nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); @@ -1029,6 +1097,9 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) nm_device_get_iface (self)); } +/*********************************************/ +/* avahi-autoipd stuff */ + static void aipd_timeout_remove (NMDevice *self) { @@ -1062,28 +1133,20 @@ aipd_cleanup (NMDevice *self) } aipd_timeout_remove (self); - - priv->aipd_addr = 0; } static NMIP4Config * -aipd_get_ip4_config (NMDevice *self, NMDeviceStateReason *reason) +aipd_get_ip4_config (NMDevice *self, struct in_addr lla) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMIP4Config *config = NULL; NMIP4Address *addr; NMIP4Route *route; - g_return_val_if_fail (priv->aipd_addr > 0, NULL); - config = nm_ip4_config_new (); - if (!config) { - *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - return NULL; - } + g_assert (config); addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, (guint32) priv->aipd_addr); + nm_ip4_address_set_address (addr, (guint32) lla.s_addr); nm_ip4_address_set_prefix (addr, 16); nm_ip4_config_take_address (config, addr); @@ -1098,35 +1161,19 @@ aipd_get_ip4_config (NMDevice *self, NMDeviceStateReason *reason) return config; } -static gboolean -handle_autoip_change (NMDevice *self, NMDeviceStateReason *reason) +static void +autoip_changed (NMDevice *self, + NMIP4Config *config, + NMSettingIP4Config *s_ip4) { - NMActRequest *req; - NMConnection *connection; - NMIP4Config *config; - - g_return_val_if_fail (reason != NULL, FALSE); - - config = aipd_get_ip4_config (self, reason); - if (!config) { - nm_log_err (LOGD_AUTOIP4, "failed to get autoip config for rebind"); - return FALSE; - } - - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); - - g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config); + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - if (!nm_device_set_ip4_config (self, config, FALSE, reason)) { + nm_utils_merge_ip4_config (config, s_ip4); + if (!nm_device_set_ip4_config (self, config, FALSE, &reason)) { nm_log_err (LOGD_AUTOIP4, "(%s): failed to update IP4 config in response to autoip event.", - nm_device_get_iface (self)); - return FALSE; + nm_device_get_iface (self)); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } - - return TRUE; } #define IPV4LL_NETWORK (htonl (0xA9FE0000L)) @@ -1138,74 +1185,62 @@ nm_device_handle_autoip4_event (NMDevice *self, const char *address) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *req; NMConnection *connection = NULL; NMSettingIP4Config *s_ip4 = NULL; - NMDeviceState state; const char *iface, *method = NULL; g_return_if_fail (event != NULL); - req = nm_device_get_act_request (self); - if (!req) + if (priv->act_request == NULL) return; - connection = nm_act_request_get_connection (req); - if (!connection) - return; + connection = nm_act_request_get_connection (priv->act_request); + g_assert (connection); /* Ignore if the connection isn't an AutoIP connection */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); - if (!s_ip4 || !method || strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0) return; iface = nm_device_get_iface (self); - state = nm_device_get_state (self); if (strcmp (event, "BIND") == 0) { - struct in_addr ip; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + struct in_addr lla; + NMIP4Config *config; - if (inet_pton (AF_INET, address, &ip) <= 0) { + if (inet_pton (AF_INET, address, &lla) <= 0) { nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd.", iface, address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } - if ((ip.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) { + if ((lla.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) { nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd (not link-local).", iface, address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } - switch (state) { - case NM_DEVICE_STATE_IP_CONFIG: - if (priv->aipd_addr) { - nm_log_warn (LOGD_AUTOIP4, "(%s): already have autoip address!", iface); - return; - } + config = aipd_get_ip4_config (self, lla); + if (config == NULL) { + nm_log_err (LOGD_AUTOIP4, "failed to get autoip config"); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } - priv->aipd_addr = ip.s_addr; + if (priv->ip4_state == IP_CONF) { aipd_timeout_remove (self); - nm_device_activate_schedule_stage4_ip4_config_get (self); - break; - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_ACTIVATED: - priv->aipd_addr = ip.s_addr; - if (!handle_autoip_change (self, &reason)) - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - break; - default: - nm_log_warn (LOGD_AUTOIP4, "(%s): unexpected avahi-autoip event %s for %s.", - iface, event, address); - break; - } + nm_device_activate_schedule_ip4_config_result (self, config); + } else if (priv->ip4_state == IP_DONE) { + autoip_changed (self, config, s_ip4); + } else + g_assert_not_reached (); + + g_object_unref (config); } else { nm_log_warn (LOGD_AUTOIP4, "(%s): autoip address %s no longer valid because '%s'.", iface, address, event); @@ -1255,15 +1290,14 @@ aipd_timeout_cb (gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!priv->aipd_timeout) - return FALSE; - priv->aipd_timeout = 0; - - nm_log_info (LOGD_AUTOIP4, "(%s): avahi-autoipd timed out.", nm_device_get_iface (self)); - aipd_cleanup (self); + if (priv->aipd_timeout) { + nm_log_info (LOGD_AUTOIP4, "(%s): avahi-autoipd timed out.", nm_device_get_iface (self)); + priv->aipd_timeout = 0; + aipd_cleanup (self); - if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) - nm_device_activate_schedule_stage4_ip4_config_timeout (self); + if (priv->ip4_state == IP_CONF) + nm_device_activate_schedule_ip4_config_timeout (self); + } return FALSE; } @@ -1279,12 +1313,12 @@ aipd_child_setup (gpointer user_data G_GNUC_UNUSED) setpgid (pid, pid); } -static gboolean -aipd_exec (NMDevice *self, GError **error) +static NMActStageReturn +aipd_start (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + const char *iface = nm_device_get_iface (self); char *argv[6], *cmdline; - gboolean success = FALSE; const char **aipd_binary = NULL; static const char *aipd_paths[] = { "/usr/sbin/avahi-autoipd", @@ -1292,6 +1326,7 @@ aipd_exec (NMDevice *self, GError **error) NULL }; int i = 0; + GError *error = NULL; aipd_cleanup (self); @@ -1304,8 +1339,11 @@ aipd_exec (NMDevice *self, GError **error) } if (!*aipd_binary) { - g_set_error (error, 0, 0, "%s", "couldn't find avahi-autoipd"); - return FALSE; + nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: not found", iface); + *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; } argv[i++] = (char *) (*aipd_binary); @@ -1317,13 +1355,24 @@ aipd_exec (NMDevice *self, GError **error) argv[i++] = NULL; cmdline = g_strjoinv (" ", argv); - nm_log_dbg(LOGD_AUTOIP4, "running: %s", cmdline); + nm_log_dbg (LOGD_AUTOIP4, "running: %s", cmdline); g_free (cmdline); - success = g_spawn_async ("/", argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, - &aipd_child_setup, NULL, &(priv->aipd_pid), error); - if (!success) - return FALSE; + if (!g_spawn_async ("/", argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, + &aipd_child_setup, NULL, &(priv->aipd_pid), &error)) { + nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: %s", + iface, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + aipd_cleanup (self); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + nm_log_info (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation (%s) Stage 3 of 5 (IP Configure Start) started" + " avahi-autoipd...", iface); /* Monitor the child process so we know when it dies */ priv->aipd_watch = g_child_watch_add (priv->aipd_pid, aipd_watch_cb, self); @@ -1331,9 +1380,12 @@ aipd_exec (NMDevice *self, GError **error) /* Start a timeout to bound the address attempt */ priv->aipd_timeout = g_timeout_add_seconds (20, aipd_timeout_cb, self); - return TRUE; + return NM_ACT_STAGE_RETURN_POSTPONE; } +/*********************************************/ +/* DHCPv4 stuff */ + static void dhcp4_add_option_cb (gpointer key, gpointer value, gpointer user_data) { @@ -1343,156 +1395,95 @@ dhcp4_add_option_cb (gpointer key, gpointer value, gpointer user_data) } static void -dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data) +dhcp4_lease_change (NMDevice *device, NMIP4Config *config) { - nm_dhcp6_config_add_option (NM_DHCP6_CONFIG (user_data), - (const char *) key, - (const char *) value); -} - -static void -handle_dhcp_lease_change (NMDevice *device, gboolean ipv6) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMIP4Config *ip4_config; - NMSettingIP4Config *s_ip4; - NMIP6Config *ip6_config; - NMSettingIP6Config *s_ip6; NMConnection *connection; - NMActRequest *req; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - gboolean assumed; - req = nm_device_get_act_request (device); - g_assert (req); - connection = nm_act_request_get_connection (req); + if (config == NULL) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to get DHCPv4 config for rebind", + nm_device_get_ip_iface (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + return; + } + + connection = nm_device_get_connection (device); g_assert (connection); - assumed = nm_act_request_get_assumed (req); - - if (ipv6) { - ip6_config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); - if (!ip6_config) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to get DHCPv6 config for rebind", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - return; - } - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); - nm_utils_merge_ip6_config (ip6_config, s_ip6); + /* Merge with user overrides */ + nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection)); - g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP6_CONFIG, ip6_config); + if (!nm_device_set_ip4_config (device, config, FALSE, &reason)) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv4 config in response to DHCP event.", + nm_device_get_ip_iface (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + return; + } - if (nm_device_set_ip6_config (device, ip6_config, assumed, &reason)) { - nm_dhcp6_config_reset (priv->dhcp6_config); - nm_dhcp_client_foreach_option (priv->dhcp6_client, - dhcp6_add_option_cb, - priv->dhcp6_config); - nm_utils_call_dispatcher ("dhcp6-change", connection, device, NULL, NULL, NULL); - } else { - nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - } - } else { - ip4_config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); - if (!ip4_config) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to get DHCPv4 config for rebind", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - return; - } + /* Notify dispatcher scripts of new DHCP4 config */ + nm_utils_call_dispatcher ("dhcp4-change", connection, device, NULL, NULL, NULL); +} - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); - nm_utils_merge_ip4_config (ip4_config, s_ip4); +static void +dhcp4_fail (NMDevice *device, gboolean timeout) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, ip4_config); + nm_dhcp4_config_reset (priv->dhcp4_config); - if (nm_device_set_ip4_config (device, ip4_config, assumed, &reason)) { - nm_dhcp4_config_reset (priv->dhcp4_config); - nm_dhcp_client_foreach_option (priv->dhcp4_client, - dhcp4_add_option_cb, - priv->dhcp4_config); - nm_utils_call_dispatcher ("dhcp4-change", connection, device, NULL, NULL, NULL); - } else { - nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv4 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - } - } + if (timeout || (priv->ip4_state == IP_CONF)) + nm_device_activate_schedule_ip4_config_timeout (device); + else if (priv->ip4_state == IP_DONE) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); } static void -dhcp_state_changed (NMDHCPClient *client, - NMDHCPState state, - gpointer user_data) +dhcp4_state_changed (NMDHCPClient *client, + NMDHCPState state, + gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); NMDeviceState dev_state; - gboolean ipv6; + NMIP4Config *config; - ipv6 = nm_dhcp_client_get_ipv6 (client); - dev_state = nm_device_get_state (device); + g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); - if (ipv6) { - nm_log_dbg (LOGD_DHCP6, "(%s): new DHCPv6 client state %d", - nm_device_get_iface (device), dev_state); - } else { - nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", - nm_device_get_iface (device), dev_state); - } + nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", + nm_device_get_iface (device), state); + + dev_state = nm_device_get_state (device); switch (state) { case DHC_BOUND4: /* lease obtained */ - case DHC_BOUND6: case DHC_RENEW4: /* lease renewed */ - case DHC_RENEW6: /* lease renewed */ case DHC_REBOOT: /* have valid lease, but now obtained a different one */ case DHC_REBIND4: /* new, different lease */ - case DHC_REBIND6: /* new, different lease */ - if (dev_state == NM_DEVICE_STATE_IP_CONFIG) { - if (ipv6) - nm_device_activate_schedule_stage4_ip6_config_get (device); - else - nm_device_activate_schedule_stage4_ip4_config_get (device); - } else if (dev_state == NM_DEVICE_STATE_ACTIVATED) - handle_dhcp_lease_change (device, ipv6); - break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ - if (ipv6) { - nm_dhcp6_config_reset (priv->dhcp6_config); - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) - nm_device_activate_schedule_stage4_ip6_config_timeout (device); - } else { + config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); + if (priv->ip4_state == IP_CONF) + nm_device_activate_schedule_ip4_config_result (device, config); + else if (priv->ip4_state == IP_DONE) + dhcp4_lease_change (device, config); + + if (config) { + /* Update the DHCP4 config object with new DHCP options */ nm_dhcp4_config_reset (priv->dhcp4_config); - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) - nm_device_activate_schedule_stage4_ip4_config_timeout (device); + nm_dhcp_client_foreach_option (priv->dhcp4_client, + dhcp4_add_option_cb, + priv->dhcp4_config); + g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP4_CONFIG); + + g_object_unref (config); } break; + case DHC_TIMEOUT: /* timed out contacting DHCP server */ + dhcp4_fail (device, TRUE); + break; case DHC_END: /* dhclient exited normally */ - /* In IPv6 info-only mode, the client doesn't handle leases so it - * may exit right after getting a response from the server. That's - * normal. In that case we just ignore the exit. - */ - if (ipv6 && (priv->dhcp6_mode == IP6_DHCP_OPT_OTHERCONF)) - break; - /* Otherwise, fall through */ case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ case DHC_ABEND: /* dhclient exited abnormally */ - if (ipv6) - nm_dhcp6_config_reset (priv->dhcp6_config); - else - nm_dhcp4_config_reset (priv->dhcp4_config); - /* dhclient quit and can't get/renew a lease; so kill the connection */ - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { - if (ipv6) - nm_device_activate_schedule_stage4_ip6_config_timeout (device); - else - nm_device_activate_schedule_stage4_ip4_config_timeout (device); - } else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + dhcp4_fail (device, FALSE); break; default: break; @@ -1500,21 +1491,15 @@ dhcp_state_changed (NMDHCPClient *client, } static void -dhcp_timeout (NMDHCPClient *client, gpointer user_data) +dhcp4_timeout (NMDHCPClient *client, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); - if (!nm_device_get_act_request (device)) - return; + g_return_if_fail (nm_device_get_act_request (device) != NULL); + g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); nm_dhcp_client_stop (client, FALSE); - - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { - if (nm_dhcp_client_get_ipv6 (client)) - nm_device_activate_schedule_stage4_ip6_config_timeout (device); - else - nm_device_activate_schedule_stage4_ip4_config_timeout (device); - } + dhcp4_fail (device, TRUE); } static NMActStageReturn @@ -1526,7 +1511,7 @@ dhcp4_start (NMDevice *self, NMSettingIP4Config *s_ip4; guint8 *anycast = NULL; - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (priv->dhcp_anycast_address) anycast = priv->dhcp_anycast_address->data; @@ -1551,11 +1536,11 @@ dhcp4_start (NMDevice *self, priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client, "state-changed", - G_CALLBACK (dhcp_state_changed), + G_CALLBACK (dhcp4_state_changed), self); priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client, "timeout", - G_CALLBACK (dhcp_timeout), + G_CALLBACK (dhcp4_timeout), self); /* DHCP devices will be notified by the DHCP manager when stuff happens */ @@ -1568,7 +1553,6 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActStageReturn ret; NMDeviceStateReason reason; - NMActRequest *req; NMConnection *connection; g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); @@ -1579,9 +1563,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) /* Terminate old DHCP instance and release the old lease */ dhcp4_cleanup (self, TRUE, release); - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (self); g_assert (connection); /* Start DHCP again on the interface */ @@ -1590,63 +1572,315 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) return (ret != NM_ACT_STAGE_RETURN_FAILURE); } +/*********************************************/ + +static GHashTable *shared_ips = NULL; + +static void +release_shared_ip (gpointer data) +{ + g_hash_table_remove (shared_ips, data); +} + +static guint32 +reserve_shared_ip (void) +{ + guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */ + guint32 count = 0; + + while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) { + count += ntohl (0x100); + if (count > ntohl (0xFE00)) { + nm_log_err (LOGD_SHARING, "ran out of shared IP addresses!"); + return 0; + } + } + + g_hash_table_insert (shared_ips, GUINT_TO_POINTER (start + count), GUINT_TO_POINTER (TRUE)); + return start + count; +} + +static NMIP4Config * +shared4_new_config (NMDevice *self, NMDeviceStateReason *reason) +{ + NMIP4Config *config = NULL; + NMIP4Address *addr; + guint32 tmp_addr; + + g_return_val_if_fail (self != NULL, NULL); + + if (G_UNLIKELY (shared_ips == NULL)) + shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal); + + tmp_addr = reserve_shared_ip (); + if (!tmp_addr) { + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NULL; + } + + config = nm_ip4_config_new (); + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, tmp_addr); + nm_ip4_address_set_prefix (addr, 24); + nm_ip4_config_take_address (config, addr); + + /* Remove the address lock when the object gets disposed */ + g_object_set_data_full (G_OBJECT (config), "shared-ip", + GUINT_TO_POINTER (tmp_addr), release_shared_ip); + + return config; +} + +/*********************************************/ + static NMActStageReturn -real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) +real_act_stage3_ip4_config_start (NMDevice *self, + NMIP4Config **out_config, + NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; NMSettingIP4Config *s_ip4; - NMActRequest *req; - NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - const char *method = NULL; - int ifindex; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + const char *method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - /* Make sure the interface is up before trying to do anything with it */ - ifindex = nm_device_get_ip_ifindex (self); - if (!nm_system_iface_is_up (ifindex)) - nm_system_iface_set_up (ifindex, TRUE, NULL); - - req = nm_device_get_act_request (self); - connection = nm_act_request_get_connection (req); - - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + connection = nm_device_get_connection (self); + g_assert (connection); /* If we did not receive IP4 configuration information, default to DHCP */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); + else if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + /* Start IPv4 addressing based on the method requested */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) ret = dhcp4_start (self, connection, reason); - } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { - GError *error = NULL; - const char *iface = nm_device_get_iface (self); - - /* Start avahi-autoipd */ - if (aipd_exec (self, &error)) { - nm_log_info (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) started" - " avahi-autoipd...", iface); - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else { - nm_log_info (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" - " to start avahi-autoipd: %s", iface, error->message); - g_error_free (error); - aipd_cleanup (self); - *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED; + else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) + ret = aipd_start (self, reason); + else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) { + /* Use only IPv4 config from the connection data */ + *out_config = nm_ip4_config_new (); + g_assert (*out_config); + ret = NM_ACT_STAGE_RETURN_SUCCESS; + } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { + *out_config = shared4_new_config (self, reason); + if (*out_config) { + priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self)); + ret = NM_ACT_STAGE_RETURN_SUCCESS; + } else ret = NM_ACT_STAGE_RETURN_FAILURE; - } } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { /* Nothing to do... */ - priv->ip4_ready = TRUE; ret = NM_ACT_STAGE_RETURN_STOP; + } else { + nm_log_warn (LOGD_IP4, "(%s): unhandled IPv4 config method; will fail", + nm_device_get_ip_iface (self)); } return ret; } +/*********************************************/ +/* DHCPv6 stuff */ + +static void +dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data) +{ + nm_dhcp6_config_add_option (NM_DHCP6_CONFIG (user_data), + (const char *) key, + (const char *) value); +} + +static void +merge_ip6_configs (NMIP6Config *dst, NMIP6Config *src) +{ + guint32 i; + + g_return_if_fail (src != NULL); + g_return_if_fail (dst != NULL); + + /* addresses */ + for (i = 0; i < nm_ip6_config_get_num_addresses (src); i++) + nm_ip6_config_add_address (dst, nm_ip6_config_get_address (src, i)); + + /* ptp address; only replace if src doesn't have one */ + if (!nm_ip6_config_get_ptp_address (dst)) + nm_ip6_config_set_ptp_address (dst, nm_ip6_config_get_ptp_address (src)); + + /* nameservers */ + for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++) + nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i)); + + /* routes */ + for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) + nm_ip6_config_add_route (dst, nm_ip6_config_get_route (src, i)); + + /* domains */ + for (i = 0; i < nm_ip6_config_get_num_domains (src); i++) + nm_ip6_config_add_domain (dst, nm_ip6_config_get_domain (src, i)); + + /* dns searches */ + for (i = 0; i < nm_ip6_config_get_num_searches (src); i++) + nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i)); + + if (!nm_ip6_config_get_mss (dst)) + nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src)); +} + +static gboolean +ip6_config_merge_and_apply (NMDevice *self, + NMIP6Config *src_config, + NMDeviceStateReason *out_reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + gboolean assumed, success; + NMIP6Config *composite; + + connection = nm_device_get_connection (self); + g_assert (connection); + + /* If no config was passed in, create a new one */ + composite = nm_ip6_config_new (); + g_assert (composite); + + /* Merge in the given config first, if any */ + if (src_config) + merge_ip6_configs (composite, src_config); + + /* Merge RA and DHCPv6 configs into the composite config */ + if (priv->ac_ip6_config && (src_config != priv->ac_ip6_config)) + merge_ip6_configs (composite, priv->ac_ip6_config); + if (priv->dhcp6_ip6_config && (src_config != priv->dhcp6_ip6_config)) + merge_ip6_configs (composite, priv->dhcp6_ip6_config); + + /* Merge user overrides into the composite config */ + nm_utils_merge_ip6_config (composite, nm_connection_get_setting_ip6_config (connection)); + + assumed = nm_act_request_get_assumed (priv->act_request); + success = nm_device_set_ip6_config (self, composite, assumed, out_reason); + g_object_unref (composite); + return success; +} + +static void +dhcp6_lease_change (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMConnection *connection; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + + if (priv->dhcp6_ip6_config == NULL) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to get DHCPv6 config for rebind", + nm_device_get_ip_iface (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + return; + } + + g_assert (priv->dhcp6_client); /* sanity check */ + + connection = nm_device_get_connection (device); + g_assert (connection); + + /* Apply the updated config */ + if (ip6_config_merge_and_apply (device, NULL, &reason) == FALSE) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.", + nm_device_get_ip_iface (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + } else { + /* Notify dispatcher scripts of new DHCPv6 config */ + nm_utils_call_dispatcher ("dhcp6-change", connection, device, NULL, NULL, NULL); + } +} + +static void +dhcp6_fail (NMDevice *device, gboolean timeout) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + + nm_dhcp6_config_reset (priv->dhcp6_config); + + if (timeout || (priv->ip6_state == IP_CONF)) + nm_device_activate_schedule_ip6_config_timeout (device); + else if (priv->ip6_state == IP_DONE) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); +} + +static void +dhcp6_state_changed (NMDHCPClient *client, + NMDHCPState state, + gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDeviceState dev_state; + + g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); + + nm_log_dbg (LOGD_DHCP6, "(%s): new DHCPv6 client state %d", + nm_device_get_iface (device), state); + + dev_state = nm_device_get_state (device); + + switch (state) { + case DHC_BOUND6: + case DHC_RENEW6: /* lease renewed */ + case DHC_REBOOT: /* have valid lease, but now obtained a different one */ + case DHC_REBIND6: /* new, different lease */ + if (priv->dhcp6_ip6_config) + g_object_unref (priv->dhcp6_ip6_config); + priv->dhcp6_ip6_config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); + if (priv->ip6_state == IP_CONF) + nm_device_activate_schedule_ip6_config_result (device, priv->dhcp6_ip6_config); + else if (priv->ip6_state == IP_DONE) + dhcp6_lease_change (device); + + if (priv->dhcp6_ip6_config) { + /* Update the DHCP6 config object with new DHCP options */ + nm_dhcp6_config_reset (priv->dhcp6_config); + nm_dhcp_client_foreach_option (priv->dhcp6_client, + dhcp6_add_option_cb, + priv->dhcp6_config); + g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG); + } + break; + case DHC_TIMEOUT: /* timed out contacting DHCP server */ + dhcp6_fail (device, TRUE); + break; + case DHC_END: /* dhclient exited normally */ + /* In IPv6 info-only mode, the client doesn't handle leases so it + * may exit right after getting a response from the server. That's + * normal. In that case we just ignore the exit. + */ + if (priv->dhcp6_mode == IP6_DHCP_OPT_OTHERCONF) + break; + /* Otherwise, fall through */ + case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ + case DHC_ABEND: /* dhclient exited abnormally */ + /* dhclient quit and can't get/renew a lease; so kill the connection */ + dhcp6_fail (device, FALSE); + break; + default: + break; + } +} + +static void +dhcp6_timeout (NMDHCPClient *client, gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + + g_return_if_fail (nm_device_get_act_request (device) != NULL); + g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); + + nm_dhcp_client_stop (client, FALSE); + dhcp6_fail (device, TRUE); +} + static NMActStageReturn dhcp6_start (NMDevice *self, NMConnection *connection, @@ -1656,17 +1890,12 @@ dhcp6_start (NMDevice *self, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; guint8 *anycast = NULL; - NMSettingIP6Config *s_ip6; const char *ip_iface; const struct in6_addr dest = { { { 0xFF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; int err; if (!connection) { - NMActRequest *req; - - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (self); g_assert (connection); } @@ -1680,6 +1909,12 @@ dhcp6_start (NMDevice *self, g_object_unref (priv->dhcp6_config); priv->dhcp6_config = nm_dhcp6_config_new (); + g_warn_if_fail (priv->dhcp6_ip6_config == NULL); + if (priv->dhcp6_ip6_config) { + g_object_unref (priv->dhcp6_ip6_config); + priv->dhcp6_ip6_config = NULL; + } + /* DHCPv6 communicates with the DHCPv6 server via two multicast addresses, * ff02::1:2 (link-scope) and ff05::1:3 (site-scope). Make sure we have * a multicast route (ff00::/8) for client <-> server communication. @@ -1692,24 +1927,22 @@ dhcp6_start (NMDevice *self, priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror (err)); } - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); - ip_iface = nm_device_get_ip_iface (self); priv->dhcp6_client = nm_dhcp_manager_start_ip6 (priv->dhcp_manager, ip_iface, nm_connection_get_uuid (connection), - s_ip6, + nm_connection_get_setting_ip6_config (connection), priv->dhcp_timeout, anycast, (dhcp_opt == IP6_DHCP_OPT_OTHERCONF) ? TRUE : FALSE); if (priv->dhcp6_client) { priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client, "state-changed", - G_CALLBACK (dhcp_state_changed), + G_CALLBACK (dhcp6_state_changed), self); priv->dhcp6_timeout_sigid = g_signal_connect (priv->dhcp6_client, "timeout", - G_CALLBACK (dhcp_timeout), + G_CALLBACK (dhcp6_timeout), self); /* DHCP devices will be notified by the DHCP manager when stuff happens */ @@ -1722,36 +1955,215 @@ dhcp6_start (NMDevice *self, return ret; } +/******************************************/ + +static void +ip6_addrconf_complete (NMIP6Manager *ip6_manager, + int ifindex, + guint dhcp_opts, + gboolean success, + gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + NMActStageReturn ret; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + + if (ifindex != nm_device_get_ip_ifindex (self)) + return; + g_return_if_fail (priv->act_request != NULL); + connection = nm_device_get_connection (self); + g_assert (connection); + + if (!priv->ip6_waiting_for_config) + return; + + priv->ip6_waiting_for_config = FALSE; + + if (!success) { + nm_device_activate_schedule_ip6_config_timeout (self); + return; + } + + priv->dhcp6_mode = dhcp_opts; + + /* If addrconf is all that's required, we're done */ + if (priv->dhcp6_mode == IP6_DHCP_OPT_NONE) { + priv->ac_ip6_config = nm_ip6_manager_get_ip6_config (ip6_manager, ifindex); + nm_device_activate_schedule_ip6_config_result (self, priv->ac_ip6_config); + return; + } + + /* If the router said to use DHCP for managed or otherconf, do it */ + + /* Don't re-start DHCPv6 if it's already in progress */ + if (priv->ip6_state != IP_CONF) + return; + + nm_log_info (LOGD_DEVICE | LOGD_DHCP6, + "Activation (%s) Stage 3 of 5 (IP Configure Start) starting DHCPv6" + " as requested by IPv6 router...", + priv->iface); + + ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason); + switch (ret) { + case NM_ACT_STAGE_RETURN_SUCCESS: + /* Shouldn't get this, but handle it anyway */ + g_warn_if_reached (); + priv->ac_ip6_config = nm_ip6_manager_get_ip6_config (ip6_manager, ifindex); + nm_device_activate_schedule_ip6_config_result (self, priv->ac_ip6_config); + break; + case NM_ACT_STAGE_RETURN_POSTPONE: + /* Cache acquired autoconf config and wait for DHCPv6 to complete */ + priv->ac_ip6_config = nm_ip6_manager_get_ip6_config (ip6_manager, ifindex); + break; + default: + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + break; + } +} + +static void +ip6_config_changed (NMIP6Manager *ip6_manager, + int ifindex, + guint dhcp_opts, + gboolean success, + gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + + if (ifindex != nm_device_get_ip_ifindex (self)) + return; + g_return_if_fail (priv->act_request != NULL); + + /* If autoconf failed and IPv6 previously succeeded, fail */ + if (!success && (priv->ip6_state == IP_DONE)) { + nm_device_state_changed (self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + /* FIXME: re-run DHCPv6 here to get any new nameservers or whatever */ + + if (priv->ac_ip6_config) + g_object_unref (priv->ac_ip6_config); + priv->ac_ip6_config = nm_ip6_manager_get_ip6_config (ip6_manager, ifindex); + + if (ip6_config_merge_and_apply (self, NULL, &reason) == FALSE) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to Router Advertisement.", + nm_device_get_ip_iface (self)); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + } +} + +static gboolean +addrconf6_start (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + gboolean success; + + connection = nm_device_get_connection (self); + g_assert (connection); + + g_warn_if_fail (priv->ac_ip6_config == NULL); + if (priv->ac_ip6_config) { + g_object_unref (priv->ac_ip6_config); + priv->ac_ip6_config = NULL; + } + + if (!priv->ip6_manager) { + priv->ip6_manager = nm_ip6_manager_get (); + priv->ip6_addrconf_sigid = g_signal_connect (priv->ip6_manager, + "addrconf-complete", + G_CALLBACK (ip6_addrconf_complete), + self); + priv->ip6_config_changed_sigid = g_signal_connect (priv->ip6_manager, + "config-changed", + G_CALLBACK (ip6_config_changed), + self); + } + + success = nm_ip6_manager_prepare_interface (priv->ip6_manager, + nm_device_get_ip_ifindex (self), + nm_connection_get_setting_ip6_config (connection), + priv->ip6_accept_ra_path); + if (success) { + priv->ip6_waiting_for_config = TRUE; + nm_ip6_manager_begin_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self)); + } + + return success; +} + +static void +addrconf6_cleanup (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->ac_ip6_config) { + g_object_unref (priv->ac_ip6_config); + priv->ac_ip6_config = NULL; + } + + if (!priv->ip6_manager) + return; + + if (priv->ip6_addrconf_sigid) { + g_signal_handler_disconnect (priv->ip6_manager, + priv->ip6_addrconf_sigid); + priv->ip6_addrconf_sigid = 0; + } + if (priv->ip6_config_changed_sigid) { + g_signal_handler_disconnect (priv->ip6_manager, + priv->ip6_config_changed_sigid); + priv->ip6_config_changed_sigid = 0; + } + + nm_ip6_manager_cancel_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self)); + g_object_unref (priv->ip6_manager); + priv->ip6_manager = NULL; +} + +/******************************************/ + static NMActStageReturn -real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason) +real_act_stage3_ip6_config_start (NMDevice *self, + NMIP6Config **out_config, + NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *ip_iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - NMActRequest *req; NMConnection *connection; + NMSettingIP6Config *s_ip6; + int conf_use_tempaddr; + NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + const char *ip6_privacy_str = "0\n"; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (self); g_assert (connection); ip_iface = nm_device_get_ip_iface (self); update_accept_ra_save (self); + update_ip6_privacy_save (self); priv->dhcp6_mode = IP6_DHCP_OPT_NONE; if ( ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { - if (!addrconf6_setup (self)) { + if (!addrconf6_start (self)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - goto out; - } - nm_ip6_manager_begin_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self)); - ret = NM_ACT_STAGE_RETURN_POSTPONE; + ret = NM_ACT_STAGE_RETURN_FAILURE; + } else + ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { /* Router advertisements shouldn't be used in pure DHCP mode */ if (priv->ip6_accept_ra_path) @@ -1765,19 +2177,52 @@ real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason) nm_utils_do_sysctl (priv->ip6_accept_ra_path, priv->ip6_accept_ra_save ? "1\n" : "0\n"); } - - priv->ip6_ready = TRUE; ret = NM_ACT_STAGE_RETURN_STOP; } else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + /* New blank config */ + *out_config = nm_ip6_config_new (); + g_assert (*out_config); + /* Router advertisements shouldn't be used in manual mode */ if (priv->ip6_accept_ra_path) nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n"); ret = NM_ACT_STAGE_RETURN_SUCCESS; + } else { + nm_log_warn (LOGD_IP6, "(%s): unhandled IPv6 config method; will fail", + nm_device_get_ip_iface (self)); } /* Other methods (shared) aren't implemented yet */ -out: + /* Enable/disable IPv6 Privacy Extensions. + * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf), + * use that value instead of per-connection value. + */ + conf_use_tempaddr = nm_backend_ipv6_use_tempaddr (); + if (conf_use_tempaddr >= 0) + ip6_privacy = conf_use_tempaddr; + else { + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) + ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6); + } + ip6_privacy = CLAMP (ip6_privacy, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + + switch (ip6_privacy) { + case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + ip6_privacy_str = "0\n"; + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + ip6_privacy_str = "1\n"; + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + ip6_privacy_str = "2\n"; + break; + } + if (priv->ip6_privacy_tempaddr_path) + nm_utils_do_sysctl (priv->ip6_privacy_tempaddr_path, ip6_privacy_str); + return ret; } @@ -1792,9 +2237,13 @@ static gboolean nm_device_activate_stage3_ip_config_start (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *iface; NMActStageReturn ret; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMIP4Config *ip4_config = NULL; + NMIP6Config *ip6_config = NULL; + int ifindex; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); @@ -1803,271 +2252,119 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); - ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) - nm_device_activate_schedule_stage4_ip4_config_get (self); - else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + /* Make sure the interface is up before trying to do anything with it */ + ifindex = nm_device_get_ip_ifindex (self); + if ((ifindex > 0) && (nm_system_iface_is_up (ifindex) == FALSE)) + nm_system_iface_set_up (ifindex, TRUE, NULL); + + priv->ip4_state = priv->ip6_state = IP_CONF; + + ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &ip4_config, &reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + g_assert (ip4_config); + nm_device_activate_schedule_ip4_config_result (self, ip4_config); + g_object_unref (ip4_config); + } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); goto out; } else if (ret == NM_ACT_STAGE_RETURN_STOP) { /* Nothing to do */ + priv->ip4_state = IP_DONE; } else g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE); - ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) - nm_device_activate_schedule_stage4_ip6_config_get (self); - else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &ip6_config, &reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + g_assert (ip6_config); + nm_device_activate_schedule_ip6_config_result (self, ip6_config); + g_object_unref (ip6_config); + } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); goto out; } else if (ret == NM_ACT_STAGE_RETURN_STOP) { /* Nothing to do */ + priv->ip6_state = IP_DONE; } else g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE); out: nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) complete.", iface); - return FALSE; -} - -/* - * nm_device_activate_schedule_stage3_ip_config_start - * - * Schedule IP configuration start - */ -void -nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) -{ - NMDevicePrivate *priv; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - g_return_if_fail (priv->act_request); - - activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); - - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) scheduled.", - nm_device_get_iface (self)); -} - -static GHashTable *shared_ips = NULL; - -static void -release_shared_ip (gpointer data) -{ - g_hash_table_remove (shared_ips, data); -} - -static guint32 -reserve_shared_ip (void) -{ - guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */ - guint32 count = 0; - - while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) { - count += ntohl (0x100); - if (count > ntohl (0xFE00)) { - nm_log_err (LOGD_SHARING, "ran out of shared IP addresses!"); - return 0; - } - } - - g_hash_table_insert (shared_ips, GUINT_TO_POINTER (start + count), GUINT_TO_POINTER (TRUE)); - return start + count; -} - -static NMIP4Config * -nm_device_new_ip4_shared_config (NMDevice *self, NMDeviceStateReason *reason) -{ - NMIP4Config *config = NULL; - NMIP4Address *addr; - guint32 tmp_addr; - - g_return_val_if_fail (self != NULL, NULL); - - if (G_UNLIKELY (shared_ips == NULL)) - shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal); - - tmp_addr = reserve_shared_ip (); - if (!tmp_addr) { - *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - return NULL; + /* Handle interfaces (bond slaves, etc) that won't have any IP config; they + * need to move to ACTIVATED. + */ + if (priv->ip4_state == IP_DONE && priv->ip6_state == IP_DONE) { + /* FIXME: call layer2 stuff to set MTU? */ + nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); } - config = nm_ip4_config_new (); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, tmp_addr); - nm_ip4_address_set_prefix (addr, 24); - nm_ip4_config_take_address (config, addr); - - /* Remove the address lock when the object gets disposed */ - g_object_set_data_full (G_OBJECT (config), "shared-ip", - GUINT_TO_POINTER (tmp_addr), release_shared_ip); - - return config; + return FALSE; } -static NMActStageReturn -real_act_stage4_get_ip4_config (NMDevice *self, - NMIP4Config **config, - NMDeviceStateReason *reason) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - NMConnection *connection; - NMSettingIP4Config *s_ip4; - const char *ip_iface; - - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - /* Use the IP interface (not the control interface) for IP stuff */ - ip_iface = nm_device_get_ip_iface (self); - - connection = nm_act_request_get_connection (nm_device_get_act_request (self)); - g_assert (connection); - - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (priv->dhcp4_client) { - /* DHCP */ - *config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); - if (*config) { - /* Merge user-defined overrides into the IP4Config to be applied */ - nm_utils_merge_ip4_config (*config, s_ip4); - - nm_dhcp4_config_reset (priv->dhcp4_config); - nm_dhcp_client_foreach_option (priv->dhcp4_client, - dhcp4_add_option_cb, - priv->dhcp4_config); - - /* Notify of new DHCP4 config */ - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); - } else - *reason = NM_DEVICE_STATE_REASON_DHCP_ERROR; - } else { - /* Not DHCP */ - const char *method; - - g_assert (s_ip4); - - method = nm_setting_ip4_config_get_method (s_ip4); - g_assert (method); - - if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { - *config = aipd_get_ip4_config (self, reason); - } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - *config = nm_ip4_config_new (); - if (*config) { - /* Merge user-defined overrides into the IP4Config to be applied */ - nm_utils_merge_ip4_config (*config, s_ip4); - } else - *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - *config = nm_device_new_ip4_shared_config (self, reason); - if (*config) - priv->dnsmasq_manager = nm_dnsmasq_manager_new (ip_iface); - } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - ret = NM_ACT_STAGE_RETURN_SUCCESS; - } - - if (!*config) { - /* Make sure device is up even if config fails */ - nm_device_bring_up (self, FALSE, NULL); - } else - ret = NM_ACT_STAGE_RETURN_SUCCESS; - - return ret; -} - -/* - * nm_device_activate_stage4_ip4_config_get - * - * Retrieve the correct IPv4 config. - * - */ -static gboolean -nm_device_activate_stage4_ip4_config_get (gpointer user_data) +static void +fw_add_to_zone_cb (GError *error, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); - NMIP4Config *ip4_config = NULL; - NMActStageReturn ret; - const char *iface = NULL; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - /* Clear the activation source ID now that this stage has run */ - activation_source_clear (self, FALSE, AF_INET); + priv->fw_call = NULL; - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Get) started...", - iface); - - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, &ip4_config, &reason); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - goto out; - else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - goto out; + if (error) { + /* FIXME: fail the device activation? */ } - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - - g_object_set_data (G_OBJECT (nm_device_get_act_request (self)), - NM_ACT_REQUEST_IP4_CONFIG, ip4_config); - nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET); + activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); -out: - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Get) complete.", - iface); - return FALSE; + nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) scheduled.", + nm_device_get_iface (self)); } - /* - * nm_device_activate_schedule_stage4_ip4_config_get - * - * Schedule creation of the IPv4 config + * nm_device_activate_schedule_stage3_ip_config_start * + * Schedule IP configuration start */ void -nm_device_activate_schedule_stage4_ip4_config_get (NMDevice *self) +nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) { NMDevicePrivate *priv; + NMConnection *connection; + NMSettingConnection *s_con = NULL; + NMDeviceState state; + const char *zone; g_return_if_fail (NM_IS_DEVICE (self)); priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); - activation_source_schedule (self, nm_device_activate_stage4_ip4_config_get, AF_INET); + state = nm_device_get_state (self); + g_warn_if_fail (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_NEED_AUTH); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Get) scheduled...", - nm_device_get_iface (self)); -} + /* Add the interface to the specified firewall zone */ + connection = nm_device_get_connection (self); + g_assert (connection); + s_con = nm_connection_get_setting_connection (connection); + zone = nm_setting_connection_get_zone (s_con); + nm_log_dbg (LOGD_DEVICE, "Activation (%s) setting firewall zone '%s'", + nm_device_get_iface (self), zone ? zone : "default"); + priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_manager, + nm_device_get_ip_iface (self), + zone, + TRUE, + fw_add_to_zone_cb, + self); +} static NMActStageReturn -real_act_stage4_ip4_config_timeout (NMDevice *self, - NMIP4Config **config, - NMDeviceStateReason *reason) +real_act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - - /* Notify of invalid DHCP4 config object */ - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); - if (nm_device_ip_config_should_fail (self, FALSE)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } - return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -2079,10 +2376,10 @@ real_act_stage4_ip4_config_timeout (NMDevice *self, * */ static gboolean -nm_device_activate_stage4_ip4_config_timeout (gpointer user_data) +nm_device_activate_ip4_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); - NMIP4Config *ip4_config = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; @@ -2092,10 +2389,10 @@ nm_device_activate_stage4_ip4_config_timeout (gpointer user_data) iface = nm_device_get_iface (self); nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Timeout) started...", + "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) started...", iface); - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &ip4_config, &reason); + ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) goto out; else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { @@ -2104,29 +2401,31 @@ nm_device_activate_stage4_ip4_config_timeout (gpointer user_data) } g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - if (ip4_config) { - g_object_set_data (G_OBJECT (nm_device_get_act_request (self)), - NM_ACT_REQUEST_IP4_CONFIG, ip4_config); - } + priv->ip4_state = IP_DONE; - nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET); + /* If IPv4 failed and IPv6 failed, the activation fails */ + if ((priv->ip6_state == IP_DONE) && (priv->ip6_config == NULL)) { + nm_device_state_changed (self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } out: nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Timeout) complete.", + "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) complete.", iface); return FALSE; } /* - * nm_device_activate_schedule_stage4_ip4_config_timeout + * nm_device_activate_schedule_ip4_config_timeout * * Deal with a timeout of the IPv4 configuration * */ void -nm_device_activate_schedule_stage4_ip4_config_timeout (NMDevice *self) +nm_device_activate_schedule_ip4_config_timeout (NMDevice *self) { NMDevicePrivate *priv; @@ -2135,214 +2434,17 @@ nm_device_activate_schedule_stage4_ip4_config_timeout (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); - activation_source_schedule (self, nm_device_activate_stage4_ip4_config_timeout, AF_INET); + activation_source_schedule (self, nm_device_activate_ip4_config_timeout, AF_INET); nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IP4 Configure Timeout) scheduled...", + "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) scheduled...", nm_device_get_iface (self)); } -static void -merge_dhcp_config_to_master (NMIP6Config *dst, NMIP6Config *src) -{ - guint32 i; - - g_return_if_fail (src != NULL); - g_return_if_fail (dst != NULL); - - /* addresses */ - for (i = 0; i < nm_ip6_config_get_num_addresses (src); i++) - nm_ip6_config_add_address (dst, nm_ip6_config_get_address (src, i)); - - /* ptp address; only replace if src doesn't have one */ - if (!nm_ip6_config_get_ptp_address (dst)) - nm_ip6_config_set_ptp_address (dst, nm_ip6_config_get_ptp_address (src)); - - /* nameservers */ - for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++) - nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i)); - - /* routes */ - for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) - nm_ip6_config_add_route (dst, nm_ip6_config_get_route (src, i)); - - /* domains */ - for (i = 0; i < nm_ip6_config_get_num_domains (src); i++) - nm_ip6_config_add_domain (dst, nm_ip6_config_get_domain (src, i)); - - /* dns searches */ - for (i = 0; i < nm_ip6_config_get_num_searches (src); i++) - nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i)); - - if (!nm_ip6_config_get_mss (dst)) - nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src)); -} static NMActStageReturn -real_act_stage4_get_ip6_config (NMDevice *self, - NMIP6Config **config, - NMDeviceStateReason *reason) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - NMSettingIP6Config *s_ip6; - const char *ip_iface; - - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - /* Use the IP interface (not the control interface) for IP stuff */ - ip_iface = nm_device_get_ip_iface (self); - - connection = nm_act_request_get_connection (nm_device_get_act_request (self)); - g_assert (connection); - - if ( ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO) - || ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { - *config = nm_ip6_manager_get_ip6_config (priv->ip6_manager, - nm_device_get_ip_ifindex (self)); - if (!*config) { - *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - goto out; - } - } else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - *config = nm_ip6_config_new (); - if (!*config) { - *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; - goto out; - } - } else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) - g_assert (priv->dhcp6_client); /* sanity check */ - - /* Autoconf might have triggered DHCPv6 too */ - if (priv->dhcp6_client) { - NMIP6Config *dhcp; - - dhcp = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); - if (!dhcp) { - *reason = NM_DEVICE_STATE_REASON_DHCP_ERROR; - goto out; - } - - /* For "managed" and DHCP-only setups, we use only the DHCP-supplied - * IPv6 config. But when autoconf is enabled, we have to merge the - * autoconf config and the DHCP-supplied config, then merge the - * user's overrides from the connection to get the final configuration - * that gets applied to the device. - */ - if (*config) { - /* Merge autoconf and DHCP configs */ - merge_dhcp_config_to_master (*config, dhcp); - g_object_unref (dhcp); - dhcp = NULL; - } else { - *config = dhcp; - } - - /* Copy the new DHCPv6 configuration into the DHCP config object that's - * exported over D-Bus to clients. - */ - nm_dhcp6_config_reset (priv->dhcp6_config); - nm_dhcp_client_foreach_option (priv->dhcp6_client, - dhcp6_add_option_cb, - priv->dhcp6_config); - - /* Notify of new DHCP6 config */ - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG); - } - - /* Merge user-defined overrides into the IP6Config to be applied */ - if (*config) { - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); - nm_utils_merge_ip6_config (*config, s_ip6); - } - -out: - return *config ? NM_ACT_STAGE_RETURN_SUCCESS : NM_ACT_STAGE_RETURN_FAILURE; -} - -/* - * nm_device_activate_stage4_ip6_config_get - * - * Retrieve the correct IPv6 config. - * - */ -static gboolean -nm_device_activate_stage4_ip6_config_get (gpointer user_data) +real_act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - NMDevice *self = NM_DEVICE (user_data); - NMIP6Config *ip6_config = NULL; - NMActStageReturn ret; - const char *iface = NULL; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - - /* Clear the activation source ID now that this stage has run */ - activation_source_clear (self, FALSE, AF_INET6); - - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Get) started...", - iface); - - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip6_config (self, &ip6_config, &reason); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - goto out; - else if (ret == NM_ACT_STAGE_RETURN_FAILURE) - { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - goto out; - } - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - - g_object_set_data (G_OBJECT (nm_device_get_act_request (self)), - NM_ACT_REQUEST_IP6_CONFIG, ip6_config); - - nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET6); - -out: - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Get) complete.", - iface); - return FALSE; -} - - -/* - * nm_device_activate_schedule_stage4_ip6_config_get - * - * Schedule creation of the IPv6 config - * - */ -void -nm_device_activate_schedule_stage4_ip6_config_get (NMDevice *self) -{ - NMDevicePrivate *priv; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - g_return_if_fail (priv->act_request); - - activation_source_schedule (self, nm_device_activate_stage4_ip6_config_get, AF_INET6); - - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Get) scheduled...", - nm_device_get_iface (self)); -} - - -static NMActStageReturn -real_act_stage4_ip6_config_timeout (NMDevice *self, - NMIP6Config **config, - NMDeviceStateReason *reason) -{ - g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); - - /* Notify of invalid DHCP4 config object */ - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG); - if (nm_device_ip_config_should_fail (self, TRUE)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; @@ -2353,16 +2455,16 @@ real_act_stage4_ip6_config_timeout (NMDevice *self, /* - * nm_device_activate_stage4_ip6_config_timeout + * nm_device_activate_ip6_config_timeout * * Time out on retrieving the IPv6 config. * */ static gboolean -nm_device_activate_stage4_ip6_config_timeout (gpointer user_data) +nm_device_activate_ip6_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); - NMIP6Config *ip6_config = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; @@ -2372,10 +2474,10 @@ nm_device_activate_stage4_ip6_config_timeout (gpointer user_data) iface = nm_device_get_iface (self); nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Timeout) started...", + "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) started...", iface); - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &ip6_config, &reason); + ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) goto out; else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { @@ -2384,29 +2486,31 @@ nm_device_activate_stage4_ip6_config_timeout (gpointer user_data) } g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - if (ip6_config) { - g_object_set_data (G_OBJECT (nm_device_get_act_request (self)), - NM_ACT_REQUEST_IP6_CONFIG, ip6_config); - } + priv->ip6_state = IP_DONE; - nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET6); + /* If IPv6 failed and IPv4 failed, the activation fails */ + if ((priv->ip4_state == IP_DONE) && (priv->ip4_config == NULL)) { + nm_device_state_changed (self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } out: nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Timeout) complete.", + "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) complete.", iface); return FALSE; } /* - * nm_device_activate_schedule_stage4_ip6_config_timeout + * nm_device_activate_schedule_ip6_config_timeout * * Deal with a timeout of the IPv6 configuration * */ void -nm_device_activate_schedule_stage4_ip6_config_timeout (NMDevice *self) +nm_device_activate_schedule_ip6_config_timeout (NMDevice *self) { NMDevicePrivate *priv; @@ -2415,10 +2519,10 @@ nm_device_activate_schedule_stage4_ip6_config_timeout (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); - activation_source_schedule (self, nm_device_activate_stage4_ip6_config_timeout, AF_INET6); + activation_source_schedule (self, nm_device_activate_ip6_config_timeout, AF_INET6); nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IP6 Configure Timeout) scheduled...", + "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) scheduled...", nm_device_get_iface (self)); } @@ -2483,7 +2587,7 @@ add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...) } static gboolean -start_sharing (NMDevice *self) +start_sharing (NMDevice *self, NMIP4Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActRequest *req; @@ -2491,17 +2595,14 @@ start_sharing (NMDevice *self) char str_addr[INET_ADDRSTRLEN + 1]; char str_mask[INET_ADDRSTRLEN + 1]; guint32 netmask, network; - NMIP4Config *ip4_config; NMIP4Address *ip4_addr; const char *ip_iface; - ip_iface = nm_device_get_ip_iface (self); + g_return_val_if_fail (config != NULL, FALSE); - ip4_config = nm_device_get_ip4_config (self); - if (!ip4_config) - return FALSE; + ip_iface = nm_device_get_ip_iface (self); - ip4_addr = nm_ip4_config_get_address (ip4_config, 0); + ip4_addr = nm_ip4_config_get_address (config, 0); if (!ip4_addr || !nm_ip4_address_get_address (ip4_addr)) return FALSE; @@ -2532,7 +2633,7 @@ start_sharing (NMDevice *self) nm_act_request_set_shared (req, TRUE); - if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) { + if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) { nm_log_err (LOGD_SHARING, "(%s/%s): failed to start dnsmasq: %s", nm_device_get_iface (self), ip_iface, error->message); g_error_free (error); @@ -2546,114 +2647,86 @@ start_sharing (NMDevice *self) return TRUE; } -/* - * nm_device_activate_stage5_ip_config_commit - * - * Commit the IP config on the device - * - */ static gboolean -nm_device_activate_stage5_ip_config_commit (gpointer user_data) +nm_device_activate_ip4_config_commit (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *act_request; - NMIP4Config *ip4_config = NULL; - NMIP6Config *ip6_config = NULL; + NMActRequest *req; + NMIP4Config *config = NULL; const char *iface, *method = NULL; NMConnection *connection; NMSettingIP4Config *s_ip4; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; gboolean assumed; - - /* Get the new IP4 and IP6 configs; since this stage gets rerun - * when automatic configuration changes (DHCP lease renewal, new - * IPv6 router advertisement, etc), it's possible that only one of - * them will be set. - */ - act_request = nm_device_get_act_request (self); - - ip4_config = g_object_get_data (G_OBJECT (act_request), - NM_ACT_REQUEST_IP4_CONFIG); - g_object_set_data (G_OBJECT (act_request), - NM_ACT_REQUEST_IP4_CONFIG, NULL); - - ip6_config = g_object_get_data (G_OBJECT (act_request), - NM_ACT_REQUEST_IP6_CONFIG); - g_object_set_data (G_OBJECT (act_request), - NM_ACT_REQUEST_IP6_CONFIG, NULL); + int ifindex; /* Clear the activation source ID now that this stage has run */ - activation_source_clear (self, FALSE, 0); + activation_source_clear (self, FALSE, AF_INET); iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IP Configure Commit) started...", + nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) started...", iface); - assumed = nm_act_request_get_assumed (priv->act_request); + req = nm_device_get_act_request (self); + g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); - if (!ip6_config && !ip4_config) { - nm_log_info (LOGD_DEVICE, - "Activation (%s) Stage 5 of 5 (IP Configure Commit) failed (no IP configuration found)", - iface); - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - goto out; - } + config = g_object_get_data (G_OBJECT (req), PENDING_IP4_CONFIG); + g_assert (config); - if (ip4_config && !nm_device_set_ip4_config (self, ip4_config, assumed, &reason)) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); - goto out; - } + /* Make sure the interface is up again just because */ + ifindex = nm_device_get_ip_ifindex (self); + if ((ifindex > 0) && (nm_system_iface_is_up (ifindex) == FALSE)) + nm_system_iface_set_up (ifindex, TRUE, NULL); - if (ip6_config && !nm_device_set_ip6_config (self, ip6_config, assumed, &reason)) { - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 5 of 5 (IP Configure Commit) IPv6 failed", - iface); + /* Allow setting MTU etc */ + if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) + NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, config); + + /* Merge with user overrides */ + nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection)); + + assumed = nm_act_request_get_assumed (priv->act_request); + if (!nm_device_set_ip4_config (self, config, assumed, &reason)) { + nm_log_info (LOGD_DEVICE | LOGD_IP4, + "Activation (%s) Stage 5 of 5 (IPv4 Commit) failed", + iface); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); goto out; } - connection = nm_act_request_get_connection (nm_device_get_act_request (self)); - - if (ip4_config) { - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (s_ip4) - method = nm_setting_ip4_config_get_method (s_ip4); + /* Start IPv4 sharing if we need it */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4) + method = nm_setting_ip4_config_get_method (s_ip4); - if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - if (!start_sharing (self)) { - nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IP Configure Commit) start sharing failed.", iface); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); - goto out; - } + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { + if (!start_sharing (self, config)) { + nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IPv4 Commit) start sharing failed.", iface); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + goto out; } } - nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); + /* Enter the ACTIVATED state if this is the first method to complete */ + priv->ip4_state = IP_DONE; + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IP Configure Commit) complete.", + nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) complete.", iface); - /* Balance IP config creation; device takes ownership in set_ip*_config() */ - if (ip4_config) - g_object_unref (ip4_config); - if (ip6_config) - g_object_unref (ip6_config); + /* Balance IP config creation; nm_device_set_ip4_config() takes a reference */ + g_object_set_data (G_OBJECT (req), PENDING_IP4_CONFIG, NULL); return FALSE; } - -/* - * nm_device_activate_schedule_stage5_ip_config_commit - * - * Schedule commit of the IP config - */ -static void -nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self, int family) +void +nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config) { NMDevicePrivate *priv; @@ -2662,26 +2735,121 @@ nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self, int family) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); - if (family == AF_INET) - priv->ip4_ready = TRUE; - else if (family == AF_INET6) - priv->ip6_ready = TRUE; + if (config == NULL) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } - /* Note that these are only set FALSE at stage3, so once you've - * made it all the way through activation once, you can jump back - * into stage4 (eg, for a DHCP lease change) and not worry about - * needing both IPv4 and IPv6 to complete. - */ - if (!priv->ip4_ready || !priv->ip6_ready) + g_object_set_data_full (G_OBJECT (priv->act_request), + PENDING_IP4_CONFIG, + g_object_ref (config), + g_object_unref); + + activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET); + + nm_log_info (LOGD_DEVICE | LOGD_IP4, + "Activation (%s) Stage 5 of 5 (IPv4 Configure Commit) scheduled...", + nm_device_get_iface (self)); +} + +gboolean +nm_device_activate_ip4_state_in_conf (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_CONF; +} + +static gboolean +nm_device_activate_ip6_config_commit (gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMActRequest *req; + NMIP6Config *config = NULL; + const char *iface; + NMConnection *connection; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + int ifindex; + + /* Clear the activation source ID now that this stage has run */ + activation_source_clear (self, FALSE, AF_INET6); + + iface = nm_device_get_iface (self); + nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv6 Commit) started...", + iface); + + req = nm_device_get_act_request (self); + g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + + config = g_object_get_data (G_OBJECT (req), PENDING_IP6_CONFIG); + g_assert (config); + + /* Make sure the interface is up again just because */ + ifindex = nm_device_get_ip_ifindex (self); + if ((ifindex > 0) && (nm_system_iface_is_up (ifindex) == FALSE)) + nm_system_iface_set_up (ifindex, TRUE, NULL); + + /* Allow setting MTU etc */ + if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) + NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, config); + + if (ip6_config_merge_and_apply (self, config, &reason)) { + /* Enter the ACTIVATED state if this is the first method to complete */ + priv->ip6_state = IP_DONE; + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); + } else { + nm_log_info (LOGD_DEVICE | LOGD_IP6, + "Activation (%s) Stage 5 of 5 (IPv6 Commit) failed", + iface); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + } + + nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv6 Commit) complete.", + iface); + + /* Balance IP config creation; nm_device_set_ip6_config() takes a reference */ + g_object_set_data (G_OBJECT (req), PENDING_IP6_CONFIG, NULL); + + return FALSE; +} + +void +nm_device_activate_schedule_ip6_config_result (NMDevice *self, NMIP6Config *config) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + g_return_if_fail (priv->act_request); + + if (config == NULL) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); return; + } - activation_source_schedule (self, nm_device_activate_stage5_ip_config_commit, 0); + /* Save the pending config */ + g_object_set_data_full (G_OBJECT (priv->act_request), + PENDING_IP6_CONFIG, + g_object_ref (config), + g_object_unref); - nm_log_info (LOGD_DEVICE, - "Activation (%s) Stage 5 of 5 (IP Configure Commit) scheduled...", - nm_device_get_iface (self)); + activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6); + + nm_log_info (LOGD_DEVICE | LOGD_IP4, + "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...", + nm_device_get_iface (self)); } +gboolean +nm_device_activate_ip6_state_in_conf (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_CONF; +} static void clear_act_request (NMDevice *self) @@ -2707,29 +2875,23 @@ clear_act_request (NMDevice *self) priv->secrets_failed_id = 0; } - nm_act_request_set_default (priv->act_request, FALSE); + nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE); g_object_unref (priv->act_request); priv->act_request = NULL; } static void -delayed_transitions_clear (NMDevice *self) +queued_state_clear (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->failed_to_disconnected_id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing failed->disconnected transition", - nm_device_get_iface (self)); - g_source_remove (priv->failed_to_disconnected_id); - priv->failed_to_disconnected_id = 0; - } - if (priv->unavailable_to_disconnected_id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing unavailable->disconnected transition", - nm_device_get_iface (self)); - g_source_remove (priv->unavailable_to_disconnected_id); - priv->unavailable_to_disconnected_id = 0; + if (priv->queued_state.id) { + nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued state transition (id %d)", + nm_device_get_iface (self), priv->queued_state.id); + g_source_remove (priv->queued_state.id); } + memset (&priv->queued_state, 0, sizeof (priv->queued_state)); } static void @@ -2738,7 +2900,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->dhcp4_config) { - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG); g_object_unref (priv->dhcp4_config); priv->dhcp4_config = NULL; } @@ -2770,8 +2932,13 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) priv->dhcp6_mode = IP6_DHCP_OPT_NONE; + if (priv->dhcp6_ip6_config) { + g_object_unref (priv->dhcp6_ip6_config); + priv->dhcp6_ip6_config = NULL; + } + if (priv->dhcp6_config) { - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); g_object_unref (priv->dhcp6_config); priv->dhcp6_config = NULL; } @@ -2813,6 +2980,32 @@ dnsmasq_cleanup (NMDevice *self) priv->dnsmasq_manager = NULL; } +static void +_update_ip4_address (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + struct ifreq req; + guint32 new_address; + int fd; + + g_return_if_fail (self != NULL); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_err (LOGD_IP4, "couldn't open control socket."); + return; + } + + memset (&req, 0, sizeof (struct ifreq)); + strncpy (req.ifr_name, nm_device_get_ip_iface (self), IFNAMSIZ); + if (ioctl (fd, SIOCGIFADDR, &req) == 0) { + new_address = ((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr; + if (new_address != priv->ip4_address) + priv->ip4_address = new_address; + } + close (fd); +} + /* * nm_device_deactivate * @@ -2820,29 +3013,58 @@ dnsmasq_cleanup (NMDevice *self) * */ static void -nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) +nm_device_deactivate (NMDevice *self, NMDeviceStateReason reason) { - NMDevice *self = NM_DEVICE (device); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE; + NMConnection *connection = NULL; + NMSettingConnection *s_con = NULL; gboolean tried_ipv6 = FALSE; int ifindex, family; g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason '%s') [%d]", nm_device_get_iface (self), reason_to_string (reason), reason); /* Save whether or not we tried IPv6 for later */ + priv = NM_DEVICE_GET_PRIVATE (self); if (priv->ip6_manager || priv->ip6_config) tried_ipv6 = TRUE; + /* Clean up when device was deactivated during call to firewall */ + if (priv->fw_call) { + nm_firewall_manager_cancel_call (priv->fw_manager, priv->fw_call); + priv->fw_call = NULL; + } + + if (priv->act_request) + connection = nm_act_request_get_connection (priv->act_request); + if (connection) { + s_con = nm_connection_get_setting_connection (connection); + nm_firewall_manager_remove_from_zone (priv->fw_manager, + nm_device_get_ip_iface (self), + nm_setting_connection_get_zone (s_con)); + } + /* Break the activation chain */ activation_source_clear (self, TRUE, AF_INET); activation_source_clear (self, TRUE, AF_INET6); - /* Clear any delayed transitions */ - delayed_transitions_clear (self); + if (priv->act_dep_result_id) { + g_source_remove (priv->act_dep_result_id); + priv->act_dep_result_id = 0; + } + if (priv->act_dep_timeout_id) { + g_source_remove (priv->act_dep_timeout_id); + priv->act_dep_timeout_id = 0; + } + + /* Clear any queued transitions */ + queued_state_clear (self); + + priv->ip4_state = priv->ip6_state = IP_NONE; dhcp4_cleanup (self, TRUE, FALSE); dhcp6_cleanup (self, TRUE, FALSE); @@ -2856,6 +3078,10 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) if (priv->ip6_accept_ra_path) nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n"); + /* Turn off IPv6 privacy extensions */ + if (priv->ip6_privacy_tempaddr_path) + nm_utils_do_sysctl (priv->ip6_privacy_tempaddr_path, "0\n"); + /* Call device type-specific deactivation */ if (NM_DEVICE_GET_CLASS (self)->deactivate) NM_DEVICE_GET_CLASS (self)->deactivate (self); @@ -2866,46 +3092,119 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) /* Take out any entries in the routing table and any IP address the device had. */ ifindex = nm_device_get_ip_ifindex (self); family = tried_ipv6 ? AF_UNSPEC : AF_INET; - nm_system_iface_flush_routes (ifindex, family); - nm_system_iface_flush_addresses (ifindex, family); - nm_device_update_ip4_address (self); + if (ifindex >= 0) { + nm_system_iface_flush_routes (ifindex, family); + nm_system_iface_flush_addresses (ifindex, family); + } + _update_ip4_address (self); /* Clean up nameservers and addresses */ nm_device_set_ip4_config (self, NULL, FALSE, &ignored); nm_device_set_ip6_config (self, NULL, FALSE, &ignored); } -static gboolean -device_disconnect (NMDeviceInterface *device, - GError **error) +gboolean +nm_device_disconnect (NMDevice *device, GError **error) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (NM_DEVICE (device)); + NMDevicePrivate *priv; + + g_return_val_if_fail (device != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, + "Cannot disconnect an inactive device."); + return FALSE; + } priv->autoconnect_inhibit = TRUE; - nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_USER_REQUESTED); + nm_device_state_changed (device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); return TRUE; } +static void +impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) +{ + g_signal_emit (device, signals[DISCONNECT_REQUEST], 0, context); +} + static gboolean -check_connection_compatible (NMDeviceInterface *dev_iface, - NMConnection *connection, - GError **error) +act_dep_timeout_cb (gpointer user_data) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (NM_DEVICE (dev_iface)); + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; - if (klass->check_connection_compatible) - return klass->check_connection_compatible (NM_DEVICE (dev_iface), connection, error); + connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->act_request)); + nm_log_warn (LOGD_DEVICE, + "Activation (%s) connection '%s' dependency timed out", + nm_device_get_iface (self), + nm_connection_get_id (connection)); - return TRUE; + nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + return FALSE; } -static gboolean -nm_device_activate (NMDeviceInterface *device, - NMActRequest *req, - GError **error) +static void +act_dep_result_cb (NMActRequest *req, + NMActRequestDependencyResult result, + NMDevice *self) { - NMDevice *self = NM_DEVICE (device); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + + connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->act_request)); + + switch (result) { + case NM_ACT_REQUEST_DEP_RESULT_FAILED: + g_source_remove (priv->act_dep_result_id); + priv->act_dep_result_id = 0; + + nm_log_warn (LOGD_DEVICE, + "Activation (%s) connection '%s' dependency failed", + nm_device_get_iface (self), + nm_connection_get_id (connection)); + nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + break; + case NM_ACT_REQUEST_DEP_RESULT_READY: + g_warn_if_fail (priv->state == NM_DEVICE_STATE_PREPARE); + if (priv->state == NM_DEVICE_STATE_PREPARE) { + nm_log_info (LOGD_DEVICE, + "Activation (%s) connection '%s' dependency ready, continuing activation", + nm_device_get_iface (self), + nm_connection_get_id (connection)); + nm_device_activate_schedule_stage1_device_prepare (self); + } + break; + case NM_ACT_REQUEST_DEP_RESULT_WAIT: + default: + g_assert_not_reached (); + break; + } +} + +gboolean +nm_device_activate (NMDevice *self, NMActRequest *req, GError **error) +{ + NMDevicePrivate *priv; + NMConnection *connection; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (req != NULL, FALSE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + + nm_log_info (LOGD_DEVICE, "Activation (%s) starting connection '%s'", + nm_device_get_iface (self), + nm_connection_get_id (connection)); /* Make sure this connection isn't activated already, or in the process of * being activated. @@ -2916,9 +3215,7 @@ nm_device_activate (NMDeviceInterface *device, NMConnection *current = nm_act_request_get_connection (priv->act_request); if (new == current) { - g_set_error_literal (error, - NM_DEVICE_INTERFACE_ERROR, - NM_DEVICE_INTERFACE_ERROR_CONNECTION_ACTIVATING, + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CONNECTION_ACTIVATING, "Connection is already activating"); return FALSE; } @@ -2927,13 +3224,44 @@ nm_device_activate (NMDeviceInterface *device, priv->act_request = g_object_ref (req); if (!nm_act_request_get_assumed (req)) { + NMActiveConnection *dep_ac; + NMConnection *dep_con; + /* HACK: update the state a bit early to avoid a race between the * scheduled stage1 handler and nm_policy_device_change_check() thinking * that the activation request isn't deferred because the deferred bit * gets cleared a bit too early, when the connection becomes valid. */ nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE); - nm_device_activate_schedule_stage1_device_prepare (self); + + /* Handle any dependencies this connection might have */ + switch (nm_act_request_get_dependency_result (priv->act_request)) { + case NM_ACT_REQUEST_DEP_RESULT_FAILED: + nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + break; + case NM_ACT_REQUEST_DEP_RESULT_WAIT: + dep_ac = nm_act_request_get_dependency (priv->act_request); + g_assert (dep_ac); + dep_con = nm_active_connection_get_connection (dep_ac); + g_assert (dep_con); + nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on dependency '%s'", + nm_device_get_iface (self), + nm_connection_get_id (connection), + nm_connection_get_id (dep_con)); + + priv->act_dep_result_id = g_signal_connect (priv->act_request, + NM_ACT_REQUEST_DEPENDENCY_RESULT, + G_CALLBACK (act_dep_result_cb), + self); + priv->act_dep_timeout_id = g_timeout_add_seconds (60, act_dep_timeout_cb, self); + break; + default: + g_warn_if_reached (); + /* fall through */ + case NM_ACT_REQUEST_DEP_RESULT_READY: + nm_device_activate_schedule_stage1_device_prepare (self); + break; + } } else { /* If it's an assumed connection, let the device subclass short-circuit * the normal connection process and just copy its IP configs from the @@ -3062,56 +3390,16 @@ nm_device_set_ip4_config (NMDevice *self, /* Add the DNS information to the DNS manager */ nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); - nm_device_update_ip4_address (self); + _update_ip4_address (self); } } g_object_unref (dns_mgr); - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_IP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG); return success; } -/* - * nm_device_get_ip4_address - * - * Get a device's IPv4 address - * - */ -guint32 -nm_device_get_ip4_address (NMDevice *self) -{ - g_return_val_if_fail (self != NULL, 0); - - return NM_DEVICE_GET_PRIVATE (self)->ip4_address; -} - - -void -nm_device_update_ip4_address (NMDevice *self) -{ - struct ifreq req; - guint32 new_address; - int fd; - - g_return_if_fail (self != NULL); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_err (LOGD_IP4, "couldn't open control socket."); - return; - } - - memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, nm_device_get_ip_iface (self), IFNAMSIZ); - if (ioctl (fd, SIOCGIFADDR, &req) == 0) { - new_address = ((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr; - if (new_address != nm_device_get_ip4_address (self)) - NM_DEVICE_GET_PRIVATE (self)->ip4_address = new_address; - } - close (fd); -} - static gboolean nm_device_set_ip6_config (NMDevice *self, NMIP6Config *new_config, @@ -3170,7 +3458,7 @@ nm_device_set_ip6_config (NMDevice *self, } g_object_unref (dns_mgr); - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_IP6_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG); return success; } @@ -3237,7 +3525,7 @@ out: if (NM_DEVICE_GET_CLASS (self)->update_hw_address) NM_DEVICE_GET_CLASS (self)->update_hw_address (self); - nm_device_update_ip4_address (self); + _update_ip4_address (self); return TRUE; } @@ -3288,7 +3576,7 @@ nm_device_take_down (NMDevice *self, gboolean block, NMDeviceStateReason reason) g_return_if_fail (NM_IS_DEVICE (self)); if (nm_device_get_act_request (self)) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (self), reason); + nm_device_deactivate (self, reason); if (nm_device_is_up (self)) { nm_log_info (LOGD_HW, "(%s): cleaning up...", nm_device_get_iface (self)); @@ -3315,20 +3603,19 @@ dispose (GObject *object) /* Don't down can-assume-connection capable devices that are activated with * a connection that can be assumed. */ - if ( nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (self)) - && (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED)) { + if (nm_device_can_assume_connections (self) && (priv->state == NM_DEVICE_STATE_ACTIVATED)) { NMConnection *connection; NMSettingIP4Config *s_ip4 = NULL; const char *method = NULL; - connection = nm_act_request_get_connection (priv->act_request); + connection = nm_device_get_connection (self); if (connection) { /* Only static or DHCP IPv4 connections can be left up. * All IPv6 connections can be left up, so we don't have * to check that. */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); if ( !method @@ -3338,8 +3625,8 @@ dispose (GObject *object) } } - /* Clear any delayed transitions */ - delayed_transitions_clear (self); + /* Clear any queued transitions */ + queued_state_clear (self); /* Clean up and stop DHCP */ dhcp4_cleanup (self, take_down, FALSE); @@ -3362,6 +3649,15 @@ dispose (GObject *object) } g_free (priv->ip6_accept_ra_path); + /* reset the saved use_tempaddr value */ + if (priv->ip6_privacy_tempaddr_path) { + char tmp[16]; + + snprintf (tmp, sizeof (tmp), "%d\n", priv->ip6_privacy_tempaddr_save); + nm_utils_do_sysctl (priv->ip6_privacy_tempaddr_path, tmp); + } + g_free (priv->ip6_privacy_tempaddr_path); + activation_source_clear (self, TRUE, AF_INET); activation_source_clear (self, TRUE, AF_INET6); @@ -3380,6 +3676,9 @@ finalize (GObject *object) if (priv->dhcp_manager) g_object_unref (priv->dhcp_manager); + if (priv->fw_manager) + g_object_unref (priv->fw_manager); + g_free (priv->udi); g_free (priv->iface); g_free (priv->ip_iface); @@ -3399,11 +3698,15 @@ set_property (GObject *object, guint prop_id, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); switch (prop_id) { - case NM_DEVICE_INTERFACE_PROP_UDI: - /* construct-only */ + case PROP_UDI: + /* Only virtual interfaces can set UDI post-construction */ + if (priv->initialized) + g_return_if_fail (nm_system_get_iface_type (priv->ifindex, NULL) != NM_IFACE_TYPE_UNSPEC); + + g_free (priv->udi); priv->udi = g_strdup (g_value_get_string (value)); break; - case NM_DEVICE_INTERFACE_PROP_IFACE: + case PROP_IFACE: g_free (priv->iface); priv->ifindex = 0; priv->iface = g_value_dup_string (value); @@ -3414,32 +3717,32 @@ set_property (GObject *object, guint prop_id, } } break; - case NM_DEVICE_INTERFACE_PROP_IP_IFACE: + case PROP_IP_IFACE: break; - case NM_DEVICE_INTERFACE_PROP_DRIVER: + case PROP_DRIVER: priv->driver = g_strdup (g_value_get_string (value)); break; - case NM_DEVICE_INTERFACE_PROP_CAPABILITIES: + case PROP_CAPABILITIES: priv->capabilities = g_value_get_uint (value); break; - case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS: + case PROP_IP4_ADDRESS: priv->ip4_address = g_value_get_uint (value); break; - case NM_DEVICE_INTERFACE_PROP_MANAGED: + case PROP_MANAGED: priv->managed = g_value_get_boolean (value); break; - case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING: + case PROP_FIRMWARE_MISSING: priv->firmware_missing = g_value_get_boolean (value); break; - case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: + case PROP_DEVICE_TYPE: g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN); priv->type = g_value_get_uint (value); break; - case NM_DEVICE_INTERFACE_PROP_TYPE_DESC: + case PROP_TYPE_DESC: g_free (priv->type_desc); priv->type_desc = g_value_dup_string (value); break; - case NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE: + case PROP_RFKILL_TYPE: priv->rfkill_type = g_value_get_uint (value); break; default: @@ -3466,75 +3769,83 @@ get_property (GObject *object, guint prop_id, state = nm_device_get_state (self); switch (prop_id) { - case NM_DEVICE_INTERFACE_PROP_UDI: + case PROP_UDI: g_value_set_string (value, priv->udi); break; - case NM_DEVICE_INTERFACE_PROP_IFACE: + case PROP_IFACE: g_value_set_string (value, priv->iface); break; - case NM_DEVICE_INTERFACE_PROP_IP_IFACE: + case PROP_IP_IFACE: if (_is_connected (state)) g_value_set_string (value, nm_device_get_ip_iface (self)); else g_value_set_string (value, NULL); break; - case NM_DEVICE_INTERFACE_PROP_IFINDEX: + case PROP_IFINDEX: g_value_set_int (value, priv->ifindex); break; - case NM_DEVICE_INTERFACE_PROP_DRIVER: + case PROP_DRIVER: g_value_set_string (value, priv->driver); break; - case NM_DEVICE_INTERFACE_PROP_CAPABILITIES: + case PROP_CAPABILITIES: g_value_set_uint (value, priv->capabilities); break; - case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS: + case PROP_IP4_ADDRESS: g_value_set_uint (value, priv->ip4_address); break; - case NM_DEVICE_INTERFACE_PROP_IP4_CONFIG: + case PROP_IP4_CONFIG: if (_is_connected (state) && priv->ip4_config) g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config)); else g_value_set_boxed (value, "/"); break; - case NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG: + case PROP_DHCP4_CONFIG: if (_is_connected (state) && priv->dhcp4_client) g_value_set_boxed (value, nm_dhcp4_config_get_dbus_path (priv->dhcp4_config)); else g_value_set_boxed (value, "/"); break; - case NM_DEVICE_INTERFACE_PROP_IP6_CONFIG: + case PROP_IP6_CONFIG: if (_is_connected (state) && priv->ip6_config) g_value_set_boxed (value, nm_ip6_config_get_dbus_path (priv->ip6_config)); else g_value_set_boxed (value, "/"); break; - case NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG: + case PROP_DHCP6_CONFIG: if (_is_connected (state) && priv->dhcp6_client) g_value_set_boxed (value, nm_dhcp6_config_get_dbus_path (priv->dhcp6_config)); else g_value_set_boxed (value, "/"); break; - case NM_DEVICE_INTERFACE_PROP_STATE: + case PROP_STATE: g_value_set_uint (value, priv->state); break; - case NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION: + case PROP_STATE_REASON: + g_value_set_boxed (value, + dbus_g_type_specialized_construct (DBUS_G_TYPE_UINT_STRUCT)); + dbus_g_type_struct_set (value, + 0, priv->state, + 1, priv->state_reason, + G_MAXUINT); + break; + case PROP_ACTIVE_CONNECTION: if (priv->act_request) - ac_path = nm_act_request_get_active_connection_path (priv->act_request); + ac_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (priv->act_request)); g_value_set_boxed (value, ac_path ? ac_path : "/"); break; - case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: + case PROP_DEVICE_TYPE: g_value_set_uint (value, priv->type); break; - case NM_DEVICE_INTERFACE_PROP_MANAGED: + case PROP_MANAGED: g_value_set_boolean (value, priv->managed); break; - case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING: + case PROP_FIRMWARE_MISSING: g_value_set_boolean (value, priv->firmware_missing); break; - case NM_DEVICE_INTERFACE_PROP_TYPE_DESC: + case PROP_TYPE_DESC: g_value_set_string (value, priv->type_desc); break; - case NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE: + case PROP_RFKILL_TYPE: g_value_set_uint (value, priv->rfkill_type); break; default: @@ -3557,6 +3868,7 @@ nm_device_class_init (NMDeviceClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; object_class->constructor = constructor; + object_class->constructed = constructed; klass->get_type_capabilities = real_get_type_capabilities; klass->get_generic_capabilities = real_get_generic_capabilities; @@ -3564,84 +3876,180 @@ nm_device_class_init (NMDeviceClass *klass) klass->act_stage2_config = real_act_stage2_config; klass->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; klass->act_stage3_ip6_config_start = real_act_stage3_ip6_config_start; - klass->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; - klass->act_stage4_get_ip6_config = real_act_stage4_get_ip6_config; klass->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout; klass->act_stage4_ip6_config_timeout = real_act_stage4_ip6_config_timeout; /* Properties */ - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_UDI, - NM_DEVICE_INTERFACE_UDI); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IFACE, - NM_DEVICE_INTERFACE_IFACE); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IP_IFACE, - NM_DEVICE_INTERFACE_IP_IFACE); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IFINDEX, - NM_DEVICE_INTERFACE_IFINDEX); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_DRIVER, - NM_DEVICE_INTERFACE_DRIVER); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_CAPABILITIES, - NM_DEVICE_INTERFACE_CAPABILITIES); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS, - NM_DEVICE_INTERFACE_IP4_ADDRESS); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, - NM_DEVICE_INTERFACE_IP4_CONFIG); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG, - NM_DEVICE_INTERFACE_DHCP4_CONFIG); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_IP6_CONFIG, - NM_DEVICE_INTERFACE_IP6_CONFIG); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG, - NM_DEVICE_INTERFACE_DHCP6_CONFIG); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_STATE, - NM_DEVICE_INTERFACE_STATE); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION, - NM_DEVICE_INTERFACE_ACTIVE_CONNECTION); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, - NM_DEVICE_INTERFACE_DEVICE_TYPE); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_MANAGED, - NM_DEVICE_INTERFACE_MANAGED); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING, - NM_DEVICE_INTERFACE_FIRMWARE_MISSING); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_TYPE_DESC, - NM_DEVICE_INTERFACE_TYPE_DESC); - - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE, - NM_DEVICE_INTERFACE_RFKILL_TYPE); + g_object_class_install_property + (object_class, PROP_UDI, + g_param_spec_string (NM_DEVICE_UDI, + "UDI", + "Unique Device Identifier", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property + (object_class, PROP_IFACE, + g_param_spec_string (NM_DEVICE_IFACE, + "Interface", + "Interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_IP_IFACE, + g_param_spec_string (NM_DEVICE_IP_IFACE, + "IP Interface", + "IP Interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_DRIVER, + g_param_spec_string (NM_DEVICE_DRIVER, + "Driver", + "Driver", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_CAPABILITIES, + "Capabilities", + "Capabilities", + 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_IP4_ADDRESS, + g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, + "IP4 address", + "IP4 address", + 0, G_MAXUINT32, 0, /* FIXME */ + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, + "IP4 Config", + "IP4 Config", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_DHCP4_CONFIG, + g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, + "DHCP4 Config", + "DHCP4 Config", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_IP6_CONFIG, + g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, + "IP6 Config", + "IP6 Config", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_DHCP6_CONFIG, + g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, + "DHCP6 Config", + "DHCP6 Config", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_DEVICE_STATE, + "State", + "State", + 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_STATE_REASON, + g_param_spec_boxed (NM_DEVICE_STATE_REASON, + "StateReason", + "StateReason", + DBUS_G_TYPE_UINT_STRUCT, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTION, + g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, + "ActiveConnection", + "ActiveConnection", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_DEVICE_TYPE, + g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, + "DeviceType", + "DeviceType", + 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); + + g_object_class_install_property + (object_class, PROP_MANAGED, + g_param_spec_boolean (NM_DEVICE_MANAGED, + "Managed", + "Managed", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_FIRMWARE_MISSING, + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, + "FirmwareMissing", + "Firmware missing", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_TYPE_DESC, + g_param_spec_string (NM_DEVICE_TYPE_DESC, + "Type Description", + "Device type description", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); + + g_object_class_install_property + (object_class, PROP_RFKILL_TYPE, + g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, + "Rfkill Type", + "Type of rfkill switch (if any) supported by this device", + RFKILL_TYPE_WLAN, + RFKILL_TYPE_MAX, + RFKILL_TYPE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); + + g_object_class_install_property + (object_class, PROP_IFINDEX, + g_param_spec_int (NM_DEVICE_IFINDEX, + "Ifindex", + "Ifindex", + 0, G_MAXINT, 0, + G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT)); + + /* Signals */ + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + _nm_marshal_VOID__UINT_UINT_UINT, + G_TYPE_NONE, 3, + G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + + signals[DISCONNECT_REQUEST] = + g_signal_new (NM_DEVICE_DISCONNECT_REQUEST, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); signals[AUTOCONNECT_ALLOWED] = g_signal_new ("autoconnect-allowed", @@ -3651,32 +4059,11 @@ nm_device_class_init (NMDeviceClass *klass) autoconnect_allowed_accumulator, NULL, _nm_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0); -} - -static gboolean -failed_to_disconnected (gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - nm_log_dbg (LOGD_DEVICE, "(%s): running failed->disconnected transition", - nm_device_get_iface (self)); - priv->failed_to_disconnected_id = 0; - nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); - return FALSE; -} -static gboolean -unavailable_to_disconnected (gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_interface_object_info); - nm_log_dbg (LOGD_DEVICE, "(%s): running unavailable->disconnected transition", - nm_device_get_iface (self)); - priv->unavailable_to_disconnected_id = 0; - nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); - return FALSE; + dbus_g_error_domain_register (NM_DEVICE_ERROR, NULL, NM_TYPE_DEVICE_ERROR); } void @@ -3690,7 +4077,7 @@ nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing) priv = NM_DEVICE_GET_PRIVATE (self); if (priv->firmware_missing != new_missing) { priv->firmware_missing = new_missing; - g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_FIRMWARE_MISSING); + g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_MISSING); } } @@ -3826,6 +4213,18 @@ reason_to_string (NMDeviceStateReason reason) return "modem-not-found"; case NM_DEVICE_STATE_REASON_BT_FAILED: return "bluetooth-failed"; + case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: + return "gsm-sim-not-inserted"; + case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: + return "gsm-sim-pin-required"; + case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: + return "gsm-sim-puk-required"; + case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: + return "gsm-sim-wrong"; + case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: + return "infiniband-mode"; + case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: + return "dependency-failed"; default: break; } @@ -3854,6 +4253,7 @@ nm_device_state_changed (NMDevice *device, old_state = priv->state; priv->state = state; + priv->state_reason = reason; nm_log_info (LOGD_DEVICE, "(%s): device state change: %s -> %s (reason '%s') [%d %d %d]", nm_device_get_iface (device), @@ -3864,12 +4264,21 @@ nm_device_state_changed (NMDevice *device, state, reason); - /* Clear any delayed transitions */ - delayed_transitions_clear (device); + /* Clear any queued transitions */ + queued_state_clear (device); /* Cache the activation request for the dispatcher */ req = priv->act_request ? g_object_ref (priv->act_request) : NULL; + /* Update connection timestamps; do this before possibly deactivating the + * device since that will clear the activation request and thus the + * connection, which we need. + */ + if (state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_ACTIVATED) { + nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)), + (guint64) time (NULL), TRUE); + } + /* Handle the new state here; but anything that could trigger * another state change should be done below. */ @@ -3891,18 +4300,19 @@ nm_device_state_changed (NMDevice *device, * assuming the device's existing connection. */ if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device), reason); + nm_device_deactivate (device, reason); break; case NM_DEVICE_STATE_DISCONNECTED: if (old_state != NM_DEVICE_STATE_UNAVAILABLE) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device), reason); + nm_device_deactivate (device, reason); break; default: priv->autoconnect_inhibit = FALSE; break; } - g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_STATE); + g_object_notify (G_OBJECT (device), NM_DEVICE_STATE); + g_object_notify (G_OBJECT (device), NM_DEVICE_STATE_REASON); g_signal_emit_by_name (device, "state-changed", state, old_state, reason); /* Post-process the event after internal notification */ @@ -3918,7 +4328,7 @@ nm_device_state_changed (NMDevice *device, if (nm_device_is_available (device)) { nm_log_dbg (LOGD_DEVICE, "(%s): device is available, will transition to DISCONNECTED", nm_device_get_iface (device)); - priv->unavailable_to_disconnected_id = g_idle_add (unavailable_to_disconnected, device); + nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); } else { nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED", nm_device_get_iface (device)); @@ -3935,7 +4345,7 @@ nm_device_state_changed (NMDevice *device, * immediately because we can't change states again from the state * handler for a variety of reasons. */ - priv->failed_to_disconnected_id = g_idle_add (failed_to_disconnected, device); + nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); break; default: break; @@ -3949,6 +4359,51 @@ nm_device_state_changed (NMDevice *device, g_object_unref (req); } +static gboolean +queued_set_state (gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->queued_state.id) { + nm_log_dbg (LOGD_DEVICE, "(%s): running queued state change to %s (id %d)", + nm_device_get_iface (self), + state_to_string (priv->queued_state.state), + priv->queued_state.id); + priv->queued_state.id = 0; + nm_device_state_changed (self, priv->queued_state.state, priv->queued_state.reason); + } + queued_state_clear (self); + return FALSE; +} + +void +nm_device_queue_state (NMDevice *self, + NMDeviceState state, + NMDeviceStateReason reason) +{ + NMDevicePrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + + /* We should only ever have one delayed state transition at a time */ + if (priv->queued_state.id) { + g_warn_if_fail (priv->queued_state.id == 0); + queued_state_clear (self); + } + + priv->queued_state.state = state; + priv->queued_state.reason = reason; + priv->queued_state.id = g_idle_add (queued_set_state, self); + + nm_log_dbg (LOGD_DEVICE, "(%s): queued state change to %s (id %d)", + nm_device_get_iface (self), state_to_string (state), + priv->queued_state.id); +} + NMDeviceState nm_device_get_state (NMDevice *device) { @@ -3983,7 +4438,7 @@ nm_device_set_managed (NMDevice *device, nm_device_get_iface (device), managed ? "managed" : "unmanaged"); - g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED); + g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED); /* If now managed, jump to unavailable */ if (managed) @@ -3992,36 +4447,156 @@ nm_device_set_managed (NMDevice *device, nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); } +gboolean +nm_device_spec_match_list (NMDevice *device, const GSList *specs) +{ + g_return_val_if_fail (device != NULL, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + if (NM_DEVICE_GET_CLASS (device)->spec_match_list) + return NM_DEVICE_GET_CLASS (device)->spec_match_list (device, specs); + return FALSE; +} + static gboolean -spec_match_list (NMDeviceInterface *device, const GSList *specs) +ip4_match_config (NMDevice *self, NMConnection *connection) { - NMDevice *self; + NMSettingIP4Config *s_ip4; + int i, num; + GSList *leases, *iter; + NMDHCPManager *dhcp_mgr; + const char *method; - g_return_val_if_fail (device != NULL, FALSE); + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (!s_ip4) + return FALSE; - self = NM_DEVICE (device); - if (NM_DEVICE_GET_CLASS (self)->spec_match_list) - return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs); + /* Get any saved leases that apply to this connection */ + dhcp_mgr = nm_dhcp_manager_get (); + leases = nm_dhcp_manager_get_lease_config (dhcp_mgr, + nm_device_get_iface (self), + nm_connection_get_uuid (connection)); + g_object_unref (dhcp_mgr); + + method = nm_setting_ip4_config_get_method (s_ip4); + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + gboolean found = FALSE; + + /* Find at least one lease's address on the device */ + for (iter = leases; iter; iter = g_slist_next (iter)) { + NMIP4Config *ip4_config = iter->data; + NMIP4Address *addr = nm_ip4_config_get_address (ip4_config, 0); + struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; + + if (addr && nm_netlink_find_address (nm_device_get_ip_ifindex (self), + AF_INET, + &tmp, + nm_ip4_address_get_prefix (addr))) { + found = TRUE; /* Yay, device has same address as a lease */ + break; + } + } + g_slist_foreach (leases, (GFunc) g_object_unref, NULL); + g_slist_free (leases); + return found; + } else { + /* Maybe the connection used to be DHCP and there are stale leases; ignore them */ + g_slist_foreach (leases, (GFunc) g_object_unref, NULL); + g_slist_free (leases); + } - return FALSE; + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + // FIXME: Enforce no ipv4 addresses? + return TRUE; + } + + /* 'shared' and 'link-local' aren't supported methods because 'shared' + * requires too much iptables and dnsmasq state to be reclaimed, and + * avahi-autoipd isn't smart enough to allow the link-local address to be + * determined at any point other than when it was first assigned. + */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + return FALSE; + + /* Everything below for static addressing */ + + /* Find all IP4 addresses of this connection on the device */ + num = nm_setting_ip4_config_get_num_addresses (s_ip4); + for (i = 0; i < num; i++) { + NMIP4Address *addr = nm_setting_ip4_config_get_address (s_ip4, i); + struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; + + if (!nm_netlink_find_address (nm_device_get_ip_ifindex (self), + AF_INET, + &tmp, + nm_ip4_address_get_prefix (addr))) + return FALSE; + } + + /* Success; all the connection's static IP addresses are assigned to the device */ + return TRUE; } -static NMConnection * -connection_match_config (NMDeviceInterface *device, const GSList *connections) +gboolean +nm_device_match_ip_config (NMDevice *device, NMConnection *connection) +{ + if (!ip4_match_config (device, connection)) + return FALSE; + + /* FIXME: match IPv6 config */ + + return TRUE; +} + +NMConnection * +nm_device_connection_match_config (NMDevice *device, const GSList *connections) { g_return_val_if_fail (device != NULL, NULL); + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); if (NM_DEVICE_GET_CLASS (device)->connection_match_config) return NM_DEVICE_GET_CLASS (device)->connection_match_config (NM_DEVICE (device), connections); return NULL; } -static gboolean -can_assume_connections (NMDeviceInterface *device) +/** + * nm_device_hwaddr_matches: + * @device: the device to use when matching the hardware address + * @connection: the connection which supplies the hardware address + * @other_hwaddr: if given, use this address instead of the device's actual + * hardware address + * @other_hwaddr_len: length in bytes of @other_hwaddr + * @fail_if_no_hwaddr: whether to fail the match if @connection does not contain + * a hardware address + * + * Matches a the devices hardware address (or @other_hwaddr if given) against + * the hardware-specific setting in @connection. Allows for device-agnostic + * hardware address matching without having to know the internal details of + * the connection and which settings are used by each device subclass. + * + * Returns: %TRUE if the @device 's hardware address or @other_hwaddr matches + * a hardware address in a hardware-specific setting in @connection + */ +gboolean +nm_device_hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { g_return_val_if_fail (device != NULL, FALSE); - - return !!NM_DEVICE_GET_CLASS (device)->connection_match_config; + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + if (other_hwaddr) + g_return_val_if_fail (other_hwaddr_len > 0, FALSE); + + if (NM_DEVICE_GET_CLASS (device)->hwaddr_matches) { + return NM_DEVICE_GET_CLASS (device)->hwaddr_matches (device, + connection, + other_hwaddr, + other_hwaddr_len, + fail_if_no_hwaddr); + } + return FALSE; } void diff --git a/src/nm-device.h b/src/nm-device.h index 1d080eda..bf76ecb5 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -33,14 +33,31 @@ #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" #include "nm-connection.h" - -typedef enum NMActStageReturn -{ - NM_ACT_STAGE_RETURN_FAILURE = 0, - NM_ACT_STAGE_RETURN_SUCCESS, - NM_ACT_STAGE_RETURN_POSTPONE, - NM_ACT_STAGE_RETURN_STOP /* This activation chain is done */ -} NMActStageReturn; +#include "nm-rfkill.h" + +/* Properties */ +#define NM_DEVICE_UDI "udi" +#define NM_DEVICE_IFACE "interface" +#define NM_DEVICE_IP_IFACE "ip-interface" +#define NM_DEVICE_DRIVER "driver" +#define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_IP4_ADDRESS "ip4-address" +#define NM_DEVICE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" +#define NM_DEVICE_IP6_CONFIG "ip6-config" +#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config" +#define NM_DEVICE_STATE "state" +#define NM_DEVICE_STATE_REASON "state-reason" +#define NM_DEVICE_ACTIVE_CONNECTION "active-connection" +#define NM_DEVICE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_MANAGED "managed" +#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ + +/* Internal signal */ +#define NM_DEVICE_DISCONNECT_REQUEST "disconnect-request" G_BEGIN_DECLS @@ -52,6 +69,14 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE)) #define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass)) +typedef enum NMActStageReturn NMActStageReturn; + +typedef enum { + NM_DEVICE_ERROR_CONNECTION_ACTIVATING = 0, /*< nick=ConnectionActivating >*/ + NM_DEVICE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ +} NMDeviceError; + typedef struct { GObject parent; } NMDevice; @@ -59,6 +84,11 @@ typedef struct { typedef struct { GObjectClass parent; + void (*state_changed) (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason); + /* Hardware state, ie IFF_UP */ gboolean (*hw_is_up) (NMDevice *self); gboolean (*hw_bring_up) (NMDevice *self, gboolean *no_firmware); @@ -80,6 +110,10 @@ typedef struct { gboolean (* is_available) (NMDevice *self); + gboolean (* get_enabled) (NMDevice *self); + + void (* set_enabled) (NMDevice *self, gboolean enabled); + NMConnection * (* get_best_auto_connection) (NMDevice *self, GSList *connections, char **specific_object); @@ -99,21 +133,20 @@ typedef struct { NMActStageReturn (* act_stage2_config) (NMDevice *self, NMDeviceStateReason *reason); NMActStageReturn (* act_stage3_ip4_config_start) (NMDevice *self, + NMIP4Config **out_config, NMDeviceStateReason *reason); NMActStageReturn (* act_stage3_ip6_config_start) (NMDevice *self, + NMIP6Config **out_config, NMDeviceStateReason *reason); - NMActStageReturn (* act_stage4_get_ip4_config) (NMDevice *self, - NMIP4Config **config, - NMDeviceStateReason *reason); - NMActStageReturn (* act_stage4_get_ip6_config) (NMDevice *self, - NMIP6Config **config, - NMDeviceStateReason *reason); NMActStageReturn (* act_stage4_ip4_config_timeout) (NMDevice *self, - NMIP4Config **config, NMDeviceStateReason *reason); NMActStageReturn (* act_stage4_ip6_config_timeout) (NMDevice *self, - NMIP6Config **config, NMDeviceStateReason *reason); + + /* Called right before IP config is set; use for setting MTU etc */ + void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config); + void (* ip6_config_pre_commit) (NMDevice *self, NMIP6Config *config); + void (* deactivate) (NMDevice *self); gboolean (* can_interrupt_activation) (NMDevice *self); @@ -121,6 +154,18 @@ typedef struct { gboolean (* spec_match_list) (NMDevice *self, const GSList *specs); NMConnection * (* connection_match_config) (NMDevice *self, const GSList *connections); + + gboolean (* hwaddr_matches) (NMDevice *self, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr); + + gboolean (* enslave_slave) (NMDevice *self, + NMDevice *slave); + + gboolean (* release_slave) (NMDevice *self, + NMDevice *slave); } NMDeviceClass; @@ -136,25 +181,21 @@ const char * nm_device_get_ip_iface (NMDevice *dev); int nm_device_get_ip_ifindex(NMDevice *dev); const char * nm_device_get_driver (NMDevice *dev); const char * nm_device_get_type_desc (NMDevice *dev); - NMDeviceType nm_device_get_device_type (NMDevice *dev); -guint32 nm_device_get_capabilities (NMDevice *dev); -guint32 nm_device_get_type_capabilities (NMDevice *dev); int nm_device_get_priority (NMDevice *dev); -guint32 nm_device_get_ip4_address (NMDevice *dev); -void nm_device_update_ip4_address (NMDevice *dev); - NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *dev); NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *dev); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); NMIP6Config * nm_device_get_ip6_config (NMDevice *dev); -void * nm_device_get_system_config_data (NMDevice *dev); +gboolean nm_device_enslave_slave (NMDevice *dev, NMDevice *slave); +gboolean nm_device_release_slave (NMDevice *dev, NMDevice *slave); NMActRequest * nm_device_get_act_request (NMDevice *dev); +NMConnection * nm_device_get_connection (NMDevice *dev); gboolean nm_device_is_available (NMDevice *dev); @@ -168,29 +209,59 @@ gboolean nm_device_complete_connection (NMDevice *device, const GSList *existing_connection, GError **error); -void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); -void nm_device_activate_schedule_stage2_device_config (NMDevice *device); -void nm_device_activate_schedule_stage4_ip4_config_get (NMDevice *device); -void nm_device_activate_schedule_stage4_ip4_config_timeout (NMDevice *device); -void nm_device_activate_schedule_stage4_ip6_config_get (NMDevice *device); -void nm_device_activate_schedule_stage4_ip6_config_timeout (NMDevice *device); +gboolean nm_device_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error); + +gboolean nm_device_can_assume_connections (NMDevice *device); + +NMConnection * nm_device_connection_match_config (NMDevice *device, + const GSList *connections); + +gboolean nm_device_hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr); + +gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); + gboolean nm_device_is_activating (NMDevice *dev); gboolean nm_device_can_interrupt_activation (NMDevice *self); gboolean nm_device_autoconnect_allowed (NMDevice *self); NMDeviceState nm_device_get_state (NMDevice *device); +gboolean nm_device_get_enabled (NMDevice *device); + +void nm_device_set_enabled (NMDevice *device, gboolean enabled); + +RfKillType nm_device_get_rfkill_type (NMDevice *device); + gboolean nm_device_get_managed (NMDevice *device); void nm_device_set_managed (NMDevice *device, gboolean managed, NMDeviceStateReason reason); -void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); -void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); - void nm_device_clear_autoconnect_inhibit (NMDevice *device); -gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); +void nm_device_handle_autoip4_event (NMDevice *self, + const char *event, + const char *address); + +void nm_device_state_changed (NMDevice *device, + NMDeviceState state, + NMDeviceStateReason reason); + +void nm_device_queue_state (NMDevice *self, + NMDeviceState state, + NMDeviceStateReason reason); + +gboolean nm_device_get_firmware_missing (NMDevice *self); + +gboolean nm_device_activate (NMDevice *device, NMActRequest *req, GError **error); + +gboolean nm_device_disconnect (NMDevice *device, GError **error); G_END_DECLS diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 2f231638..f06e4069 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -71,7 +71,7 @@ enum { static struct nl_addr * -nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr) +nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr, guint prefix) { struct nl_addr * nla = NULL; @@ -79,6 +79,8 @@ nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr) return NULL; nl_addr_set_family (nla, AF_INET6); nl_addr_set_binary_addr (nla, (struct in6_addr *)ip6_addr, sizeof (struct in6_addr)); + if (prefix) + nl_addr_set_prefixlen (nla, prefix); return nla; } @@ -428,14 +430,16 @@ nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_default) /* libnl convenience/conversion functions */ -static int ip6_addr_to_rtnl_local (const struct in6_addr *ip6_address, struct rtnl_addr *addr) +static int ip6_addr_to_rtnl_local (const struct in6_addr *ip6_address, + struct rtnl_addr *addr, + guint prefix) { struct nl_addr * local = NULL; int err = 0; g_return_val_if_fail (addr != NULL, -1); - local = nm_utils_ip6_addr_to_nl_addr (ip6_address); + local = nm_utils_ip6_addr_to_nl_addr (ip6_address, prefix); err = rtnl_addr_set_local (addr, local); nl_addr_put (local); @@ -449,7 +453,7 @@ static int ip6_addr_to_rtnl_peer (const struct in6_addr *ip6_address, struct rtn g_return_val_if_fail (addr != NULL, -1); - peer = nm_utils_ip6_addr_to_nl_addr (ip6_address); + peer = nm_utils_ip6_addr_to_nl_addr (ip6_address, 0); err = rtnl_addr_set_peer (addr, peer); nl_addr_put (peer); @@ -472,8 +476,11 @@ nm_ip6_config_to_rtnl_addr (NMIP6Config *config, guint32 i, guint32 flags) if (!(addr = rtnl_addr_alloc())) return NULL; - if (flags & NM_RTNL_ADDR_ADDR) - success = (ip6_addr_to_rtnl_local (nm_ip6_address_get_address (config_addr), addr) >= 0); + if (flags & NM_RTNL_ADDR_ADDR) { + success = (ip6_addr_to_rtnl_local (nm_ip6_address_get_address (config_addr), + addr, + nm_ip6_address_get_prefix (config_addr)) >= 0); + } if (flags & NM_RTNL_ADDR_PTP_ADDR) success = (ip6_addr_to_rtnl_peer (&priv->ptp_address, addr) >= 0); diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index beed65ab..d797032b 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -541,7 +541,7 @@ nm_auth_uid_in_acl (NMConnection *connection, g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (smon != NULL, FALSE); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); /* Reject the request if the request comes from no session at all */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 475344a5..7c812bdc 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -16,16 +16,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2009 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. */ #include <config.h> #include <netinet/ether.h> -#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> #include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib.h> #include <gio/gio.h> @@ -38,15 +40,14 @@ #include "nm-vpn-manager.h" #include "nm-modem-manager.h" #include "nm-device-bt.h" -#include "nm-device-interface.h" -#include "nm-device-private.h" +#include "nm-device.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" -#if WITH_WIMAX -#include "nm-device-wimax.h" -#endif #include "nm-device-modem.h" +#include "nm-device-infiniband.h" +#include "nm-device-bond.h" +#include "nm-device-vlan.h" #include "nm-system.h" #include "nm-properties-changed-signal.h" #include "nm-setting-bluetooth.h" @@ -64,6 +65,14 @@ #include "nm-manager-auth.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" +#include "nm-device-factory.h" +#include "wifi-utils.h" +#include "nm-enum-types.h" + +#if WITH_CONCHECK +#include "nm-connectivity.h" +#endif + #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" @@ -117,15 +126,6 @@ static gboolean impl_manager_set_logging (NMManager *manager, #include "nm-manager-glue.h" -static void udev_device_added_cb (NMUdevManager *udev_mgr, - GUdevDevice *device, - NMDeviceCreatorFn creator_fn, - gpointer user_data); - -static void udev_device_removed_cb (NMUdevManager *udev_mgr, - GUdevDevice *device, - gpointer user_data); - static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, const char *bdaddr, const char *name, @@ -144,14 +144,15 @@ static void add_device (NMManager *self, NMDevice *device); static void hostname_provider_init (NMHostnameProvider *provider_class); -static const char *internal_activate_device (NMManager *manager, - NMDevice *device, - NMConnection *connection, - const char *specific_object, - gboolean user_requested, - gulong sender_uid, - gboolean assumed, - GError **error); +static NMActiveConnection *internal_activate_device (NMManager *manager, + NMDevice *device, + NMConnection *connection, + const char *specific_object, + gboolean user_requested, + gulong sender_uid, + gboolean assumed, + NMActiveConnection *master, + GError **error); static NMDevice *find_device_by_ip_iface (NMManager *self, const gchar *iface); @@ -200,11 +201,17 @@ typedef struct { GSList *devices; NMState state; +#if WITH_CONCHECK + NMConnectivity *connectivity; +#endif NMDBusManager *dbus_mgr; NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; + /* List of NMDeviceFactoryFunc pointers sorted in priority order */ + GSList *factories; + NMSettings *settings; char *hostname; @@ -277,20 +284,7 @@ enum { /************************************************************************/ -typedef enum { - NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, - NM_MANAGER_ERROR_UNKNOWN_DEVICE, - NM_MANAGER_ERROR_UNMANAGED_DEVICE, - NM_MANAGER_ERROR_SYSTEM_CONNECTION, - NM_MANAGER_ERROR_PERMISSION_DENIED, - NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, - NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, - NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, - NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, -} NMManagerError; - #define NM_MANAGER_ERROR (nm_manager_error_quark ()) -#define NM_TYPE_MANAGER_ERROR (nm_manager_error_get_type ()) static GQuark nm_manager_error_quark (void) @@ -301,41 +295,6 @@ nm_manager_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_manager_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not provided by any known settings service. */ - ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "UnknownConnection"), - /* Unknown device. */ - ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_DEVICE, "UnknownDevice"), - /* Unmanaged device. */ - ENUM_ENTRY (NM_MANAGER_ERROR_UNMANAGED_DEVICE, "UnmanagedDevice"), - /* Connection was superceded by a system connection. */ - ENUM_ENTRY (NM_MANAGER_ERROR_SYSTEM_CONNECTION, "SystemConnection"), - /* User does not have the permission to activate this connection. */ - ENUM_ENTRY (NM_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"), - /* The connection was not active. */ - ENUM_ENTRY (NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "ConnectionNotActive"), - /* The manager is already in the requested sleep state */ - ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "AlreadyAsleepOrAwake"), - /* The manager is already in the requested enabled/disabled state */ - ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "AlreadyEnabledOrDisabled"), - /* The requested operation is unsupported for this type of connection */ - ENUM_ENTRY (NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, "UnsupportedConnectionType"), - { 0, 0, 0 }, - }; - etype = g_enum_register_static ("NMManagerError", values); - } - return etype; -} - /************************************************************************/ static NMDevice * @@ -366,6 +325,24 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path) return NULL; } +NMDevice * +nm_manager_get_device_by_master (NMManager *manager, const char *master, const char *driver) +{ + GSList *iter; + + g_return_val_if_fail (master != NULL, NULL); + + for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { + NMDevice *device = NM_DEVICE (iter->data); + + if (!strcmp (nm_device_get_iface (device), master) && + (!driver || !strcmp (nm_device_get_driver (device), driver))) + return device; + } + + return NULL; +} + static gboolean manager_sleeping (NMManager *self) { @@ -385,7 +362,7 @@ vpn_manager_connection_activated_cb (NMVPNManager *manager, { /* Update timestamp for the VPN connection */ nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_vpn_connection_get_connection (vpn)), - (guint64) time (NULL)); + (guint64) time (NULL), TRUE); } static void @@ -422,7 +399,7 @@ modem_added (NMModemManager *modem_manager, /* Give Bluetooth DUN devices first chance to claim the modem */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - if (NM_IS_DEVICE_BT (iter->data)) { + if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) { if (nm_device_bt_modem_added (NM_DEVICE_BT (iter->data), modem, driver)) return; } @@ -462,8 +439,12 @@ nm_manager_update_state (NMManager *manager) NMDeviceState state = nm_device_get_state (dev); if (state == NM_DEVICE_STATE_ACTIVATED) { - /* FIXME: handle local-only and site too */ new_state = NM_STATE_CONNECTED_GLOBAL; +#if WITH_CONCHECK + /* Connectivity check might have a better idea */ + if (nm_connectivity_get_connected (priv->connectivity) == FALSE) + new_state = NM_STATE_CONNECTED_SITE; +#endif break; } @@ -491,7 +472,10 @@ manager_device_state_changed (NMDevice *device, NMDeviceStateReason reason, gpointer user_data) { - NMManager *manager = NM_MANAGER (user_data); + NMManager *self = NM_MANAGER (user_data); +#if WITH_CONCHECK + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); +#endif switch (new_state) { case NM_DEVICE_STATE_UNMANAGED: @@ -499,22 +483,30 @@ manager_device_state_changed (NMDevice *device, case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_FAILED: - g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS); break; default: break; } - nm_manager_update_state (manager); - - if (new_state == NM_DEVICE_STATE_ACTIVATED) { - NMActRequest *req; + nm_manager_update_state (self); - req = nm_device_get_act_request (device); - if (req) - nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)), - (guint64) time (NULL)); +#if WITH_CONCHECK + if (priv->state >= NM_STATE_CONNECTED_LOCAL) { + if (old_state == NM_DEVICE_STATE_ACTIVATED || new_state == NM_DEVICE_STATE_ACTIVATED) { + /* Still connected, but a device activated or deactivated; make sure + * we still have connectivity on the other activated devices. + */ + nm_log_dbg (LOGD_CORE, "(%s): triggered connectivity check due to state change", + nm_device_get_iface (device)); + nm_connectivity_start_check (priv->connectivity); + } + } else { + /* Cannot be connected if no devices are activated */ + nm_log_dbg (LOGD_CORE, "stopping connectivity checks"); + nm_connectivity_stop_check (priv->connectivity); } +#endif } /* Removes a device from a device list; returns the start of the new device list */ @@ -535,7 +527,7 @@ remove_one_device (NMManager *manager, * connections get torn down and the interface is deactivated. */ - if ( !nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device)) + if ( !nm_device_can_assume_connections (device) || (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) || !quitting) nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED); @@ -562,7 +554,7 @@ modem_removed (NMModemManager *modem_manager, /* Give Bluetooth DUN devices first chance to handle the modem removal */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - if (NM_IS_DEVICE_BT (iter->data)) { + if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) { if (nm_device_bt_modem_removed (NM_DEVICE_BT (iter->data), modem)) return; } @@ -639,11 +631,11 @@ might_be_vpn (NMConnection *connection) NMSettingConnection *s_con; const char *ctype = NULL; - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN)) + if (nm_connection_get_setting_vpn (connection)) return TRUE; /* Make sure it's not a VPN, which we can't autocomplete yet */ - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if (s_con) ctype = nm_setting_connection_get_connection_type (s_con); @@ -655,7 +647,7 @@ try_complete_vpn (NMConnection *connection, GSList *existing, GError **error) { g_assert (might_be_vpn (connection) == TRUE); - if (!nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN)) { + if (!nm_connection_get_setting_vpn (connection)) { g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, @@ -741,13 +733,14 @@ pending_activation_new (NMManager *manager, pending->context = context; pending->callback = callback; - pending->device_path = g_strdup (device_path); pending->connection_path = g_strdup (connection_path); pending->connection = connection; /* "/" is special-cased to NULL to get through D-Bus */ if (specific_object_path && strcmp (specific_object_path, "/")) pending->specific_object_path = g_strdup (specific_object_path); + if (device_path && strcmp (device_path, "/")) + pending->device_path = g_strdup (device_path); return pending; } @@ -862,19 +855,21 @@ pending_activation_check_authorized (PendingActivation *pending, static void pending_activation_destroy (PendingActivation *pending, GError *error, - const char *ac_path) + NMActiveConnection *ac) { g_return_if_fail (pending != NULL); if (error) dbus_g_method_return_error (pending->context, error); - else if (ac_path) { + else if (ac) { if (pending->connection) { dbus_g_method_return (pending->context, pending->connection_path, - ac_path); - } else - dbus_g_method_return (pending->context, ac_path); + nm_active_connection_get_path (ac)); + } else { + dbus_g_method_return (pending->context, + nm_active_connection_get_path (ac)); + } } g_free (pending->connection_path); @@ -909,7 +904,7 @@ get_active_connections (NMManager *manager, NMConnection *filter) continue; if (!filter || (nm_act_request_get_connection (req) == filter)) { - path = nm_act_request_get_active_connection_path (req); + path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (req)); g_ptr_array_add (active, g_strdup (path)); } } @@ -924,12 +919,274 @@ get_active_connections (NMManager *manager, NMConnection *filter) /* Settings stuff via NMSettings */ /*******************************************************************/ +static NMDevice * +get_device_from_hwaddr (NMManager *self, NMConnection *connection) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + if (nm_device_hwaddr_matches (NM_DEVICE (iter->data), connection, NULL, 0, TRUE)) + return iter->data; + } + return NULL; +} + +static NMDevice* +find_vlan_parent (NMManager *self, + NMConnection *connection, + gboolean check_hwaddr) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSettingVlan *s_vlan; + NMConnection *parent_connection; + const char *parent_iface; + NMDevice *parent = NULL; + GSList *iter; + + /* The 'parent' property could be either an interface name, a connection + * UUID, or even given by the MAC address of the connection's ethernet, + * InfiniBand, or WiFi setting. + */ + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan != NULL, NULL); + + parent_iface = nm_setting_vlan_get_parent (s_vlan); + if (parent_iface) { + parent = find_device_by_ip_iface (self, parent_iface); + if (parent) + return parent; + + if (nm_utils_is_uuid (parent_iface)) { + /* Try as a connection UUID */ + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, parent_iface); + if (parent_connection) { + /* Check if the parent connection is activated on some device already */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMActRequest *req; + NMConnection *candidate; + + req = nm_device_get_act_request (NM_DEVICE (iter->data)); + if (req) { + candidate = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (req)); + if (candidate == parent_connection) + return parent; + } + } + + /* Check the hardware address of the parent connection */ + if (check_hwaddr) + return get_device_from_hwaddr (self, parent_connection); + } + return NULL; + } + } + + /* Try the hardware address from the VLAN connection's hardware setting */ + if (check_hwaddr) + return get_device_from_hwaddr (self, connection); + + return NULL; +} + +/** + * get_virtual_iface_name: + * @self: the #NMManager + * @connection: the #NMConnection representing a virtual interface + * @out_parent: on success, the parent device if any + * + * Given @connection, returns the interface name that the connection + * would represent. If the interface name is not given by the connection, + * this may require constructing it based on information in the connection + * and existing network interfaces. + * + * Returns: the expected interface name (caller takes ownership), or %NULL + */ +static char * +get_virtual_iface_name (NMManager *self, + NMConnection *connection, + NMDevice **out_parent) +{ + char *vname = NULL; + NMDevice *parent = NULL; + + if (out_parent) + *out_parent = NULL; + + if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + return g_strdup (nm_connection_get_virtual_iface_name (connection)); + + if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { + NMSettingVlan *s_vlan; + const char *ifname; + + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan != NULL, NULL); + + parent = find_vlan_parent (self, connection, TRUE); + if (parent) { + /* If the connection doesn't specify the interface name for the VLAN + * device, we create one for it using the VLAN ID and the parent + * interface's name. + */ + ifname = nm_connection_get_virtual_iface_name (connection); + if (ifname) + vname = g_strdup (ifname); + else { + vname = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), + nm_setting_vlan_get_id (s_vlan)); + } + if (out_parent) + *out_parent = parent; + } + } + + return vname; +} + +static gboolean +connection_needs_virtual_device (NMConnection *connection) +{ + if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + return TRUE; + if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) + return TRUE; + + return FALSE; +} + +static char * +get_virtual_iface_placeholder_udi (void) +{ + static guint32 id = 0; + + return g_strdup_printf ("/virtual/device/placeholder/%d", id++); +} + +/** + * system_create_virtual_device: + * @self: the #NMManager + * @connection: the connection which might require a virtual device + * + * If @connection requires a virtual device and one does not yet exist for it, + * creates that device. + * + * Returns: the #NMDevice if successfully created, NULL if not + */ +static NMDevice * +system_create_virtual_device (NMManager *self, NMConnection *connection) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; + char *iface = NULL, *udi; + NMDevice *device = NULL, *parent = NULL; + + iface = get_virtual_iface_name (self, connection, &parent); + if (!iface) { + nm_log_warn (LOGD_DEVICE, "(%s) failed to determine virtual interface name", + nm_connection_get_id (connection)); + return NULL; + } + + /* Make sure we didn't create a device for this connection already */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *candidate = iter->data; + GError *error = NULL; + + if ( g_strcmp0 (nm_device_get_iface (candidate), iface) == 0 + || nm_device_check_connection_compatible (candidate, connection, &error)) { + g_clear_error (&error); + goto out; + } + g_clear_error (&error); + } + + if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { + if (!nm_system_add_bonding_master (iface)) { + nm_log_warn (LOGD_DEVICE, "(%s): failed to add bonding master interface for '%s'", + iface, nm_connection_get_id (connection)); + goto out; + } + + udi = get_virtual_iface_placeholder_udi (); + device = nm_device_bond_new (udi, iface); + g_free (udi); + } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { + g_return_val_if_fail (parent != NULL, FALSE); + + if (!nm_system_add_vlan_iface (connection, iface, nm_device_get_ip_ifindex (parent))) { + nm_log_warn (LOGD_DEVICE, "(%s): failed to add VLAN interface for '%s'", + iface, nm_connection_get_id (connection)); + goto out; + } + udi = get_virtual_iface_placeholder_udi (); + device = nm_device_vlan_new (udi, iface, parent); + g_free (udi); + } + + if (device) + add_device (self, device); + +out: + g_free (iface); + return device; +} + static void -connections_changed (NMSettings *settings, +system_create_virtual_devices (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter, *connections; + + nm_log_dbg (LOGD_CORE, "creating virtual devices..."); + + connections = nm_settings_get_connections (priv->settings); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = iter->data; + NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + + g_assert (s_con); + if (connection_needs_virtual_device (connection)) { + /* We only create a virtual interface if the connection can autoconnect */ + if (nm_setting_connection_get_autoconnect (s_con)) + system_create_virtual_device (self, connection); + } + } + g_slist_free (connections); +} + +static void +connection_added (NMSettings *settings, + NMSettingsConnection *connection, + NMManager *manager) +{ + bluez_manager_resync_devices (manager); + + if (connection_needs_virtual_device (NM_CONNECTION (connection))) + system_create_virtual_device (manager, NM_CONNECTION (connection)); +} + +static void +connection_changed (NMSettings *settings, NMSettingsConnection *connection, NMManager *manager) { bluez_manager_resync_devices (manager); + + /* FIXME: Some virtual devices may need to be updated in the future. */ +} + +static void +connection_removed (NMSettings *settings, + NMSettingsConnection *connection, + NMManager *manager) +{ + bluez_manager_resync_devices (manager); + + /* + * Do not delete existing virtual devices to keep connectivity up. + * Virtual devices are reused when NetworkManager is restarted. + */ } static void @@ -946,7 +1203,7 @@ system_unmanaged_devices_changed_cb (NMSettings *settings, NMDevice *device = NM_DEVICE (iter->data); gboolean managed; - managed = !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs); + managed = !nm_device_spec_match_list (device, unmanaged_specs); nm_device_set_managed (device, managed, managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED : @@ -1072,20 +1329,19 @@ manager_update_radio_enabled (NMManager *self, /* enable/disable wireless devices as required */ for (iter = priv->devices; iter; iter = iter->next) { - RfKillType devtype = RFKILL_TYPE_UNKNOWN; + NMDevice *device = NM_DEVICE (iter->data); - g_object_get (G_OBJECT (iter->data), NM_DEVICE_INTERFACE_RFKILL_TYPE, &devtype, NULL); - if (devtype == rstate->rtype) { + if (nm_device_get_rfkill_type (device) == rstate->rtype) { nm_log_dbg (LOGD_RFKILL, "(%s): setting radio %s", - nm_device_get_iface (NM_DEVICE (iter->data)), + nm_device_get_iface (device), enabled ? "enabled" : "disabled"); - nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (iter->data), enabled); + nm_device_set_enabled (device, enabled); } } } static void -manager_hidden_ap_found (NMDeviceInterface *device, +manager_hidden_ap_found (NMDevice *device, NMAccessPoint *ap, gpointer user_data) { @@ -1128,7 +1384,7 @@ nm_manager_get_ipw_rfkill_state (NMManager *self) NMDevice *candidate = NM_DEVICE (iter->data); RfKillState candidate_state; - if (NM_IS_DEVICE_WIFI (candidate)) { + if (nm_device_get_device_type (candidate) == NM_DEVICE_TYPE_WIFI) { candidate_state = nm_device_wifi_get_ipw_rfkill_state (NM_DEVICE_WIFI (candidate)); if (candidate_state > ipw_state) @@ -1149,11 +1405,9 @@ nm_manager_get_modem_enabled_state (NMManager *self) for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *candidate = NM_DEVICE (iter->data); RfKillState candidate_state = RFKILL_UNBLOCKED; - RfKillType devtype = RFKILL_TYPE_UNKNOWN; - g_object_get (G_OBJECT (candidate), NM_DEVICE_INTERFACE_RFKILL_TYPE, &devtype, NULL); - if (devtype == RFKILL_TYPE_WWAN) { - if (!nm_device_interface_get_enabled (NM_DEVICE_INTERFACE (candidate))) + if (nm_device_get_rfkill_type (candidate) == RFKILL_TYPE_WWAN) { + if (!nm_device_get_enabled (candidate)) candidate_state = RFKILL_SOFT_BLOCKED; if (candidate_state > wwan_state) @@ -1323,7 +1577,7 @@ disconnect_net_auth_done_cb (NMAuthChain *chain, error = deactivate_disconnect_check_error (auth_error, result, "Disconnect"); if (!error) { device = nm_auth_chain_get_data (chain, "device"); - if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &error)) + if (!nm_device_disconnect (device, &error)) g_assert (error); } @@ -1375,7 +1629,7 @@ manager_device_disconnect_request (NMDevice *device, /* Yay for root */ if (0 == sender_uid) { - if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &error)) { + if (!nm_device_disconnect (device, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); } else @@ -1403,12 +1657,23 @@ add_device (NMManager *self, NMDevice *device) const GSList *unmanaged_specs; NMConnection *existing = NULL; gboolean managed = FALSE, enabled = FALSE; - RfKillType rtype = RFKILL_TYPE_UNKNOWN; + RfKillType rtype; + NMDeviceType devtype; iface = nm_device_get_ip_iface (device); g_assert (iface); - if (!NM_IS_DEVICE_MODEM (device) && find_device_by_ip_iface (self, iface)) { + devtype = nm_device_get_device_type (device); + + /* Ignore the device if we already know about it. But some modems will + * provide pseudo-ethernet devices that NM has already claimed while + * ModemManager is still detecting the modem's serial ports, so when the + * MM modem object finally shows up it may have the same IP interface as the + * ethernet interface we've already detected. In this case we skip the + * check for an existing device with the same IP interface name and kill + * the ethernet device later in favor of the modem device. + */ + if ((devtype != NM_DEVICE_TYPE_MODEM) && find_device_by_ip_iface (self, iface)) { g_object_unref (device); return; } @@ -1419,11 +1684,11 @@ add_device (NMManager *self, NMDevice *device) G_CALLBACK (manager_device_state_changed), self); - g_signal_connect (device, NM_DEVICE_INTERFACE_DISCONNECT_REQUEST, + g_signal_connect (device, NM_DEVICE_DISCONNECT_REQUEST, G_CALLBACK (manager_device_disconnect_request), self); - if (NM_IS_DEVICE_WIFI (device)) { + if (devtype == NM_DEVICE_TYPE_WIFI) { /* Attach to the access-point-added signal so that the manager can fill * non-SSID-broadcasting APs with an SSID. */ @@ -1437,25 +1702,21 @@ add_device (NMManager *self, NMDevice *device) g_signal_connect (device, "notify::" NM_DEVICE_WIFI_IPW_RFKILL_STATE, G_CALLBACK (manager_ipw_rfkill_state_changed), self); - rtype = RFKILL_TYPE_WLAN; - } else if (NM_IS_DEVICE_MODEM (device)) { + } else if (devtype == NM_DEVICE_TYPE_MODEM) { g_signal_connect (device, NM_DEVICE_MODEM_ENABLE_CHANGED, G_CALLBACK (manager_modem_enabled_changed), self); - rtype = RFKILL_TYPE_WWAN; -#if WITH_WIMAX - } else if (NM_IS_DEVICE_WIMAX (device)) { - rtype = RFKILL_TYPE_WIMAX; -#endif } + /* Update global rfkill state for this device type with the device's + * rfkill state, and then set this device's rfkill state based on the + * global state. + */ + rtype = nm_device_get_rfkill_type (device); if (rtype != RFKILL_TYPE_UNKNOWN) { - /* Update global rfkill state with this device's rfkill state, and - * then set this device's rfkill state based on the global state. - */ nm_manager_rfkill_update (self, rtype); enabled = radio_enabled_for_type (self, rtype, TRUE); - nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled); + nm_device_set_enabled (device, enabled); } type_desc = nm_device_get_type_desc (device); @@ -1477,12 +1738,11 @@ add_device (NMManager *self, NMDevice *device) /* Check if we should assume the device's active connection by matching its * config with an existing system connection. */ - if (nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device))) { + if (nm_device_can_assume_connections (device)) { GSList *connections = NULL; connections = nm_settings_get_connections (priv->settings); - existing = nm_device_interface_connection_match_config (NM_DEVICE_INTERFACE (device), - (const GSList *) connections); + existing = nm_device_connection_match_config (device, (const GSList *) connections); g_slist_free (connections); if (existing) @@ -1494,7 +1754,7 @@ add_device (NMManager *self, NMDevice *device) /* Start the device if it's supposed to be managed */ unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); if ( !manager_sleeping (self) - && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) { + && !nm_device_spec_match_list (device, unmanaged_specs)) { nm_device_set_managed (device, TRUE, existing ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : @@ -1505,16 +1765,21 @@ add_device (NMManager *self, NMDevice *device) nm_settings_device_added (priv->settings, device); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); + /* New devices might be master interfaces for virtual interfaces; so we may + * need to create new virtual interfaces now. + */ + system_create_virtual_devices (self); + /* If the device has a connection it can assume, do that now */ if (existing && managed && nm_device_is_available (device)) { - const char *ac_path; + NMActiveConnection *ac; GError *error = NULL; nm_log_dbg (LOGD_DEVICE, "(%s): will attempt to assume existing connection", nm_device_get_iface (device)); - ac_path = internal_activate_device (self, device, existing, NULL, FALSE, 0, TRUE, &error); - if (ac_path) + ac = internal_activate_device (self, device, existing, NULL, FALSE, 0, TRUE, NULL, &error); + if (ac) g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS); else { nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s", @@ -1570,14 +1835,14 @@ bluez_manager_find_connection (NMManager *manager, const char *con_type; const char *bt_type; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (candidate); g_assert (s_con); con_type = nm_setting_connection_get_connection_type (s_con); g_assert (con_type); if (!g_str_equal (con_type, NM_SETTING_BLUETOOTH_SETTING_NAME)) continue; - s_bt = (NMSettingBluetooth *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_BLUETOOTH); + s_bt = nm_connection_get_setting_bluetooth (candidate); if (!s_bt) continue; @@ -1612,7 +1877,7 @@ bluez_manager_resync_devices (NMManager *self) guint32 uuids; const char *bdaddr; - if (NM_IS_DEVICE_BT (candidate)) { + if (nm_device_get_device_type (candidate) == NM_DEVICE_TYPE_BT) { uuids = nm_device_bt_get_capabilities (NM_DEVICE_BT (candidate)); bdaddr = nm_device_bt_get_hw_address (NM_DEVICE_BT (candidate)); @@ -1734,23 +1999,246 @@ find_device_by_ifindex (NMManager *self, guint32 ifindex) return NULL; } +#define PLUGIN_PREFIX "libnm-device-plugin-" + +typedef struct { + NMDeviceType t; + guint priority; + NMDeviceFactoryCreateFunc create_func; +} PluginInfo; + +static gint +plugin_sort (PluginInfo *a, PluginInfo *b) +{ + /* Higher priority means sort earlier in the list (ie, return -1) */ + if (a->priority > b->priority) + return -1; + else if (a->priority < b->priority) + return 1; + return 0; +} + +static void +load_device_factories (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GDir *dir; + GError *error = NULL; + const char *item; + char *path; + GSList *list = NULL, *iter; + + dir = g_dir_open (NMPLUGINDIR, 0, &error); + if (!dir) { + nm_log_warn (LOGD_HW, "Failed to open plugin directory %s: %s", + NMPLUGINDIR, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + return; + } + + while ((item = g_dir_read_name (dir))) { + GModule *plugin; + NMDeviceFactoryCreateFunc create_func; + NMDeviceFactoryPriorityFunc priority_func; + NMDeviceFactoryTypeFunc type_func; + PluginInfo *info = NULL; + NMDeviceType plugin_type; + + if (!g_str_has_prefix (item, PLUGIN_PREFIX)) + continue; + + path = g_module_build_path (NMPLUGINDIR, item); + g_assert (path); + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + g_free (path); + + if (!plugin) { + nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ()); + continue; + } + + if (!g_module_symbol (plugin, "nm_device_factory_get_type", (gpointer) (&type_func))) { + nm_log_warn (LOGD_HW, "(%s): failed to find device factory: %s", item, g_module_error ()); + g_module_close (plugin); + continue; + } + + /* Make sure we don't double-load plugins */ + plugin_type = type_func (); + for (iter = list; iter; iter = g_slist_next (iter)) { + PluginInfo *candidate = iter->data; + + if (plugin_type == candidate->t) { + info = candidate; + break; + } + } + if (info) { + g_module_close (plugin); + continue; + } + + if (!g_module_symbol (plugin, "nm_device_factory_create_device", (gpointer) (&create_func))) { + nm_log_warn (LOGD_HW, "(%s): failed to find device creator: %s", item, g_module_error ()); + g_module_close (plugin); + continue; + } + + info = g_malloc0 (sizeof (*info)); + info->create_func = create_func; + info->t = plugin_type; + + /* Grab priority; higher number equals higher priority */ + if (g_module_symbol (plugin, "nm_device_factory_get_priority", (gpointer) (&priority_func))) + info->priority = priority_func (); + else { + nm_log_dbg (LOGD_HW, "(%s): failed to find device factory priority func: %s", + item, g_module_error ()); + } + + g_module_make_resident (plugin); + list = g_slist_insert_sorted (list, info, (GCompareFunc) plugin_sort); + + nm_log_info (LOGD_HW, "Loaded device factory: %s", g_module_name (plugin)); + }; + g_dir_close (dir); + + /* Ditch the priority info and copy the factory functions to our private data */ + for (iter = list; iter; iter = g_slist_next (iter)) { + PluginInfo *info = iter->data; + + priv->factories = g_slist_append (priv->factories, info->create_func); + g_free (info); + } + g_slist_free (list); +} + +static gboolean +is_wireless (GUdevDevice *device) +{ + const char *tmp; + + /* Check devtype, newer kernels (2.6.32+) have this */ + tmp = g_udev_device_get_property (device, "DEVTYPE"); + if (g_strcmp0 (tmp, "wlan") == 0) + return TRUE; + + /* Otherwise hit up WEXT directly */ + return wifi_utils_is_wifi (g_udev_device_get_name (device), + g_udev_device_get_sysfs_path (device)); +} + +static gboolean +is_olpc_mesh (GUdevDevice *device) +{ + const gchar *prop = g_udev_device_get_property (device, "ID_NM_OLPC_MESH"); + return (prop != NULL); +} + +static gboolean +is_infiniband (GUdevDevice *device) +{ + gint etype = g_udev_device_get_sysfs_attr_as_int (device, "type"); + return etype == ARPHRD_INFINIBAND; +} + +static gboolean +is_bond (int ifindex) +{ + return (nm_system_get_iface_type (ifindex, NULL) == NM_IFACE_TYPE_BOND); +} + +static gboolean +is_vlan (int ifindex) +{ + return (nm_system_get_iface_type (ifindex, NULL) == NM_IFACE_TYPE_VLAN); +} + static void udev_device_added_cb (NMUdevManager *udev_mgr, GUdevDevice *udev_device, - NMDeviceCreatorFn creator_fn, + const char *iface, + const char *sysfs_path, + const char *driver, + int ifindex, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); - GObject *device; - guint32 ifindex; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMDevice *device = NULL; + GSList *iter; + GError *error = NULL; - ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX"); - if (find_device_by_ifindex (self, ifindex)) + g_return_if_fail (udev_device != NULL); + g_return_if_fail (iface != NULL); + g_return_if_fail (sysfs_path != NULL); + g_return_if_fail (driver != NULL); + g_return_if_fail (ifindex >= 0); + + device = find_device_by_ifindex (self, ifindex); + if (device) { + /* If it's a virtual device we may need to update its UDI */ + if (nm_system_get_iface_type (ifindex, iface) != NM_IFACE_TYPE_UNSPEC) + g_object_set (G_OBJECT (device), NM_DEVICE_UDI, sysfs_path, NULL); return; + } + + /* Try registered device factories */ + for (iter = priv->factories; iter; iter = g_slist_next (iter)) { + NMDeviceFactoryCreateFunc create_func = iter->data; + + g_clear_error (&error); + device = (NMDevice *) create_func (udev_device, sysfs_path, iface, driver, &error); + if (device && NM_IS_DEVICE (device)) { + g_assert_no_error (error); + break; /* success! */ + } + + if (error) { + nm_log_warn (LOGD_HW, "%s: factory failed to create device: (%d) %s", + sysfs_path, + error ? error->code : -1, + error ? error->message : "(unknown)"); + g_clear_error (&error); + return; + } + } + + if (device == NULL) { + if (is_olpc_mesh (udev_device)) /* must be before is_wireless */ + device = nm_device_olpc_mesh_new (sysfs_path, iface, driver); + else if (is_wireless (udev_device)) + device = nm_device_wifi_new (sysfs_path, iface, driver); + else if (is_infiniband (udev_device)) + device = nm_device_infiniband_new (sysfs_path, iface, driver); + else if (is_bond (ifindex)) + device = nm_device_bond_new (sysfs_path, iface); + else if (is_vlan (ifindex)) { + int parent_ifindex = -1; + NMDevice *parent; + + /* Have to find the parent device */ + if (nm_system_get_iface_vlan_info (ifindex, &parent_ifindex, NULL)) { + parent = find_device_by_ifindex (self, parent_ifindex); + if (parent) + device = nm_device_vlan_new (sysfs_path, iface, parent); + else { + /* If udev signaled the VLAN interface before it signaled + * the VLAN's parent at startup we may not know about the + * parent device yet. But we'll find it on the second pass + * from nm_manager_start(). + */ + nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", iface); + } + } else + nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", iface); + } else + device = nm_device_ethernet_new (sysfs_path, iface, driver); + } - device = creator_fn (udev_mgr, udev_device, manager_sleeping (self)); if (device) - add_device (self, NM_DEVICE (device)); + add_device (self, device); } static void @@ -1855,7 +2343,7 @@ nm_manager_get_act_request_by_path (NMManager *manager, if (!req) continue; - ac_path = nm_act_request_get_active_connection_path (req); + ac_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (req)); if (!strcmp (path, ac_path)) { *device = NM_DEVICE (iter->data); return req; @@ -1865,7 +2353,7 @@ nm_manager_get_act_request_by_path (NMManager *manager, return NULL; } -static const char * +static NMActiveConnection * internal_activate_device (NMManager *manager, NMDevice *device, NMConnection *connection, @@ -1873,20 +2361,18 @@ internal_activate_device (NMManager *manager, gboolean user_requested, gulong sender_uid, gboolean assumed, + NMActiveConnection *master, GError **error) { NMActRequest *req; - NMDeviceInterface *dev_iface; gboolean success; g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); g_return_val_if_fail (NM_IS_DEVICE (device), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - dev_iface = NM_DEVICE_INTERFACE (device); - /* Ensure the requested connection is compatible with the device */ - if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error)) + if (!nm_device_check_connection_compatible (device, connection, error)) return NULL; /* Tear down any existing connection */ @@ -1903,14 +2389,322 @@ internal_activate_device (NMManager *manager, user_requested, sender_uid, assumed, - (gpointer) device); - success = nm_device_interface_activate (dev_iface, req, error); + (gpointer) device, + master); + success = nm_device_activate (device, req, error); g_object_unref (req); - return success ? nm_act_request_get_active_connection_path (req) : NULL; + return success ? NM_ACTIVE_CONNECTION (req) : NULL; +} + +/** + * find_master: + * @self: #NMManager object + * @connection: the #NMConnection to find the master connection and device for + * @device: the #NMDevice, if any, which will activate @connection + * @out_master_connection: on success, the master connection of @connection if + * that master connection was found + * @out_master_device: on success, the master device of @connection if that + * master device was found + * + * Given an #NMConnection, attempts to find its master connection and/or its + * master device. This function may return a master connection, a master device, + * or both. If only a connection is returned, that master connection is not + * currently active on any device. If only a device is returned, that device + * is not currently activated with any connection. If both are returned, then + * the device is currently activated or activating with the returned master + * connection. + * + * Returns: %TRUE if the master device and/or connection could be found or if + * the connection did not require a master, %FALSE otherwise + **/ +static gboolean +find_master (NMManager *self, + NMConnection *connection, + NMDevice *device, + NMConnection **out_master_connection, + NMDevice **out_master_device) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSettingConnection *s_con; + const char *master; + NMDevice *master_device = NULL; + NMConnection *master_connection = NULL; + GSList *iter, *connections = NULL; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + master = nm_setting_connection_get_master (s_con); + + if (master == NULL) + return TRUE; /* success, but no master */ + + /* Try as an interface name first */ + master_device = find_device_by_ip_iface (self, master); + if (master_device) { + /* A device obviously can't be its own master */ + if (master_device == device) + return FALSE; + } else { + /* Try master as a connection UUID */ + master_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, master); + if (master_connection) { + /* Check if the master connection is activated on some device already */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *candidate = NM_DEVICE (iter->data); + + if (candidate == device) + continue; + + if (nm_device_get_connection (candidate) == master_connection) { + master_device = candidate; + break; + } + } + } else { + /* Might be a virtual interface that hasn't been created yet, so + * look through the interface names of connections that require + * virtual interfaces and see if one of their virtual interface + * names matches the master. + */ + connections = nm_settings_get_connections (priv->settings); + for (iter = connections; iter && !master_connection; iter = g_slist_next (iter)) { + NMConnection *candidate = iter->data; + char *vname; + + if (connection_needs_virtual_device (candidate)) { + vname = get_virtual_iface_name (self, candidate, NULL); + if (g_strcmp0 (master, vname) == 0) + master_connection = candidate; + g_free (vname); + } + } + g_slist_free (connections); + } + } + + if (out_master_connection) + *out_master_connection = master_connection; + if (out_master_device) + *out_master_device = master_device; + + return master_device || master_connection; +} + +static gboolean +is_compatible_with_slave (NMConnection *master, NMConnection *slave) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (master, FALSE); + g_return_val_if_fail (slave, FALSE); + + s_con = nm_connection_get_setting_connection (slave); + g_assert (s_con); + + return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con)); +} + +/** + * ensure_master_active_connection: + * + * @self: the #NMManager + * @dbus_sender: if the request was initiated by a user via D-Bus, the + * dbus sender name of the client that requested the activation; for auto + * activated connections use %NULL + * @connection: the connection that should depend on @master_connection + * @device: the #NMDevice, if any, which will activate @connection + * @master_connection: the master connection + * @master_device: the master device + * @error: the error, if an error occurred + * + * Determines whether a given #NMConnection depends on another connection to + * be activated, and if so, finds that master connection or creates it. + * + * Returns: the master #NMActiveConnection that the caller should depend on, or + * %NULL if an error occurred + */ +static NMActiveConnection * +ensure_master_active_connection (NMManager *self, + const char *dbus_sender, + NMConnection *connection, + NMDevice *device, + NMConnection *master_connection, + NMDevice *master_device, + GError **error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMActiveConnection *master_ac = NULL; + NMDeviceState master_state; + GSList *iter; + + g_assert (connection); + g_assert (master_connection || master_device); + + /* If the master device isn't activated then we need to activate it using + * compatible connection. If it's already activating we can just proceed. + */ + if (master_device) { + /* If we're passed a connection and a device, we require that connection + * be already activated on the device, eg returned from find_master(). + */ + if (master_connection) + g_assert (nm_device_get_connection (master_device) == master_connection); + + master_state = nm_device_get_state (master_device); + if ( (master_state == NM_DEVICE_STATE_ACTIVATED) + || nm_device_is_activating (master_device)) { + /* Device already using master_connection */ + return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device)); + } + + /* If the device is disconnected, find a compabile connection and + * activate it on the device. + */ + if (master_state == NM_DEVICE_STATE_DISCONNECTED) { + GSList *connections; + + g_assert (master_connection == NULL); + + /* Find a compatible connection and activate this device using it */ + connections = nm_settings_get_connections (priv->settings); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + /* Ensure eg bond slave and the candidate master is a bond master */ + if (!is_compatible_with_slave (candidate, connection)) + continue; + + if (nm_device_check_connection_compatible (master_device, candidate, NULL)) { + master_ac = nm_manager_activate_connection (self, + candidate, + NULL, + nm_device_get_path (master_device), + dbus_sender, + error); + g_slist_free (connections); + return master_ac; + } + } + g_slist_free (connections); + + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_CONNECTION, + "No compatible connection found for master device %s.", + nm_device_get_iface (master_device)); + return NULL; + } + + /* Otherwise, the device is unmanaged, unavailable, or disconnecting */ + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNMANAGED_DEVICE, + "Master device %s unmanaged or not available for activation", + nm_device_get_iface (master_device)); + } else if (master_connection) { + gboolean found_device = FALSE; + + /* Find a compatible device and activate it using this connection */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *candidate = NM_DEVICE (iter->data); + + if (candidate == device) { + /* A device obviously can't be its own master */ + continue; + } + + if (!nm_device_check_connection_compatible (candidate, master_connection, NULL)) + continue; + + found_device = TRUE; + master_state = nm_device_get_state (candidate); + if (master_state != NM_DEVICE_STATE_DISCONNECTED) + continue; + + return nm_manager_activate_connection (self, + master_connection, + NULL, + nm_device_get_path (candidate), + dbus_sender, + error); + } + + /* Device described by master_connection may be a virtual one that's + * not created yet. + */ + if (!found_device && connection_needs_virtual_device (master_connection)) { + return nm_manager_activate_connection (self, + master_connection, + NULL, + NULL, + dbus_sender, + error); + } + + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "No compatible disconnected device found for master connection %s.", + nm_connection_get_uuid (master_connection)); + } else + g_assert_not_reached (); + + return NULL; +} + +static NMActiveConnection * +activate_vpn_connection (NMManager *self, + NMConnection *connection, + const char *specific_object, + const char *device_path, + gulong sender_uid, + GError **error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMActRequest *parent_req = NULL; + NMDevice *device = NULL; + GSList *iter; + + if (specific_object) { + /* Find the specifc connection the client requested we use */ + parent_req = nm_manager_get_act_request_by_path (self, specific_object, &device); + if (!parent_req) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, + "Base connection for VPN connection not active."); + return NULL; + } + } else { + /* Just find the current default connection */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *candidate = NM_DEVICE (iter->data); + NMActRequest *candidate_req; + + candidate_req = nm_device_get_act_request (candidate); + if (candidate_req && nm_active_connection_get_default (NM_ACTIVE_CONNECTION (candidate_req))) { + device = candidate; + parent_req = candidate_req; + break; + } + } + } + + if (!device || !parent_req) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Could not find source connection, or the source connection had no active device."); + return NULL; + } + + return nm_vpn_manager_activate_connection (priv->vpn_manager, + connection, + device, + nm_active_connection_get_path (NM_ACTIVE_CONNECTION (parent_req)), + TRUE, + sender_uid, + error); } -const char * +NMActiveConnection * nm_manager_activate_connection (NMManager *manager, NMConnection *connection, const char *specific_object, @@ -1920,11 +2714,13 @@ nm_manager_activate_connection (NMManager *manager, { NMManagerPrivate *priv; NMDevice *device = NULL; - NMSettingConnection *s_con; - NMVPNConnection *vpn_connection; - const char *path = NULL; gulong sender_uid = 0; DBusError dbus_error; + NMDeviceState state; + char *iface; + NMDevice *master_device = NULL; + NMConnection *master_connection = NULL; + NMActiveConnection *master_ac = NULL; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); @@ -1948,87 +2744,141 @@ nm_manager_activate_connection (NMManager *manager, } } - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); + /* VPN ? */ + if (nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) + return activate_vpn_connection (manager, connection, specific_object, device_path, sender_uid, error); - if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) { - NMActRequest *parent_req = NULL; - - /* VPN connection */ + /* Device-based connection */ + if (device_path) { + device = nm_manager_get_device_by_path (manager, device_path); + if (!device) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Device not found"); + return NULL; + } - if (specific_object) { - /* Find the specifc connection the client requested we use */ - parent_req = nm_manager_get_act_request_by_path (manager, specific_object, &device); - if (!parent_req) { - g_set_error (error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, - "%s", "Base connection for VPN connection not active."); + /* If it's a virtual interface make sure the device given by the + * path matches the connection's interface details. + */ + if (connection_needs_virtual_device (connection)) { + iface = get_virtual_iface_name (manager, connection, NULL); + if (!iface) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Failed to determine connection's virtual interface name"); + return NULL; + } else if (g_strcmp0 (iface, nm_device_get_ip_iface (device)) != 0) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Device given by path did not match connection's virtual interface name"); + g_free (iface); return NULL; } - } else { - GSList *iter; + g_free (iface); + } + } else { + /* Virtual connections (VLAN, bond, etc) may not specify a device + * path because the device may not be created yet, or it be given + * by the connection's properties instead. Find the device the + * connection refers to, or create it if needed. + */ + if (!connection_needs_virtual_device (connection)) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "This connection requires an existing device."); + return NULL; + } - /* Just find the current default connection */ - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = NM_DEVICE (iter->data); - NMActRequest *candidate_req; + iface = get_virtual_iface_name (manager, connection, NULL); + if (!iface) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Failed to determine connection's virtual interface name"); + return NULL; + } - candidate_req = nm_device_get_act_request (candidate); - if (candidate_req && nm_act_request_get_default (candidate_req)) { - device = candidate; - parent_req = candidate_req; - break; - } + device = find_device_by_ip_iface (manager, iface); + if (!device) { + /* Create it */ + device = system_create_virtual_device (manager, connection); + if (!device) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Failed to create virtual interface"); + return NULL; } - } - if (!device || !parent_req) { - g_set_error (error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "%s", "Could not find source connection, or the source connection had no active device."); - return NULL; + /* A newly created device, if allowed to be managed by NM, will be + * in the UNAVAILABLE state here. Since we want to use it right + * away, we transition it immediately to DISCONNECTED. + */ + if ( nm_device_is_available (device) + && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) { + nm_device_state_changed (device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_NONE); + } } + } - vpn_connection = nm_vpn_manager_activate_connection (priv->vpn_manager, - connection, - device, - nm_act_request_get_active_connection_path (parent_req), - TRUE, - sender_uid, - error); - if (vpn_connection) - path = nm_vpn_connection_get_active_connection_path (vpn_connection); - } else { - NMDeviceState state; + state = nm_device_get_state (device); + if (state < NM_DEVICE_STATE_DISCONNECTED) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE, + "Device not managed by NetworkManager or unavailable"); + return NULL; + } - /* Device-based connection */ - device = nm_manager_get_device_by_path (manager, device_path); - if (!device) { - g_set_error (error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "%s", "Device not found"); + /* Try to find the master connection/device if the connection has a dependency */ + if (!find_master (manager, connection, device, &master_connection, &master_device)) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Master connection not found or invalid"); + return NULL; + } + + /* Ensure there's a master active connection the new connection we're + * activating can depend on. + */ + if (master_connection || master_device) { + if (master_connection) { + nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master connection '%s'", + nm_connection_get_id (connection), + nm_connection_get_id (master_connection)); + } + if (master_device) { + nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master device '%s'", + nm_connection_get_id (connection), + nm_device_get_ip_iface (master_device)); + } + + /* Ensure eg bond slave and the candidate master is a bond master */ + if (master_connection && !is_compatible_with_slave (master_connection, connection)) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, + "The master connection was not compatible"); return NULL; } - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); - if (state < NM_DEVICE_STATE_DISCONNECTED) { - g_set_error (error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE, - "%s", "Device not managed by NetworkManager or unavailable"); + master_ac = ensure_master_active_connection (manager, + dbus_sender, + connection, + device, + master_connection, + master_device, + error); + if (!master_ac) { + if (error) + g_assert (*error); return NULL; } - path = internal_activate_device (manager, - device, - connection, - specific_object, - dbus_sender ? TRUE : FALSE, - dbus_sender ? sender_uid : 0, - FALSE, - error); + nm_log_dbg (LOGD_CORE, "Activation of '%s' depends on active connection %s", + nm_connection_get_id (connection), + nm_active_connection_get_path (master_ac)); } - return path; + return internal_activate_device (manager, + device, + connection, + specific_object, + dbus_sender ? TRUE : FALSE, + dbus_sender ? sender_uid : 0, + FALSE, + master_ac, + error); } /* @@ -2042,7 +2892,7 @@ pending_activate (NMManager *self, PendingActivation *pending) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMSettingsConnection *connection; - const char *path = NULL; + NMActiveConnection *ac = NULL; GError *error = NULL; char *sender; @@ -2058,24 +2908,25 @@ pending_activate (NMManager *self, PendingActivation *pending) sender = dbus_g_method_get_sender (pending->context); g_assert (sender); - path = nm_manager_activate_connection (self, - NM_CONNECTION (connection), - pending->specific_object_path, - pending->device_path, - sender, - &error); + ac = nm_manager_activate_connection (self, + NM_CONNECTION (connection), + pending->specific_object_path, + pending->device_path, + sender, + &error); g_free (sender); - if (!path) { + if (ac) + g_object_notify (G_OBJECT (pending->manager), NM_MANAGER_ACTIVE_CONNECTIONS); + else { nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s", pending->connection_path, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); - } else - g_object_notify (G_OBJECT (pending->manager), NM_MANAGER_ACTIVE_CONNECTIONS); + } out: - pending_activation_destroy (pending, error, path); + pending_activation_destroy (pending, error, ac); g_clear_error (&error); } @@ -2207,7 +3058,7 @@ nm_manager_deactivate_connection (NMManager *manager, if (!req) continue; - if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) { + if (!strcmp (connection_path, nm_active_connection_get_path (NM_ACTIVE_CONNECTION (req)))) { nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, reason); @@ -2286,7 +3137,7 @@ impl_manager_deactivate_connection (NMManager *self, req = nm_device_get_act_request (NM_DEVICE (iter->data)); if (req) - req_path = nm_act_request_get_active_connection_path (req); + req_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (req)); if (req_path && !strcmp (active_path, req_path)) { connection = nm_act_request_get_connection (req); @@ -2384,7 +3235,6 @@ do_sleep_wake (NMManager *self) for (i = 0; i < RFKILL_TYPE_MAX; i++) { RadioState *rstate = &priv->radio_states[i]; gboolean enabled = radio_enabled_for_rstate (rstate, TRUE); - RfKillType devtype = RFKILL_TYPE_UNKNOWN; if (rstate->desc) { nm_log_dbg (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)", @@ -2392,13 +3242,12 @@ do_sleep_wake (NMManager *self) rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled); } - g_object_get (G_OBJECT (device), NM_DEVICE_INTERFACE_RFKILL_TYPE, &devtype, NULL); - if (devtype == rstate->rtype) - nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled); + if (nm_device_get_rfkill_type (device) == rstate->rtype) + nm_device_set_enabled (device, enabled); } nm_device_clear_autoconnect_inhibit (device); - if (nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) + if (nm_device_spec_match_list (device, unmanaged_specs)) nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); else nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); @@ -2823,6 +3672,20 @@ nm_manager_start (NMManager *self) nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); + + /* Query devices again to ensure that we catch all virtual interfaces (like + * VLANs) that require a parent. If during the first pass the VLAN + * interface was detected first, the parent wouldn't exist yet and creating + * the VLAN would fail. The second query ensures that we'll have a valid + * parent for the VLAN during the second pass. + */ + nm_udev_manager_query_devices (priv->udev_mgr); + + /* + * Connections added before the manager is started do not emit + * connection-added signals thus devices have to be created manually. + */ + system_create_virtual_devices (self); } static gboolean @@ -2857,6 +3720,23 @@ handle_firmware_changed (gpointer user_data) return FALSE; } +#if WITH_CONCHECK +static void +connectivity_changed (NMConnectivity *connectivity, + GParamSpec *pspec, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + gboolean connected; + + connected = nm_connectivity_get_connected (connectivity); + nm_log_dbg (LOGD_CORE, "connectivity checking indicates %s", + connected ? "CONNECTED" : "NOT CONNECTED"); + + nm_manager_update_state (self); +} +#endif /* WITH_CONCHECK */ + static void firmware_dir_changed (GFileMonitor *monitor, GFile *file, @@ -3058,6 +3938,9 @@ nm_manager_new (NMSettings *settings, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, gboolean initial_wimax_enabled, + const gchar *connectivity_uri, + gint connectivity_interval, + const gchar *connectivity_response, GError **error) { NMManagerPrivate *priv; @@ -3073,6 +3956,13 @@ nm_manager_new (NMSettings *settings, priv = NM_MANAGER_GET_PRIVATE (singleton); +#if WITH_CONCHECK + priv->connectivity = nm_connectivity_new (connectivity_uri, connectivity_interval, connectivity_response); + + g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_CONNECTED, + G_CALLBACK (connectivity_changed), singleton); +#endif + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); g_assert (bus); dbus_connection = dbus_g_connection_get_connection (bus); @@ -3099,13 +3989,13 @@ nm_manager_new (NMSettings *settings, g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (connections_changed), singleton); + G_CALLBACK (connection_added), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, - G_CALLBACK (connections_changed), singleton); + G_CALLBACK (connection_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, - G_CALLBACK (connections_changed), singleton); + G_CALLBACK (connection_removed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, - G_CALLBACK (connections_changed), singleton); + G_CALLBACK (connection_changed), singleton); dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton)); @@ -3171,6 +4061,13 @@ dispose (GObject *object) TRUE); } +#if WITH_CONCHECK + if (priv->connectivity) { + g_object_unref (priv->connectivity); + priv->connectivity = NULL; + } +#endif + g_free (priv->hostname); g_object_unref (priv->settings); @@ -3224,6 +4121,8 @@ dispose (GObject *object) g_object_unref (priv->fw_monitor); } + g_slist_free (priv->factories); + if (priv->timestamp_update_id) { g_source_remove (priv->timestamp_update_id); priv->timestamp_update_id = 0; @@ -3436,7 +4335,7 @@ periodic_update_active_connection_timestamps (gpointer user_data) req = nm_manager_get_act_request_by_path (manager, active_path, &device); if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)), - (guint64) time (NULL)); + (guint64) time (NULL), FALSE); else { /* The connection is probably VPN */ NMVPNConnection *vpn_con; @@ -3444,7 +4343,7 @@ periodic_update_active_connection_timestamps (gpointer user_data) vpn_con = nm_vpn_manager_get_vpn_connection_for_active (priv->vpn_manager, active_path); if (vpn_con && nm_vpn_connection_get_vpn_state (vpn_con) == NM_VPN_CONNECTION_STATE_ACTIVATED) nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_vpn_connection_get_connection (vpn_con)), - (guint64) time (NULL)); + (guint64) time (NULL), FALSE); } } @@ -3570,6 +4469,8 @@ nm_manager_init (NMManager *manager) KERNEL_FIRMWARE_DIR); } + load_device_factories (manager); + /* Update timestamps in active connections */ priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager); } diff --git a/src/nm-manager.h b/src/nm-manager.h index b044971f..58ba4605 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -26,7 +26,6 @@ #include <glib-object.h> #include <dbus/dbus-glib.h> #include "nm-device.h" -#include "nm-device-interface.h" #include "nm-settings.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) @@ -36,6 +35,19 @@ #define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_MANAGER)) #define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass)) +typedef enum { + NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, /*< nick=UnknownConnection >*/ + NM_MANAGER_ERROR_UNKNOWN_DEVICE, /*< nick=UnknownDevice >*/ + NM_MANAGER_ERROR_UNMANAGED_DEVICE, /*< nick=UnmanagedDevice >*/ + NM_MANAGER_ERROR_SYSTEM_CONNECTION, /*< nick=SystemConnection >*/ + NM_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, /*< nick=ConnectionNotActive >*/ + NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, /*< nick=AlreadyAsleepOrAwake >*/ + NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, /*< nick=AlreadyEnabledOrDisabled >*/ + NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, /*< nick=UnsupportedConnectionType >*/ + NM_MANAGER_ERROR_DEPENDENCY_FAILED, /*< nick=DependencyFailed >*/ +} NMManagerError; + #define NM_MANAGER_VERSION "version" #define NM_MANAGER_STATE "state" #define NM_MANAGER_NETWORKING_ENABLED "networking-enabled" @@ -73,7 +85,10 @@ NMManager *nm_manager_new (NMSettings *settings, gboolean initial_net_enabled, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, - gboolean initial_wimax_enabled, + gboolean initial_wimax_enabled, + const gchar *connectivity_uri, + gint connectivity_interval, + const gchar *connectivity_response, GError **error); NMManager *nm_manager_get (void); @@ -84,12 +99,16 @@ void nm_manager_start (NMManager *manager); GSList *nm_manager_get_devices (NMManager *manager); -const char * nm_manager_activate_connection (NMManager *manager, - NMConnection *connection, - const char *specific_object, - const char *device_path, - const char *dbus_sender, /* NULL if automatic */ - GError **error); +NMDevice *nm_manager_get_device_by_master (NMManager *manager, + const char *master, + const char *driver); + +NMActiveConnection *nm_manager_activate_connection (NMManager *manager, + NMConnection *connection, + const char *specific_object, + const char *device_path, + const char *dbus_sender, /* NULL if automatic */ + GError **error); gboolean nm_manager_deactivate_connection (NMManager *manager, const char *connection_path, diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c index e91a1ff2..974121ad 100644 --- a/src/nm-netlink-compat.c +++ b/src/nm-netlink-compat.c @@ -20,7 +20,13 @@ #include <config.h> #include <glib.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <linux/if_vlan.h> +#include <linux/sockios.h> +#include "nm-logging.h" #include "nm-netlink-compat.h" #ifndef HAVE_LIBNL1 @@ -102,4 +108,135 @@ nl_compat_error (int err) return -err; } + +int +rtnl_link_vlan_get_id (struct rtnl_link *l) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + strcpy (if_request.device1, if_name); + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + if_request.cmd = GET_VLAN_VID_CMD; + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't get vlan id for %s.", if_name); + goto err_out; + } + + close(fd); + return if_request.u.VID; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_flags (struct rtnl_link *l, unsigned int flags) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_FLAG_CMD; + if_request.u.flag = flags; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set flag in device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_ingress_map (struct rtnl_link *l, int from, uint32_t to) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD; + if_request.u.skb_priority = from; + if_request.vlan_qos = to; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set ingress map on device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} + +int +rtnl_link_vlan_set_egress_map (struct rtnl_link *l, int from, uint32_t to) +{ + int fd; + struct vlan_ioctl_args if_request; + char *if_name = NULL; + + if ((if_name = rtnl_link_get_name (l)) == NULL) + return -1; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, if_name); + if_request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD; + if_request.u.skb_priority = from; + if_request.vlan_qos = to; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set egress map on device %s.", if_name); + goto err_out; + } + + close(fd); + return 0; +err_out: + close(fd); + return -1; +} #endif diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h index af21fb9a..eb0926ad 100644 --- a/src/nm-netlink-compat.h +++ b/src/nm-netlink-compat.h @@ -16,6 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2011 Caixa Magica Software. + * Copyright (C) 2011 - 2012 Red Hat, Inc. */ #ifndef NM_NETLINK_COMPAT_H @@ -68,7 +69,7 @@ __rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache) /* functions with similar prototypes */ #define nlmsg_datalen nlmsg_len -#endif +#endif /* HAVE_LIBNL2 */ /* libnl-1.0 compat functions */ @@ -202,6 +203,79 @@ __nl_cache_include (struct nl_cache *cache, struct nl_object *obj, change_func_t #define NLE_NOACCESS 27 #define NLE_PERM 28 #define NLE_PKTLOC_FILE 29 -#endif + +#endif /* HAVE_LIBNL1 */ + +/* Stuff that only libnl3 has */ +#if defined(HAVE_LIBNL1) || defined(HAVE_LIBNL2) + +static inline int +rtnl_link_bond_add (struct nl_sock *h, const char *name, void *data) +{ + /* Bonding only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline int +rtnl_link_get_kernel (struct nl_sock *h, int f, const char *name, struct rtnl_link **out_link) +{ + /* Bonding only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline char * +rtnl_link_get_type (struct rtnl_link *rtnl_link) +{ + /* Bonding only in libnl3 */ + return NULL; +} + +static inline int +rtnl_link_bond_enslave_ifindex (struct nl_sock *h, int master_ifidx, int slave_ifidx) +{ + /* Bonding only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline int +rtnl_link_bond_release_ifindex (struct nl_sock *h, int slave_ifidx) +{ + /* Bonding only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline int +rtnl_link_vlan_set_id (struct rtnl_link *l, int id) +{ + /* VLAN only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +int rtnl_link_vlan_get_id (struct rtnl_link *l); +int rtnl_link_vlan_set_flags (struct rtnl_link *l, unsigned int flags); +int rtnl_link_vlan_set_ingress_map (struct rtnl_link *l, int from, uint32_t to); +int rtnl_link_vlan_set_egress_map (struct rtnl_link *l, int from, uint32_t to); + +static inline int +rtnl_link_set_type (struct rtnl_link *l, const char *type) +{ + /* Operation only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline int +rtnl_link_add (struct nl_sock *sk, struct rtnl_link *l, int flags) +{ + /* Operation only in libnl3 */ + return -NLE_OPNOTSUPP; +} + +static inline int +rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *l) +{ + /* Operation only in libnl3 */ + return -NLE_OPNOTSUPP; +} +#endif /* HAVE_LIBNL1 || HAVE_LIBNL2 */ #endif /* NM_NETLINK_COMPAT_H */ diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c index 9b8dac5c..29a21e3c 100644 --- a/src/nm-netlink-monitor.c +++ b/src/nm-netlink-monitor.c @@ -76,7 +76,6 @@ enum { NOTIFICATION = 0, CARRIER_ON, CARRIER_OFF, - ERROR, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -84,11 +83,60 @@ static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (NMNetlinkMonitor, nm_netlink_monitor, G_TYPE_OBJECT); +/****************************************************************/ + +static gboolean +detach_monitor (gpointer data) +{ + nm_log_warn (LOGD_HW, "detaching netlink event monitor"); + nm_netlink_monitor_detach (NM_NETLINK_MONITOR (data)); + return FALSE; +} + +static void +log_error_limited (NMNetlinkMonitor *monitor, guint32 code, const char *fmt, ...) +{ + static time_t rl_time = 0; + static guint32 rl_code = 0; + static guint32 rl_count = 0; + va_list args; + char *msg; + time_t now; + + g_return_if_fail (monitor != NULL); + + now = time (NULL); + + if ((code != rl_code) || (now > rl_time + 10)) { + va_start (args, fmt); + msg = g_strdup_vprintf (fmt, args); + va_end (args); + + nm_log_warn (LOGD_HW, "error monitoring device for netlink events: %s\n", msg); + g_free (msg); + + rl_time = now; + rl_code = code; + rl_count = 0; + } + + rl_count++; + if (rl_count > 100) { + /* Broken drivers will sometimes cause a flood of netlink errors. + * rh #459205, novell #443429, lp #284507 + */ + nm_log_warn (LOGD_HW, "excessive netlink errors ocurred, disabling netlink monitor."); + nm_log_warn (LOGD_HW, "link change events will not be processed."); + g_idle_add_full (G_PRIORITY_HIGH, detach_monitor, monitor, NULL); + } +} + +/****************************************************************/ + static void link_msg_handler (struct nl_object *obj, void *arg) { NMNetlinkMonitor *self = NM_NETLINK_MONITOR (arg); - GError *error; struct rtnl_link *filter; struct rtnl_link *link_obj; guint flags; @@ -96,12 +144,9 @@ link_msg_handler (struct nl_object *obj, void *arg) filter = rtnl_link_alloc (); if (!filter) { - error = g_error_new (NM_NETLINK_MONITOR_ERROR, - NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, - _("error processing netlink message: %s"), - nl_geterror (ENOMEM)); - g_signal_emit (self, signals[ERROR], 0, error); - g_error_free (error); + log_error_limited (self, NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, + _("error processing netlink message: %s"), + nl_geterror (ENOMEM)); return; } @@ -195,7 +240,6 @@ event_handler (GIOChannel *channel, { NMNetlinkMonitor *self = (NMNetlinkMonitor *) user_data; NMNetlinkMonitorPrivate *priv; - GError *error = NULL; int err; g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), TRUE); @@ -204,22 +248,17 @@ event_handler (GIOChannel *channel, g_return_val_if_fail (priv->event_id > 0, TRUE); if (io_condition & ERROR_CONDITIONS) { - const char *err_msg; + const char *err_msg = _("error occurred while waiting for data on socket"); int err_code = 0; socklen_t err_len = sizeof (err_code); /* Grab error information */ if (getsockopt (g_io_channel_unix_get_fd (channel), - SOL_SOCKET, SO_ERROR, (void *) &err_code, &err_len)) + SOL_SOCKET, SO_ERROR, + (void *) &err_code, &err_len) == 0) err_msg = strerror (err_code); - else - err_msg = _("error occurred while waiting for data on socket"); - error = g_error_new (NM_NETLINK_MONITOR_ERROR, - NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA, - "%s", err_msg); - g_signal_emit (self, signals[ERROR], 0, error); - g_error_free (error); + log_error_limited (self, NM_NETLINK_MONITOR_ERROR_WAITING_FOR_SOCKET_DATA, "%s", err_msg); return TRUE; } else if (io_condition & DISCONNECT_CONDITIONS) return FALSE; @@ -229,12 +268,9 @@ event_handler (GIOChannel *channel, /* Process the netlink messages */ err = nl_recvmsgs_default (priv->nlh_event); if (err < 0) { - error = g_error_new (NM_NETLINK_MONITOR_ERROR, - NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE, - _("error processing netlink message: %s"), - nl_geterror (err)); - g_signal_emit (self, signals[ERROR], 0, error); - g_error_free (error); + log_error_limited (self, NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE, + _("error processing netlink message: %s"), + nl_geterror (err)); } return TRUE; @@ -578,20 +614,18 @@ deferred_emit_carrier_state (gpointer user_data) return FALSE; } -gboolean -nm_netlink_monitor_request_status (NMNetlinkMonitor *self, GError **error) +void +nm_netlink_monitor_request_status (NMNetlinkMonitor *self) { NMNetlinkMonitorPrivate *priv; - g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); + g_return_if_fail (NM_IS_NETLINK_MONITOR (self)); priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); /* Schedule the carrier state emission */ if (!priv->request_status_id) priv->request_status_id = g_idle_add (deferred_emit_carrier_state, self); - - return TRUE; } typedef struct { @@ -778,10 +812,26 @@ NMNetlinkMonitor * nm_netlink_monitor_get (void) { static NMNetlinkMonitor *singleton = NULL; + GError *error = NULL; - if (!singleton) - singleton = NM_NETLINK_MONITOR (g_object_new (NM_TYPE_NETLINK_MONITOR, NULL)); - else + if (!singleton) { + singleton = (NMNetlinkMonitor *) g_object_new (NM_TYPE_NETLINK_MONITOR, NULL); + g_return_val_if_fail (singleton != NULL, NULL); + + if (nm_netlink_monitor_open_connection (singleton, &error)) { + nm_netlink_monitor_attach (singleton); + /* Request initial status of cards */ + nm_netlink_monitor_request_status (singleton); + } else { + nm_log_warn (LOGD_HW, "Failed to connect to netlink: (%d) %s", + error ? error->code : 0, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + + g_object_unref (singleton); + singleton = NULL; + } + } else g_object_ref (singleton); return singleton; @@ -860,14 +910,6 @@ nm_netlink_monitor_class_init (NMNetlinkMonitorClass *monitor_class) G_STRUCT_OFFSET (NMNetlinkMonitorClass, carrier_off), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - - signals[ERROR] = - g_signal_new ("error", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMNetlinkMonitorClass, error), - NULL, NULL, g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); } GQuark diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h index 5c1fa339..4e0787bd 100644 --- a/src/nm-netlink-monitor.h +++ b/src/nm-netlink-monitor.h @@ -58,7 +58,6 @@ typedef struct { void (*notification) (NMNetlinkMonitor *monitor, struct nl_msg *msg); void (*carrier_on) (NMNetlinkMonitor *monitor, int index); void (*carrier_off) (NMNetlinkMonitor *monitor, int index); - void (*error) (NMNetlinkMonitor *monitor, GError *error); } NMNetlinkMonitorClass; @@ -83,8 +82,8 @@ void nm_netlink_monitor_unsubscribe (NMNetlinkMonitor *monitor gboolean nm_netlink_monitor_request_ip6_info (NMNetlinkMonitor *monitor, GError **error); -gboolean nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor, - GError **error); +void nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor); + gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor, guint32 ifindex, guint32 *ifflags, diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index 4a62aa55..99aebcb8 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -165,45 +165,50 @@ nm_netlink_route_new (int ifindex, } /** - * nm_netlink_route_add: + * _route_add: * @route: the route to add + * @family: address family, either %AF_INET or %AF_INET6 + * @dest: the route destination address, either a struct in_addr or a struct + * in6_addr depending on @family + * @dest_prefix: the CIDR prefix of @dest + * @gateway: the gateway through which to reach @dest, if any; given as a + * struct in_addr or struct in6_addr depending on @family + * @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE * * Returns: zero if succeeded or the netlink error otherwise. **/ -int nm_netlink_route_add(struct rtnl_route * route, - int family, - const void * dest, /* in_addr or in6_addr */ - int dest_prefix, - const void * gateway, /* in_addr or in6_addr */ - int flags) +static int +_route_add (struct rtnl_route *route, + int family, + const void *dest, /* in_addr or in6_addr */ + int dest_prefix, + const void *gateway, /* in_addr or in6_addr */ + int flags) { - struct nl_sock * sk; - struct nl_addr * dest_addr, * gw_addr; - void * tmp_addr; + struct nl_sock *sk; + struct nl_addr *dest_addr, *gw_addr; + void *tmp_addr; int addrlen, err, log; - if(family == AF_INET) { - addrlen = sizeof(struct in_addr); + if (family == AF_INET) { + addrlen = sizeof (struct in_addr); log = LOGD_IP4; - } - else if (family == AF_INET6) { - addrlen = sizeof(struct in6_addr); + } else if (family == AF_INET6) { + addrlen = sizeof (struct in6_addr); log = LOGD_IP6; - } else { + } else g_assert_not_reached (); - } - - sk = nm_netlink_get_default_handle(); + sk = nm_netlink_get_default_handle (); /* Build up the destination address */ if (dest) { /* Copy to preserve const */ - tmp_addr = g_malloc0(addrlen); - memcpy(tmp_addr, dest, addrlen); + tmp_addr = g_malloc0 (addrlen); + memcpy (tmp_addr, dest, addrlen); dest_addr = nl_addr_build (family, tmp_addr, addrlen); - g_free(tmp_addr); + g_free (tmp_addr); g_return_val_if_fail (dest_addr != NULL, -NLE_INVAL); nl_addr_set_prefixlen (dest_addr, dest_prefix); @@ -214,20 +219,19 @@ int nm_netlink_route_add(struct rtnl_route * route, /* Build up the gateway address */ if (gateway) { - tmp_addr = g_malloc0(addrlen); - memcpy(tmp_addr, gateway, addrlen); + tmp_addr = g_malloc0 (addrlen); + memcpy (tmp_addr, gateway, addrlen); gw_addr = nl_addr_build (family, tmp_addr, addrlen); - g_free(tmp_addr); + g_free (tmp_addr); if (gw_addr) { nl_addr_set_prefixlen (gw_addr, 0); rtnl_route_set_gateway (route, gw_addr); rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - nl_addr_put(gw_addr); - } else { + nl_addr_put (gw_addr); + } else nm_log_err (LOGD_DEVICE | log, "Invalid gateway"); - } } err = rtnl_route_add (sk, route, flags); @@ -236,15 +240,54 @@ int nm_netlink_route_add(struct rtnl_route * route, if (err == -NLE_FAILURE) err = -NLE_OBJ_NOTFOUND; - if (err) - nm_log_warn (LOGD_DEVICE | log, - "Failed to add route %s", - nl_geterror(err)); - return err; } /** + * nm_netlink_route4_add: + * @route: the route to add + * @dest: the route destination address in network byte order + * @dest_prefix: the CIDR prefix of @dest + * @gateway: the gateway through which to reach @dest, if any, in network byte order + * @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE + * + * Adds an IPv4 route with the given parameters. + * + * Returns: zero if succeeded or the netlink error otherwise. + **/ +int +nm_netlink_route4_add (struct rtnl_route *route, + guint32 *dst, + int prefix, + guint32 *gw, + int flags) +{ + return _route_add (route, AF_INET, dst, prefix, gw, flags); +} + +/** + * nm_netlink_route6_add: + * @route: the route to add + * @dest: the route destination address + * @dest_prefix: the CIDR prefix of @dest + * @gateway: the gateway through which to reach @dest, if any + * @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE + * + * Adds an IPv6 route with the given parameters. + * + * Returns: zero if succeeded or the netlink error otherwise. + **/ +int +nm_netlink_route6_add (struct rtnl_route *route, + const struct in6_addr *dst, + int prefix, + const struct in6_addr *gw, + int flags) +{ + return _route_add (route, AF_INET6, dst, prefix, gw, flags); +} + +/** * nm_netlink_route_delete: * @route: the route to delete * diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index c6c452a0..697faaf0 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -24,6 +24,7 @@ #include <glib.h> #include <netlink/route/rtnl.h> #include <netlink/route/route.h> +#include <netinet/in.h> gboolean nm_netlink_find_address (int ifindex, int family, @@ -43,11 +44,16 @@ struct rtnl_route * nm_netlink_route_new (int ifindex, int mss, ...) __attribute__((__sentinel__)); -int nm_netlink_route_add (struct rtnl_route *route, - int family, - const void * dst, /* struct in_addr or struct in6_addr */ +int nm_netlink_route4_add (struct rtnl_route *route, + guint32 *dst, + int prefix, + guint32 *gw, + int flags); + +int nm_netlink_route6_add (struct rtnl_route *route, + const struct in6_addr *dst, int prefix, - const void * gw, /* struct in_addr or struct in6_addr */ + const struct in6_addr *gw, int flags); gboolean nm_netlink_route_delete (struct rtnl_route *route); @@ -76,5 +82,5 @@ struct rtnl_route * nm_netlink_foreach_route (int ifindex, NlRouteForeachFunc callback, gpointer user_data); -#endif /* NM_NETLINK_MONITOR_H */ +#endif /* NM_NETLINK_UTILS_H */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 669db28b..babf1649 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -31,14 +31,7 @@ #include "nm-wifi-ap.h" #include "nm-activation-request.h" #include "nm-logging.h" -#include "nm-device-interface.h" #include "nm-device.h" -#include "nm-device-wifi.h" -#include "nm-device-ethernet.h" -#include "nm-device-modem.h" -#if WITH_WIMAX -#include "nm-device-wimax.h" -#endif #include "nm-dbus-manager.h" #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" @@ -47,6 +40,7 @@ #include "nm-vpn-manager.h" #include "nm-policy-hostname.h" #include "nm-manager-auth.h" +#include "nm-firewall-manager.h" struct NMPolicy { NMManager *manager; @@ -60,6 +54,9 @@ struct NMPolicy { gulong vpn_activated_id; gulong vpn_deactivated_id; + NMFirewallManager *fw_manager; + gulong fw_started_id; + NMSettings *settings; NMDevice *default_device4; @@ -80,6 +77,9 @@ struct NMPolicy { #define RESET_RETRIES_TIMER 300 #define FAILURE_REASON_TAG "failure-reason" +static void schedule_activate_all (NMPolicy *policy); + + static NMDevice * get_best_ip4_device (NMManager *manager, NMActRequest **out_req) { @@ -95,6 +95,7 @@ get_best_ip4_device (NMManager *manager, NMActRequest **out_req) devices = nm_manager_get_devices (manager); for (iter = devices; iter; iter = g_slist_next (iter)) { NMDevice *dev = NM_DEVICE (iter->data); + NMDeviceType devtype = nm_device_get_device_type (dev); NMActRequest *req; NMConnection *connection; NMIP4Config *ip4_config; @@ -117,7 +118,7 @@ get_best_ip4_device (NMManager *manager, NMActRequest **out_req) g_assert (connection); /* Never set the default route through an IPv4LL-addressed device */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); @@ -135,7 +136,7 @@ get_best_ip4_device (NMManager *manager, NMActRequest **out_req) } } - if (!can_default && !NM_IS_DEVICE_MODEM (dev)) + if (!can_default && (devtype != NM_DEVICE_TYPE_MODEM)) continue; /* 'never-default' devices can't ever be the default */ @@ -169,6 +170,7 @@ get_best_ip6_device (NMManager *manager, NMActRequest **out_req) devices = nm_manager_get_devices (manager); for (iter = devices; iter; iter = g_slist_next (iter)) { NMDevice *dev = NM_DEVICE (iter->data); + NMDeviceType devtype = nm_device_get_device_type (dev); NMActRequest *req; NMConnection *connection; NMIP6Config *ip6_config; @@ -191,7 +193,7 @@ get_best_ip6_device (NMManager *manager, NMActRequest **out_req) g_assert (connection); /* Never set the default route through an IPv4LL-addressed device */ - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) method = nm_setting_ip6_config_get_method (s_ip6); @@ -209,7 +211,7 @@ get_best_ip6_device (NMManager *manager, NMActRequest **out_req) } } - if (!can_default && !NM_IS_DEVICE_MODEM (dev)) + if (!can_default && (devtype != NM_DEVICE_TYPE_MODEM)) continue; /* 'never-default' devices can't ever be the default */ @@ -471,7 +473,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) can_default = FALSE; /* Check the user's preference from the NMConnection */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (vpn_connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (vpn_connection); if (s_ip4 && nm_setting_ip4_config_get_never_default (s_ip4)) can_default = FALSE; @@ -533,7 +535,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) req = nm_device_get_act_request (dev); if (req && (req != best_req)) - nm_act_request_set_default (req, FALSE); + nm_active_connection_set_default (NM_ACTIVE_CONNECTION (req), FALSE); } dns_mgr = nm_dns_manager_get (NULL); @@ -544,10 +546,10 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) * if the connection is shared dnsmasq picks up the right stuff. */ if (best_req) - nm_act_request_set_default (best_req, TRUE); + nm_active_connection_set_default (NM_ACTIVE_CONNECTION (best_req), TRUE); if (connection) - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL; if (connection_id) { @@ -598,7 +600,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) /* If it's marked 'never-default', don't make it default */ vpn_connection = nm_vpn_connection_get_connection (candidate); g_assert (vpn_connection); - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (vpn_connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (vpn_connection); if (s_ip6 && nm_setting_ip6_config_get_never_default (s_ip6)) can_default = FALSE; @@ -660,7 +662,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) req = nm_device_get_act_request (dev); if (req && (req != best_req)) - nm_act_request_set_default6 (req, FALSE); + nm_active_connection_set_default6 (NM_ACTIVE_CONNECTION (req), FALSE); } dns_mgr = nm_dns_manager_get (NULL); @@ -671,10 +673,10 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) * if the connection is shared dnsmasq picks up the right stuff. */ if (best_req) - nm_act_request_set_default6 (best_req, TRUE); + nm_active_connection_set_default6 (NM_ACTIVE_CONNECTION (best_req), TRUE); if (connection) - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL; if (connection_id) { @@ -792,7 +794,9 @@ auto_activate_device (gpointer user_data) NULL, &error)) { nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation failed: (%d) %s", - nm_connection_get_id (best_connection), error->code, error->message); + nm_connection_get_id (best_connection), + error ? error->code : -1, + error ? error->message : "(none)"); g_error_free (error); } } @@ -870,7 +874,7 @@ reset_retries_all (NMSettings *settings, NMDevice *device) connections = nm_settings_get_connections (settings); for (iter = connections; iter; iter = g_slist_next (iter)) { - if (!device || nm_device_interface_check_connection_compatible (NM_DEVICE_INTERFACE (device), iter->data, &error)) + if (!device || nm_device_check_connection_compatible (device, iter->data, &error)) set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT); g_clear_error (&error); } @@ -917,11 +921,11 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP) return; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); + state = nm_device_get_state (device); if (state < NM_DEVICE_STATE_DISCONNECTED) return; - if (!nm_device_interface_get_enabled (NM_DEVICE_INTERFACE (device))) + if (!nm_device_get_enabled (device)) return; if (!nm_device_autoconnect_allowed (device)) @@ -940,6 +944,7 @@ reset_connections_retries (gpointer user_data) NMPolicy *policy = (NMPolicy *) user_data; GSList *connections, *iter; time_t con_stamp, min_stamp, now; + gboolean changed = FALSE; policy->reset_retries_id = 0; @@ -952,6 +957,7 @@ reset_connections_retries (gpointer user_data) if (con_stamp + RESET_RETRIES_TIMER <= now) { set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT); g_object_set_data (G_OBJECT (iter->data), RESET_RETRIES_TIMESTAMP_TAG, GSIZE_TO_POINTER (0)); + changed = TRUE; continue; } if (con_stamp < min_stamp) @@ -962,19 +968,53 @@ reset_connections_retries (gpointer user_data) /* Schedule the handler again if there are some stamps left */ if (min_stamp != now) policy->reset_retries_id = g_timeout_add_seconds (RESET_RETRIES_TIMER - (now - min_stamp), reset_connections_retries, policy); + + /* If anything changed, try to activate the newly re-enabled connections */ + if (changed) + schedule_activate_all (policy); + return FALSE; } static NMConnection * get_device_connection (NMDevice *device) { - NMActRequest *req; + NMActRequest *req = NULL; req = nm_device_get_act_request (device); - if (!req) - return NULL; + return req ? nm_act_request_get_connection (req) : NULL; +} + +static void schedule_activate_all (NMPolicy *policy); + +static void +activate_slave_connections (NMPolicy *policy, NMConnection *connection, + NMDevice *device) +{ + const char *master_device; + GSList *connections, *iter; + + master_device = nm_device_get_iface (device); + g_assert (master_device); + + connections = nm_settings_get_connections (policy->settings); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *slave; + NMSettingConnection *s_slave_con; + + slave = NM_CONNECTION (iter->data); + g_assert (slave); - return nm_act_request_get_connection (req); + s_slave_con = nm_connection_get_setting_connection (slave); + g_assert (s_slave_con); + + if (!g_strcmp0 (nm_setting_connection_get_master (s_slave_con), master_device)) + set_connection_auto_retries (slave, RETRIES_DEFAULT); + } + + g_slist_free (connections); + + schedule_activate_all (policy); } static void @@ -995,7 +1035,9 @@ device_state_changed (NMDevice *device, /* Mark the connection invalid if it failed during activation so that * it doesn't get automatically chosen over and over and over again. */ - if (connection && IS_ACTIVATING_STATE (old_state)) { + if ( connection + && old_state >= NM_DEVICE_STATE_PREPARE + && old_state <= NM_DEVICE_STATE_ACTIVATED) { guint32 tries = get_connection_auto_retries (connection); if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) { @@ -1064,6 +1106,13 @@ device_state_changed (NMDevice *device, update_routing_and_dns (policy, FALSE); schedule_activate_check (policy, device, 0); break; + + case NM_DEVICE_STATE_PREPARE: + /* Reset auto-connect retries of all slaves and schedule them for + * activation. */ + activate_slave_connections (policy, connection, device); + break; + default: break; } @@ -1078,23 +1127,21 @@ device_ip_config_changed (NMDevice *device, } static void -wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer user_data) +wireless_networks_changed (NMDevice *device, GObject *ap, gpointer user_data) { - schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); + schedule_activate_check ((NMPolicy *) user_data, device, 0); } -#if WITH_WIMAX static void -nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data) +nsps_changed (NMDevice *device, GObject *nsp, gpointer user_data) { - schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); + schedule_activate_check ((NMPolicy *) user_data, device, 0); } -#endif static void -modem_enabled_changed (NMDeviceModem *device, gpointer user_data) +modem_enabled_changed (NMDevice *device, gpointer user_data) { - schedule_activate_check ((NMPolicy *) (user_data), NM_DEVICE (device), 0); + schedule_activate_check ((NMPolicy *) (user_data), device, 0); } typedef struct { @@ -1120,19 +1167,23 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) NMPolicy *policy = (NMPolicy *) user_data; _connect_device_signal (policy, device, "state-changed", device_state_changed); - _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, device_ip_config_changed); - _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG, device_ip_config_changed); + _connect_device_signal (policy, device, "notify::" NM_DEVICE_IP4_CONFIG, device_ip_config_changed); + _connect_device_signal (policy, device, "notify::" NM_DEVICE_IP6_CONFIG, device_ip_config_changed); - if (NM_IS_DEVICE_WIFI (device)) { + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_WIFI: _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed); _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed); -#if WITH_WIMAX - } else if (NM_IS_DEVICE_WIMAX (device)) { + break; + case NM_DEVICE_TYPE_WIMAX: _connect_device_signal (policy, device, "nsp-added", nsps_changed); _connect_device_signal (policy, device, "nsp-removed", nsps_changed); -#endif - } else if (NM_IS_DEVICE_MODEM (device)) { - _connect_device_signal (policy, device, NM_DEVICE_MODEM_ENABLE_CHANGED, modem_enabled_changed); + break; + case NM_DEVICE_TYPE_MODEM: + _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed); + break; + default: + break; } } @@ -1200,14 +1251,80 @@ connections_loaded (NMSettings *settings, gpointer user_data) } static void +add_or_change_zone_cb (GError *error, gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + + if (error) { + /* FIXME: what do we do here? */ + } + + g_object_unref (device); +} + +static void +firewall_update_zone (NMPolicy *policy, NMConnection *connection) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + GSList *iter, *devices; + + devices = nm_manager_get_devices (policy->manager); + /* find dev with passed connection and change zone its interface belongs to */ + for (iter = devices; iter; iter = g_slist_next (iter)) { + NMDevice *dev = NM_DEVICE (iter->data); + + if ( (get_device_connection (dev) == connection) + && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) { + nm_firewall_manager_add_or_change_zone (policy->fw_manager, + nm_device_get_ip_iface (dev), + nm_setting_connection_get_zone (s_con), + FALSE, /* change zone */ + add_or_change_zone_cb, + g_object_ref (dev)); + } + } +} + +static void +firewall_started (NMFirewallManager *manager, + gpointer user_data) +{ + NMPolicy *policy = (NMPolicy *) user_data; + NMConnection *connection; + NMSettingConnection *s_con; + GSList *iter, *devices; + + devices = nm_manager_get_devices (policy->manager); + /* add interface of each device to correct zone */ + for (iter = devices; iter; iter = g_slist_next (iter)) { + NMDevice *dev = NM_DEVICE (iter->data); + + connection = get_device_connection (dev); + s_con = nm_connection_get_setting_connection (connection); + if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { + nm_firewall_manager_add_or_change_zone (policy->fw_manager, + nm_device_get_ip_iface (dev), + nm_setting_connection_get_zone (s_con), + TRUE, /* add zone */ + add_or_change_zone_cb, + g_object_ref (dev)); + } + } +} + +static void connection_updated (NMSettings *settings, NMConnection *connection, gpointer user_data) { + NMPolicy *policy = (NMPolicy *) user_data; + + firewall_update_zone (policy, connection); + /* Reset auto retries back to default since connection was updated */ set_connection_auto_retries (connection, RETRIES_DEFAULT); - schedule_activate_all ((NMPolicy *) user_data); + schedule_activate_all (policy); } static void @@ -1325,6 +1442,11 @@ nm_policy_new (NMManager *manager, G_CALLBACK (vpn_connection_deactivated), policy); policy->vpn_deactivated_id = id; + policy->fw_manager = nm_firewall_manager_get(); + id = g_signal_connect (policy->fw_manager, "started", + G_CALLBACK (firewall_started), policy); + policy->fw_started_id = id; + _connect_manager_signal (policy, "state-changed", global_state_changed); _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed); _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed); @@ -1369,6 +1491,9 @@ nm_policy_destroy (NMPolicy *policy) g_signal_handler_disconnect (policy->vpn_manager, policy->vpn_deactivated_id); g_object_unref (policy->vpn_manager); + g_signal_handler_disconnect (policy->fw_manager, policy->fw_started_id); + g_object_unref (policy->fw_manager); + for (iter = policy->manager_ids; iter; iter = g_slist_next (iter)) g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data)); g_slist_free (policy->manager_ids); diff --git a/src/nm-properties-changed-signal.c b/src/nm-properties-changed-signal.c index 4a9db8af..871d1bb0 100644 --- a/src/nm-properties-changed-signal.c +++ b/src/nm-properties-changed-signal.c @@ -16,13 +16,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2012 Red Hat, Inc. */ #include <string.h> #include <stdio.h> #include <dbus/dbus-glib.h> +#ifdef DEBUG +#include "nm-logging.h" +#endif #include "nm-properties-changed-signal.h" #include "nm-dbus-glib-types.h" diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor-ck.c index 7ee9013a..72ffc9ff 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor-ck.c @@ -20,13 +20,12 @@ #include "config.h" #include <errno.h> -#include <pwd.h> #include <string.h> -#include <sys/types.h> #include <sys/stat.h> #include <gio/gio.h> #include "nm-logging.h" +#include "nm-session-utils.h" #include "nm-session-monitor.h" #define CKDB_PATH "/var/run/ConsoleKit/database" @@ -66,53 +65,6 @@ G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); /********************************************************************/ -#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ()) -GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST; -GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; - -typedef enum { - NM_SESSION_MONITOR_ERROR_IO_ERROR = 0, - NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, - NM_SESSION_MONITOR_ERROR_NO_DATABASE, -} NMSessionMonitorError; - -GQuark -nm_session_monitor_error_quark (void) -{ - static GQuark ret = 0; - - if (G_UNLIKELY (ret == 0)) - ret = g_quark_from_static_string ("nm-session-monitor-error"); - return ret; -} - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_session_monitor_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Some I/O operation on the CK database failed */ - ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_IO_ERROR, "IOError"), - /* Error parsing the CK database */ - ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "MalformedDatabase"), - /* Username or UID could could not be found */ - ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"), - /* No ConsoleKit database */ - ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NoDatabase"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("NMSessionMonitorError", values); - } - return etype; -} -/********************************************************************/ - typedef struct { char *user; uid_t uid; @@ -149,7 +101,7 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) { GError *local = NULL; Session *s; - struct passwd *pw; + const char *uname = NULL; s = g_new0 (Session, 1); g_assert (s); @@ -173,16 +125,9 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) if (local) goto error; - pw = getpwuid (s->uid); - if (!pw) { - g_set_error (&local, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, - "Could not get username for UID %d", - s->uid); - goto error; - } - s->user = g_strdup (pw->pw_name); + if (!nm_session_uid_to_user (s->uid, &uname, error)) + return FALSE; + s->user = g_strdup (uname); return s; @@ -289,10 +234,6 @@ ensure_database (NMSessionMonitor *self, GError **error) { gboolean ret = FALSE; -#if NO_CONSOLEKIT - return TRUE; -#endif - if (self->database != NULL) { struct stat statbuf; @@ -339,10 +280,6 @@ nm_session_monitor_init (NMSessionMonitor *self) GError *error = NULL; GFile *file; -#if NO_CONSOLEKIT - return; -#endif - /* Sessions-by-user is responsible for destroying the Session objects */ self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) session_free); @@ -428,50 +365,6 @@ nm_session_monitor_get (void) /* ---------------------------------------------------------------------------------------------------- */ -#if NO_CONSOLEKIT -static gboolean -uid_to_user (uid_t uid, const char **out_user, GError **error) -{ - struct passwd *pw; - - pw = getpwuid (uid); - if (!pw) { - g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, - "Could not get username for UID %d", - uid); - return FALSE; - } - - /* Ugly, but hey, use ConsoleKit */ - if (out_user) - *out_user = pw->pw_name; - return TRUE; -} - -static gboolean -user_to_uid (const char *user, uid_t *out_uid, GError **error) -{ - struct passwd *pw; - - pw = getpwnam (user); - if (!pw) { - g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, - "Could not get UID for username '%s'", - user); - return FALSE; - } - - /* Ugly, but hey, use ConsoleKit */ - if (out_uid) - *out_uid = pw->pw_uid; - return TRUE; -} -#endif - /** * nm_session_monitor_user_has_session: * @monitor: A #NMSessionMonitor. @@ -491,12 +384,6 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, { Session *s; -#if NO_CONSOLEKIT - if (!user_to_uid (username, out_uid, error)) - return FALSE; - return TRUE; -#endif - if (!ensure_database (monitor, error)) return FALSE; @@ -534,12 +421,6 @@ nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, { Session *s; -#if NO_CONSOLEKIT - if (!uid_to_user (uid, out_user, error)) - return FALSE; - return TRUE; -#endif - if (!ensure_database (monitor, error)) return FALSE; @@ -576,10 +457,6 @@ nm_session_monitor_user_active (NMSessionMonitor *monitor, { Session *s; -#if NO_CONSOLEKIT - return TRUE; -#endif - if (!ensure_database (monitor, error)) return FALSE; @@ -614,10 +491,6 @@ nm_session_monitor_uid_active (NMSessionMonitor *monitor, { Session *s; -#if NO_CONSOLEKIT - return TRUE; -#endif - if (!ensure_database (monitor, error)) return FALSE; diff --git a/src/nm-session-monitor-null.c b/src/nm-session-monitor-null.c new file mode 100644 index 00000000..beabcf21 --- /dev/null +++ b/src/nm-session-monitor-null.c @@ -0,0 +1,171 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + * Author: David Zeuthen <davidz@redhat.com> + * Author: Dan Williams <dcbw@redhat.com> + */ + +#include "config.h" +#include <string.h> +#include "nm-logging.h" + +#include "nm-session-utils.h" +#include "nm-session-monitor.h" + +/* <internal> + * SECTION:nm-session-monitor + * @title: NMSessionMonitor + * @short_description: Monitor sessions + * + * The #NMSessionMonitor class is a utility class to track and monitor sessions. + */ + +struct _NMSessionMonitor { + GObject parent_instance; +}; + +struct _NMSessionMonitorClass { + GObjectClass parent_class; + + void (*changed) (NMSessionMonitor *monitor); +}; + + +enum { + CHANGED, + LAST_SIGNAL, +}; +static guint signals[LAST_SIGNAL] = {0}; + +G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); + +/********************************************************************/ + +static void +nm_session_monitor_init (NMSessionMonitor *self) +{ +} + +static void +nm_session_monitor_class_init (NMSessionMonitorClass *klass) +{ + /** + * NMSessionMonitor::changed: + * @monitor: A #NMSessionMonitor + * + * Emitted when something changes. + */ + signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED, + NM_TYPE_SESSION_MONITOR, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +NMSessionMonitor * +nm_session_monitor_get (void) +{ + static NMSessionMonitor *singleton = NULL; + + if (singleton) + return g_object_ref (singleton); + + singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); + g_assert (singleton); + return singleton; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * nm_session_monitor_user_has_session: + * @monitor: A #NMSessionMonitor. + * @username: A username. + * @error: Return location for error. + * + * Checks whether the given @username is logged into a session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is + * currently logged into a session. + */ +gboolean +nm_session_monitor_user_has_session (NMSessionMonitor *monitor, + const char *username, + uid_t *out_uid, + GError **error) +{ + return nm_session_user_to_uid (username, out_uid, error); +} + +/** + * nm_session_monitor_uid_has_session: + * @monitor: A #NMSessionMonitor. + * @uid: A user ID. + * @error: Return location for error. + * + * Checks whether the given @uid is logged into a session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is + * currently logged into a session. + */ +gboolean +nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, + uid_t uid, + const char **out_user, + GError **error) +{ + return nm_session_uid_to_user (uid, out_user, error); +} + +/** + * nm_session_monitor_user_active: + * @monitor: A #NMSessionMonitor. + * @username: A username. + * @error: Return location for error. + * + * Checks whether the given @username is logged into a active session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is + * logged into an active session. + */ +gboolean +nm_session_monitor_user_active (NMSessionMonitor *monitor, + const char *username, + GError **error) +{ + return TRUE; +} + +/** + * nm_session_monitor_uid_active: + * @monitor: A #NMSessionMonitor. + * @uid: A user ID. + * @error: Return location for error. + * + * Checks whether the given @uid is logged into a active session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is + * logged into an active session. + */ +gboolean +nm_session_monitor_uid_active (NMSessionMonitor *monitor, + uid_t uid, + GError **error) +{ + return TRUE; +} + diff --git a/src/nm-session-monitor-systemd.c b/src/nm-session-monitor-systemd.c new file mode 100644 index 00000000..29ba7c21 --- /dev/null +++ b/src/nm-session-monitor-systemd.c @@ -0,0 +1,251 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * 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., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Matthias Clasen + */ + +#include "config.h" +#include <errno.h> +#include <pwd.h> +#include <grp.h> +#include <string.h> +#include <glib/gstdio.h> +#include <systemd/sd-login.h> +#include <stdlib.h> + +#include "nm-session-utils.h" +#include "nm-session-monitor.h" + +/********************************************************************/ + +typedef struct { + GSource source; + GPollFD pollfd; + sd_login_monitor *monitor; +} SdSource; + +static gboolean +sd_source_prepare (GSource *source, gint *timeout) +{ + *timeout = -1; + return FALSE; +} + +static gboolean +sd_source_check (GSource *source) +{ + SdSource *sd_source = (SdSource *) source; + + return sd_source->pollfd.revents != 0; +} + +static gboolean +sd_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) + +{ + SdSource *sd_source = (SdSource *)source; + gboolean ret; + + g_warn_if_fail (callback != NULL); + ret = (*callback) (user_data); + sd_login_monitor_flush (sd_source->monitor); + return ret; +} + +static void +sd_source_finalize (GSource *source) +{ + SdSource *sd_source = (SdSource*) source; + + sd_login_monitor_unref (sd_source->monitor); +} + +static GSourceFuncs sd_source_funcs = { + sd_source_prepare, + sd_source_check, + sd_source_dispatch, + sd_source_finalize +}; + +static GSource * +sd_source_new (void) +{ + GSource *source; + SdSource *sd_source; + int ret; + + source = g_source_new (&sd_source_funcs, sizeof (SdSource)); + sd_source = (SdSource *)source; + + ret = sd_login_monitor_new (NULL, &sd_source->monitor); + if (ret < 0) + g_printerr ("Error getting login monitor: %d", ret); + else { + sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor); + sd_source->pollfd.events = G_IO_IN; + g_source_add_poll (source, &sd_source->pollfd); + } + + return source; +} + +struct _NMSessionMonitor { + GObject parent_instance; + + GSource *sd_source; +}; + +struct _NMSessionMonitorClass { + GObjectClass parent_class; + + void (*changed) (NMSessionMonitor *monitor); +}; + + +enum { + CHANGED_SIGNAL, + LAST_SIGNAL, +}; +static guint signals[LAST_SIGNAL] = {0}; + +G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +sessions_changed (gpointer user_data) +{ + NMSessionMonitor *monitor = NM_SESSION_MONITOR (user_data); + + g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0); + return TRUE; +} + + +static void +nm_session_monitor_init (NMSessionMonitor *monitor) +{ + monitor->sd_source = sd_source_new (); + g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL); + g_source_attach (monitor->sd_source, NULL); +} + +static void +nm_session_monitor_finalize (GObject *object) +{ + NMSessionMonitor *monitor = NM_SESSION_MONITOR (object); + + if (monitor->sd_source != NULL) { + g_source_destroy (monitor->sd_source); + g_source_unref (monitor->sd_source); + } + + if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL) + G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object); +} + +static void +nm_session_monitor_class_init (NMSessionMonitorClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = nm_session_monitor_finalize; + + /** + * NMSessionMonitor::changed: + * @monitor: A #NMSessionMonitor + * + * Emitted when something changes. + */ + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + NM_TYPE_SESSION_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSessionMonitorClass, changed), + NULL, /* accumulator */ + NULL, /* accumulator data */ + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +NMSessionMonitor * +nm_session_monitor_get (void) +{ + static NMSessionMonitor *singleton = NULL; + + if (singleton) + return g_object_ref (singleton); + + singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); + g_assert (singleton); + return singleton; +} + +gboolean +nm_session_monitor_user_has_session (NMSessionMonitor *monitor, + const char *username, + uid_t *out_uid, + GError **error) +{ + uid_t uid; + + if (!nm_session_user_to_uid (username, &uid, error)) + return FALSE; + + if (out_uid) + *out_uid = uid; + + return nm_session_monitor_uid_has_session (monitor, uid, NULL, error); +} + +gboolean +nm_session_monitor_user_active (NMSessionMonitor *monitor, + const char *username, + GError **error) +{ + uid_t uid; + + if (!nm_session_user_to_uid (username, &uid, error)) + return FALSE; + + return nm_session_monitor_uid_active (monitor, uid, error); +} + +gboolean +nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, + uid_t uid, + const char **out_user, + GError **error) +{ + if (!nm_session_uid_to_user (uid, out_user, error)) + return FALSE; + + return sd_uid_get_sessions (uid, FALSE, NULL) > 0; +} + +gboolean +nm_session_monitor_uid_active (NMSessionMonitor *monitor, + uid_t uid, + GError **error) +{ + return sd_uid_get_sessions (uid, TRUE, NULL) > 0; +} diff --git a/src/nm-session-utils.c b/src/nm-session-utils.c new file mode 100644 index 00000000..269e2f81 --- /dev/null +++ b/src/nm-session-utils.c @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Red Hat, Inc. + * Author: Dan Williams <dcbw@redhat.com> + */ + +#include <pwd.h> +#include <sys/types.h> + +#include "nm-session-utils.h" + +/********************************************************************/ + +GQuark +nm_session_monitor_error_quark (void) +{ + static GQuark ret = 0; + + if (G_UNLIKELY (ret == 0)) + ret = g_quark_from_static_string ("nm-session-monitor-error"); + return ret; +} + +/********************************************************************/ + +gboolean +nm_session_uid_to_user (uid_t uid, const char **out_user, GError **error) +{ + struct passwd *pw; + + pw = getpwuid (uid); + if (!pw) { + g_set_error (error, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + "Could not get username for UID %d", + uid); + return FALSE; + } + + if (out_user) + *out_user = pw->pw_name; + return TRUE; +} + +gboolean +nm_session_user_to_uid (const char *user, uid_t *out_uid, GError **error) +{ + struct passwd *pw; + + pw = getpwnam (user); + if (!pw) { + g_set_error (error, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + "Could not get UID for username '%s'", + user); + return FALSE; + } + + /* Ugly, but hey, use ConsoleKit */ + if (out_uid) + *out_uid = pw->pw_uid; + return TRUE; +} + diff --git a/src/nm-session-utils.h b/src/nm-session-utils.h new file mode 100644 index 00000000..54b6d4c4 --- /dev/null +++ b/src/nm-session-utils.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Red Hat, Inc. + * Author: Dan Williams <dcbw@redhat.com> + */ + +#ifndef NM_SESSION_UTILS_H +#define NM_SESSION_UTILS_H + +#include <glib.h> +#include <glib-object.h> + +#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ()) +GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST; +GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; + +typedef enum { + NM_SESSION_MONITOR_ERROR_IO_ERROR = 0, /*< nick=IOError >*/ + NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, /*< nick=MalformedDatabase >*/ + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, /*< nick=UnknownUser >*/ + NM_SESSION_MONITOR_ERROR_NO_DATABASE, /*< nick=NoDatabase >*/ +} NMSessionMonitorError; + +gboolean nm_session_uid_to_user (uid_t uid, const char **out_user, GError **error); + +gboolean nm_session_user_to_uid (const char *user, uid_t *out_uid, GError **error); + +#endif /* NM_SESSION_UTILS_H */ diff --git a/src/nm-system.c b/src/nm-system.c index 62ab8b93..91153ec2 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -21,6 +21,7 @@ * Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com> */ +#include <config.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> @@ -41,6 +42,8 @@ #include <glib.h> #include <ctype.h> #include <linux/if.h> +#include <linux/sockios.h> +#include <linux/if_bonding.h> #include "nm-system.h" #include "nm-device.h" @@ -57,6 +60,16 @@ #include <netlink/utils.h> #include <netlink/route/link.h> +#ifdef HAVE_LIBNL3 +#include <netlink/route/link/bonding.h> +#include <netlink/route/link/vlan.h> +#endif + +#if !HAVE_VLAN_FLAG_LOOSE_BINDING +/* Older kernels don't have this flag */ +#define VLAN_FLAG_LOOSE_BINDING 0x04 +#endif + static void nm_system_device_set_priority (int ifindex, NMIP4Config *config, int priority); @@ -108,7 +121,7 @@ nm_system_device_set_ip4_route (int ifindex, g_return_val_if_fail (route != NULL, NULL); /* Add the route */ - err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0); + err = nm_netlink_route4_add (route, &ip4_dest, ip4_prefix, &ip4_gateway, 0); if (err == -NLE_OBJ_NOTFOUND && ip4_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; @@ -116,9 +129,9 @@ nm_system_device_set_ip4_route (int ifindex, route2 = nm_netlink_route_new (ifindex, AF_INET, mss, NULL); if (route2) { /* Add route to gateway over bridge */ - err = nm_netlink_route_add(route2, AF_INET, &ip4_gateway, 32, NULL, 0); + err = nm_netlink_route4_add (route2, &ip4_gateway, 32, NULL, 0); if (!err) { - err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0); + err = nm_netlink_route4_add (route, &ip4_dest, ip4_prefix, &ip4_gateway, 0); if (err) nm_netlink_route_delete (route2); } @@ -233,7 +246,7 @@ sync_addresses (int ifindex, if (buf_valid) { nm_log_dbg (log_domain, "(%s): removing address '%s/%d'", - iface, buf, nl_addr_get_prefixlen (nladdr)); + iface, buf, rtnl_addr_get_prefixlen (match_addr)); } /* Otherwise, match_addr should be removed from the interface. */ @@ -479,18 +492,18 @@ nm_system_set_ip6_route (int ifindex, g_return_val_if_fail (route != NULL, -1); /* Add the route */ - err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0); + err = nm_netlink_route6_add (route, ip6_dest, ip6_prefix, ip6_gateway, 0); if (err == -NLE_OBJ_NOTFOUND && ip6_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; route2 = nm_netlink_route_new (ifindex, AF_INET6, mss, NULL); if (route2) { - err = nm_netlink_route_add(route, AF_INET6, &ip6_gateway, 128, NULL, 0); + err = nm_netlink_route6_add (route, ip6_gateway, 128, NULL, 0); /* Add route to gateway over bridge */ if (!err) { /* Try adding the route again */ - err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0); + err = nm_netlink_route6_add (route, ip6_dest, ip6_prefix, ip6_gateway, 0); if (err) nm_netlink_route_delete (route2); } @@ -588,7 +601,7 @@ nm_system_apply_ip6_config (int ifindex, RTPROT_UNSPEC, RT_TABLE_UNSPEC, NULL); - if (err) { + if (err && (err != -NLE_EXIST)) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 route: %s", iface ? iface : "unknown", @@ -657,15 +670,8 @@ nm_system_iface_set_up (int ifindex, return success; } -/** - * nm_system_iface_is_up: - * @ifindex: interface index - * - * Returns: %TRUE if the interface is up, %FALSE if it was down or the check - * failed. - **/ -gboolean -nm_system_iface_is_up (int ifindex) +guint32 +nm_system_iface_get_flags (int ifindex) { struct rtnl_link *l; guint32 flags; @@ -686,7 +692,20 @@ nm_system_iface_is_up (int ifindex) flags = rtnl_link_get_flags (l); rtnl_link_put (l); - return flags & IFF_UP; + return flags; +} + +/** + * nm_system_iface_is_up: + * @ifindex: interface index + * + * Returns: %TRUE if the interface is up, %FALSE if it was down or the check + * failed. + **/ +gboolean +nm_system_iface_is_up (int ifindex) +{ + return nm_system_iface_get_flags (ifindex) & IFF_UP; } /** @@ -812,7 +831,7 @@ add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) g_return_val_if_fail (route != NULL, NULL); /* Add direct route to the gateway */ - err = nm_netlink_route_add(route, AF_INET, &gw, 32, NULL, 0); + err = nm_netlink_route4_add (route, &gw, 32, NULL, 0); if (err) { char *iface = nm_netlink_index_to_iface (ifindex); @@ -836,7 +855,7 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) struct rtnl_route *route = NULL; struct nl_sock *nlh; int err = -1; - int dst=0; + guint32 dst = 0; g_return_val_if_fail (ifindex > 0, -ENODEV); @@ -850,7 +869,9 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) g_return_val_if_fail (route != NULL, -ENOMEM); /* Add the new default route */ - err = nm_netlink_route_add (route, AF_INET, &dst, 0, &gw, NLM_F_REPLACE); + err = nm_netlink_route4_add (route, &dst, 0, &gw, NLM_F_REPLACE); + if (err == -NLE_EXIST) + err = 0; rtnl_route_put (route); return err; @@ -985,7 +1006,7 @@ add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) g_return_val_if_fail (route != NULL, NULL); /* Add direct route to the gateway */ - err = nm_netlink_route_add(route, AF_INET, gw, 128, NULL, 0); + err = nm_netlink_route6_add (route, gw, 128, NULL, 0); if (err) { char *iface = nm_netlink_index_to_iface (ifindex); @@ -1020,11 +1041,10 @@ replace_default_ip6_route (int ifindex, const struct in6_addr *gw) g_return_val_if_fail (route != NULL, -ENOMEM); /* Add the new default route */ - nm_netlink_route_add(route, AF_INET6, NULL, 0, gw, NLM_F_REPLACE); + err = nm_netlink_route6_add (route, &in6addr_any, 0, gw, NLM_F_REPLACE); if (err == -NLE_EXIST) { /* FIXME: even though we use NLM_F_REPLACE the kernel won't replace - * the route if it's the same. Should try to remove it first, then - * add the new one again here. + * the route if it's the same. Suppress the pointless error. */ err = 0; } @@ -1051,6 +1071,9 @@ nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) if (err == 0) return TRUE; + if (err == -NLE_EXIST) + return TRUE; + iface = nm_netlink_index_to_iface (ifindex); if (!iface) goto out; @@ -1202,3 +1225,762 @@ nm_system_device_set_priority (int ifindex, rtnl_route_put (found); } } + +static const struct { + const char *option; + const char *default_value; +} bonding_defaults[] = { + { "mode", "balance-rr" }, + { "arp_interval", "0" }, + { "miimon", "0" }, + + { "ad_select", "stable" }, + { "arp_validate", "none" }, + { "downdelay", "0" }, + { "fail_over_mac", "none" }, + { "lacp_rate", "slow" }, + { "min_links", "0" }, + { "num_grat_arp", "1" }, + { "num_unsol_na", "1" }, + { "primary", "" }, + { "primary_reselect", "always" }, + { "resend_igmp", "1" }, + { "updelay", "0" }, + { "use_carrier", "1" }, + { "xmit_hash_policy", "layer2" }, + { NULL, NULL } +}; + +static void +remove_bonding_entries (const char *iface, const char *path) +{ + char cmd[20]; + char *value, **entries; + gboolean ret; + int i; + + if (!g_file_get_contents (path, &value, NULL, NULL)) + return; + + entries = g_strsplit (value, " ", -1); + for (i = 0; entries[i]; i++) { + snprintf (cmd, sizeof (cmd), "-%s", g_strstrip (entries[i])); + ret = nm_utils_do_sysctl (path, cmd); + if (!ret) { + nm_log_warn (LOGD_HW, "(%s): failed to remove entry '%s' from '%s'", + iface, entries[i], path); + } + } + g_strfreev (entries); +} + +static gboolean +option_valid_for_nm_setting (const char *option, const char **valid_opts) +{ + while (*valid_opts) { + if (strcmp (option, *valid_opts) == 0) + return TRUE; + valid_opts++; + } + return FALSE; +} + +gboolean +nm_system_apply_bonding_config (const char *iface, NMSettingBond *s_bond) +{ + const char **valid_opts; + const char *option, *value; + char path[FILENAME_MAX]; + char *current, *space; + gboolean ret; + int i; + + g_return_val_if_fail (iface != NULL, FALSE); + + /* Remove old slaves and arp_ip_targets */ + snprintf (path, sizeof (path), "/sys/class/net/%s/bonding/arp_ip_target", iface); + remove_bonding_entries (iface, path); + snprintf (path, sizeof (path), "/sys/class/net/%s/bonding/slaves", iface); + remove_bonding_entries (iface, path); + + /* Apply config/defaults */ + valid_opts = nm_setting_bond_get_valid_options (s_bond); + for (i = 0; bonding_defaults[i].option; i++) { + option = bonding_defaults[i].option; + if (option_valid_for_nm_setting (option, valid_opts)) + value = nm_setting_bond_get_option_by_name (s_bond, option); + else + value = NULL; + if (!value) + value = bonding_defaults[i].default_value; + + snprintf (path, sizeof (path), "/sys/class/net/%s/bonding/%s", iface, option); + if (g_file_get_contents (path, ¤t, NULL, NULL)) { + g_strstrip (current); + space = strchr (current, ' '); + if (space) + *space = '\0'; + if (strcmp (current, value) != 0) { + ret = nm_utils_do_sysctl (path, value); + if (!ret) { + nm_log_warn (LOGD_HW, "(%s): failed to set bonding attribute " + "'%s' to '%s'", iface, option, value); + } + } + } + } + + /* Handle arp_ip_target */ + value = nm_setting_bond_get_option_by_name (s_bond, "arp_ip_target"); + if (value) { + char **addresses, cmd[20]; + + snprintf (path, sizeof (path), "/sys/class/net/%s/bonding/arp_ip_target", iface); + addresses = g_strsplit (value, ",", -1); + for (i = 0; addresses[i]; i++) { + snprintf (cmd, sizeof (cmd), "+%s", g_strstrip (addresses[i])); + ret = nm_utils_do_sysctl (path, cmd); + if (!ret) { + nm_log_warn (LOGD_HW, "(%s): failed to add arp_ip_target '%s'", + iface, addresses[i]); + } + } + g_strfreev (addresses); + } + + return TRUE; +} + +/** + * nm_system_add_bonding_master: + * @iface: the interface name for the new bond master + * + * Adds a virtual bonding device if it does not exist yet. + * + * Returns: %TRUE on success, %FALSE on failure + */ +gboolean +nm_system_add_bonding_master (const char *iface) +{ + struct nl_sock *sock; + int err; + + g_return_val_if_fail (iface != NULL, FALSE); + + sock = nm_netlink_get_default_handle (); + + /* Existing bonding devices with matching name will be reused */ + err = rtnl_link_bond_add (sock, iface, NULL); + if (err < 0) { + nm_log_err (LOGD_DEVICE, "(%s): error %d returned from " + "rtnl_link_bond_add(): %s", + iface, err, nl_geterror (err)); + return FALSE; + } + return TRUE; +} + +static gboolean +nm_system_iface_compat_enslave (const char *master_iface, const char *slave_iface) +{ + struct ifreq ifr; + int fd; + gboolean ret = FALSE; + + memset (&ifr, 0, sizeof (ifr)); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return FALSE; + } + + strncpy (ifr.ifr_name, master_iface, IFNAMSIZ); + strncpy (ifr.ifr_slave, slave_iface, IFNAMSIZ); + + if (ioctl (fd, SIOCBONDENSLAVE, &ifr) < 0 && + ioctl (fd, BOND_ENSLAVE_OLD, &ifr) < 0) { + nm_log_err (LOGD_DEVICE, "(%s): error enslaving %s: %d (%s)", + master_iface, slave_iface, errno, strerror (errno)); + } else + ret = TRUE; + + close (fd); + + return ret; +} + +/** + * nm_system_iface_enslave: + * @master_ifindex: master device interface index + * @master_iface: master device interface name + * @slave_ifindex: slave device interface index + * @slave_iface: slave device interface name + * + * Enslaves the 'slave' to 'master. This function targets implementing a + * generic interface to attaching all kinds of slaves to masters. Currently + * only bonding is properly supported due to the backwards compatibility + * function being bonding specific. + * + * The slave device needs to be down as a prerequisite. + * + * Returns: %TRUE on success, or %FALSE + */ +gboolean +nm_system_iface_enslave (gint master_ifindex, + const char *master_iface, + gint slave_ifindex, + const char *slave_iface) +{ + struct nl_sock *sock; + int err; + + g_return_val_if_fail (master_ifindex >= 0, FALSE); + g_return_val_if_fail (master_iface != NULL, FALSE); + g_return_val_if_fail (slave_ifindex >= 0, FALSE); + g_return_val_if_fail (slave_iface != NULL, FALSE); + + sock = nm_netlink_get_default_handle (); + + if (!(nm_system_iface_get_flags (master_ifindex) & IFF_MASTER)) { + nm_log_err (LOGD_DEVICE, "(%s): interface is not a master", master_iface); + return FALSE; + } + + g_assert (!nm_system_iface_is_up (slave_ifindex)); + + if (nm_system_iface_get_flags (slave_ifindex) & IFF_SLAVE) { + nm_log_err (LOGD_DEVICE, "(%s): %s is already a slave", + master_iface, slave_iface); + return FALSE; + } + + err = rtnl_link_bond_enslave_ifindex (sock, master_ifindex, slave_ifindex); + if (err == -NLE_OPNOTSUPP) + return nm_system_iface_compat_enslave (master_iface, slave_iface); + + if (err < 0) { + nm_log_err (LOGD_DEVICE, "(%s): error enslaving %s: %d (%s)", + master_iface, slave_iface, err, nl_geterror (err)); + return FALSE; + } + + return TRUE; +} + +static gboolean +nm_system_iface_compat_release (const char *master_iface, const char *slave_iface) +{ + struct ifreq ifr; + int fd; + gboolean ret = FALSE; + + memset (&ifr, 0, sizeof (ifr)); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return FALSE; + } + + strncpy (ifr.ifr_name, master_iface, IFNAMSIZ); + strncpy (ifr.ifr_slave, slave_iface, IFNAMSIZ); + + if (ioctl (fd, SIOCBONDRELEASE, &ifr) < 0 && + ioctl (fd, BOND_RELEASE_OLD, &ifr) < 0) { + nm_log_err (LOGD_DEVICE, "(%s): error releasing slave %s: %d (%s)", + master_iface, slave_iface, errno, strerror (errno)); + } else + ret = TRUE; + + close (fd); + return ret; +} + +/** + * nm_system_iface_release: + * @master_ifindex: master device interface index + * @master_iface: master device interface name + * @slave_ifindex: slave device interface index + * @slave_iface: slave device interface name + * + * Releases the 'slave' which is attached to 'master. This function targets + * implementing a generic interface to releasing all kinds of slaves. Currently + * only bonding is properly supported due to the backwards compatibility + * function being bonding specific. + * + * Returns: %TRUE on success, or %FALSE + */ +gboolean +nm_system_iface_release (gint master_ifindex, + const char *master_iface, + gint slave_ifindex, + const char *slave_iface) +{ + struct nl_sock *sock; + int err; + + g_return_val_if_fail (master_ifindex >= 0, FALSE); + g_return_val_if_fail (master_iface != NULL, FALSE); + g_return_val_if_fail (slave_ifindex >= 0, FALSE); + g_return_val_if_fail (slave_iface != NULL, FALSE); + + sock = nm_netlink_get_default_handle (); + + /* Only release if this is actually a slave */ + if (!(nm_system_iface_get_flags (slave_ifindex) & IFF_SLAVE)) + return TRUE; + + err = rtnl_link_bond_release_ifindex (sock, slave_ifindex); + if (err == -NLE_OPNOTSUPP) + return nm_system_iface_compat_release (master_iface, slave_iface); + else if (err < 0) { + nm_log_err (LOGD_DEVICE, "(%s): error releasing slave %s: %d (%s)", + master_iface, slave_iface, err, nl_geterror (err)); + return FALSE; + } + + return TRUE; +} + +/** + * nm_system_get_iface_type: + * @ifindex: interface index + * @name: name of interface + * + * Lookup the type of an interface. At least one of @ifindex or @name must + * be provided. + * + * Returns: Interface type (NM_IFACE_TYPE_*) or NM_IFACE_TYPE_UNSPEC. + **/ +int +nm_system_get_iface_type (int ifindex, const char *name) +{ + struct rtnl_link *result; + struct nl_sock *nlh; + char *type; + int res = NM_IFACE_TYPE_UNSPEC; + + g_return_val_if_fail (ifindex >= 0 || name, NM_IFACE_TYPE_UNSPEC); + + nlh = nm_netlink_get_default_handle (); + if (!nlh) + goto out; + + /* Prefer interface indexes to names */ + if (rtnl_link_get_kernel (nlh, ifindex, ifindex < 0 ? name : NULL, &result) < 0) + goto out; + + type = rtnl_link_get_type (result); + + if (!g_strcmp0 (type, "bond")) + res = NM_IFACE_TYPE_BOND; + else if (!g_strcmp0 (type, "vlan")) + res = NM_IFACE_TYPE_VLAN; + else if (!g_strcmp0 (type, "dummy")) + res = NM_IFACE_TYPE_DUMMY; + + rtnl_link_put (result); +out: + return res; +} + +/** + * nm_system_get_iface_vlan_info: + * @ifindex: the VLAN interface index + * @out_parent_ifindex: on success, the interface index of the parent interface of + * @iface + * @out_vlan_id: on success, the VLAN ID of @iface + * + * Gets the VLAN parent interface name and VLAN ID. + * + * Returns: %TRUE if the interface is a VLAN device and no error occurred; + * %FALSE if the interface was not a VLAN interface or an error occurred + **/ +gboolean +nm_system_get_iface_vlan_info (int ifindex, + int *out_parent_ifindex, + int *out_vlan_id) +{ + struct nl_sock *nlh; + struct rtnl_link *lk; + struct nl_cache *cache = NULL; + gboolean success = FALSE; + int ret; + + if (nm_system_get_iface_type (ifindex, NULL) != NM_IFACE_TYPE_VLAN) + return FALSE; + + nlh = nm_netlink_get_default_handle (); + if (!nlh) + return FALSE; + + ret = rtnl_link_alloc_cache (nlh, &cache); + g_return_val_if_fail (ret == 0, FALSE); + g_return_val_if_fail (cache != NULL, FALSE); + + lk = rtnl_link_get (cache, ifindex); + if (lk) { + if (out_parent_ifindex) + *out_parent_ifindex = rtnl_link_get_link (lk); + if (out_vlan_id) + *out_vlan_id = rtnl_link_vlan_get_id (lk); + + rtnl_link_put (lk); + success = TRUE; + } + + nl_cache_free (cache); + return success; +} + +static gboolean +nm_system_iface_compat_set_name (const char *old_name, const char *new_name) +{ + int fd; + struct ifreq ifr; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&ifr, 0, sizeof (struct ifreq)); + strncpy (ifr.ifr_name, old_name, sizeof (ifr.ifr_name)); + strncpy (ifr.ifr_newname, new_name, sizeof (ifr.ifr_newname)); + + if (ioctl (fd, SIOCSIFNAME, &ifr) < 0) { + nm_log_err (LOGD_DEVICE, "cann't change %s with %s.", old_name, new_name); + close (fd); + return FALSE; + } + + close (fd); + return TRUE; +} + +static gboolean +nm_system_iface_compat_set_vlan_name_type (int name_type) +{ + int fd; + struct vlan_ioctl_args if_request; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + if_request.cmd = SET_VLAN_NAME_TYPE_CMD; + if_request.u.name_type = name_type; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't set name type."); + close (fd); + return FALSE; + } + + close (fd); + return TRUE; +} + +static gboolean +nm_system_iface_compat_add_vlan_device (const char *master, int vid) +{ + int fd; + struct vlan_ioctl_args if_request; + + g_return_val_if_fail (master, FALSE); + g_return_val_if_fail (vid < 4096, FALSE); + + /* + * use VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD as default, + * we will overwrite it with rtnl_link_set_name() later. + */ + if (!nm_system_iface_compat_set_vlan_name_type (VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD)) + return FALSE; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, master); + if_request.cmd = ADD_VLAN_CMD; + if_request.u.VID = vid; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't add vlan device %s vid %d.", master, vid); + close (fd); + return FALSE; + } + + close (fd); + return TRUE; +} + +static gboolean +nm_system_iface_compat_rem_vlan_device (const char *iface) +{ + int fd; + struct vlan_ioctl_args if_request; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't open control socket."); + return -1; + } + + memset (&if_request, 0, sizeof (struct vlan_ioctl_args)); + strcpy (if_request.device1, iface); + if_request.cmd = DEL_VLAN_CMD; + + if (ioctl (fd, SIOCSIFVLAN, &if_request) < 0) { + nm_log_err (LOGD_DEVICE, "couldn't rem vlan device %s.", iface); + close (fd); + return FALSE; + } + + close (fd); + return TRUE; +} + +static gboolean +nm_system_iface_compat_add_vlan (NMConnection *connection, + const char *iface, + int master_ifindex) +{ + NMSettingVlan *s_vlan; + int vlan_id; + guint32 vlan_flags = 0; + guint32 num, i, from, to; + int ifindex; + struct rtnl_link *new_link = NULL; + char *master = nm_netlink_index_to_iface (master_ifindex); + char *name = NULL; + + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan, FALSE); + + vlan_id = nm_setting_vlan_get_id (s_vlan); + + if (!iface) { + iface = nm_connection_get_virtual_iface_name (connection); + g_return_val_if_fail (iface != NULL, FALSE); + } + + /* + * Use VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD as default, + * we will overwrite it with rtnl_link_set_name() later. + */ + name = nm_utils_new_vlan_name(master, vlan_id); + + /* + * vconfig add + */ + + if (!nm_system_iface_compat_add_vlan_device (master, vlan_id)) + goto err_out; + + /* + * get corresponding rtnl_link + */ + + if (!nm_system_iface_compat_set_name (name, iface)) + goto err_out_delete_vlan_with_default_name; + + ifindex = nm_netlink_iface_to_index (iface); + if (ifindex <= 0) + goto err_out; + + new_link = nm_netlink_index_to_rtnl_link (ifindex); + if (!new_link) + goto err_out_delete_vlan_with_default_name; + + /* + * vconfig set_flag + */ + vlan_flags = nm_setting_vlan_get_flags (s_vlan); + if (vlan_flags) + if (rtnl_link_vlan_set_flags (new_link, vlan_flags)) + goto err_out_delete_vlan_with_new_name; + + /* + * vconfig set_ingress_map + */ + num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP); + for (i = 0; i < num; i++) { + if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, i, &from, &to)) + if (rtnl_link_vlan_set_ingress_map (new_link, from, to)) + goto err_out_delete_vlan_with_new_name; + } + + /* + * vconfig set_egress_map + */ + num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP); + for (i = 0; i < num; i++) { + if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, i, &from, &to)) + if (rtnl_link_vlan_set_egress_map (new_link, from, to)) + goto err_out_delete_vlan_with_new_name; + } + + rtnl_link_put (new_link); + return TRUE; + +err_out: + g_free (name); + return FALSE; + +err_out_delete_vlan_with_default_name: + nm_system_iface_compat_rem_vlan_device (name); + g_free (name); + return FALSE; + +err_out_delete_vlan_with_new_name: + rtnl_link_put (new_link); + nm_system_iface_compat_rem_vlan_device (iface); + g_free (name); + return FALSE; +} + +/** + * nm_system_add_vlan_iface: + * @connection: the #NMConnection that describes the VLAN interface + * @iface: the interface name of the new VLAN interface + * @parent_ifindex: the interface index of the new VLAN interface's master + * interface + * + * Add a VLAN device named @iface and specified in @connection. + * + * Returns: %TRUE on success, %FALSE on failure + */ +gboolean +nm_system_add_vlan_iface (NMConnection *connection, + const char *iface, + int parent_ifindex) +{ + NMSettingVlan *s_vlan; + int ret = -1; + struct rtnl_link *new_link = NULL; + struct nl_sock *nlh = NULL; + guint32 vlan_id = 0; + guint32 vlan_flags = 0; + guint32 num, i, from, to; + + g_return_val_if_fail (parent_ifindex >= 0, FALSE); + + nlh = nm_netlink_get_default_handle (); + g_return_val_if_fail (nlh != NULL, FALSE); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan, FALSE); + + vlan_id = nm_setting_vlan_get_id (s_vlan); + + if (!iface) { + iface = nm_connection_get_virtual_iface_name (connection); + g_return_val_if_fail (iface != NULL, FALSE); + } + + new_link = rtnl_link_alloc (); + if (!new_link) { + g_warn_if_fail (new_link != NULL); + goto out; + } + + ret = rtnl_link_set_type (new_link, "vlan"); + if (ret == -NLE_OPNOTSUPP) { + /* + * There is no linbl3, try ioctl. + */ + ret = -1; + if (nm_system_iface_compat_add_vlan (connection, iface, parent_ifindex)) + ret = 0; + goto out; + } + + rtnl_link_set_link (new_link, parent_ifindex); + rtnl_link_set_name (new_link, iface); + rtnl_link_vlan_set_id (new_link, vlan_id); + + vlan_flags = nm_setting_vlan_get_flags (s_vlan); + if (vlan_flags) { + guint kernel_flags = 0; + + if (vlan_flags & NM_VLAN_FLAG_REORDER_HEADERS) + kernel_flags |= VLAN_FLAG_REORDER_HDR; + if (vlan_flags & NM_VLAN_FLAG_GVRP) + kernel_flags |= VLAN_FLAG_GVRP; + if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) + kernel_flags |= VLAN_FLAG_LOOSE_BINDING; + + rtnl_link_vlan_set_flags (new_link, kernel_flags); + } + + num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP); + for (i = 0; i < num; i++) { + if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, i, &from, &to)) + rtnl_link_vlan_set_ingress_map (new_link, (int) from, (int) to); + } + + num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP); + for (i = 0; i < num; i++) { + if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, i, &from, &to)) + rtnl_link_vlan_set_egress_map (new_link, (int) from, (int) to); + } + + ret = rtnl_link_add (nlh, new_link, NLM_F_CREATE); + +out: + if (new_link) + rtnl_link_put (new_link); + return (ret == 0); +} + +/** + * nm_system_del_vlan_iface: + * @iface: the interface name + * + * Delete a VLAN interface specified by @iface. + * + * Returns: %TRUE on success, or %FALSE + */ +gboolean +nm_system_del_vlan_iface (const char *iface) +{ + int ret = 0; + struct nl_sock *nlh = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *new_link = NULL; + int itype; + + g_return_val_if_fail (iface != NULL, FALSE); + + itype = nm_system_get_iface_type (-1, iface); + g_return_val_if_fail (itype == NM_IFACE_TYPE_VLAN, FALSE); + + nlh = nm_netlink_get_default_handle (); + g_return_val_if_fail (nlh != NULL, FALSE); + + ret = rtnl_link_alloc_cache (nlh, &cache); + g_return_val_if_fail (ret == 0, FALSE); + g_return_val_if_fail (cache != NULL, FALSE); + + new_link = rtnl_link_get_by_name (cache, iface); + if (new_link) { + ret = rtnl_link_delete (nlh, new_link); + if (ret == -NLE_OPNOTSUPP) { + /* + * There is no linbl3, try ioctl. + */ + ret = -1; + if (nm_system_iface_compat_rem_vlan_device (iface)) + ret = 0; + } + } + + rtnl_link_put (new_link); + nl_cache_free (cache); + return (ret == 0) ? TRUE : FALSE; +} diff --git a/src/nm-system.h b/src/nm-system.h index ae4e7d91..84ae6c27 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -30,6 +30,8 @@ #include <glib.h> #include "nm-device.h" #include "nm-ip4-config.h" +#include "nm-setting-bond.h" +#include "nm-setting-vlan.h" /* Prototypes for system/distribution dependent functions, * implemented in the backend files in backends/ directory @@ -56,9 +58,6 @@ struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, gboolean nm_system_iface_flush_addresses (int ifindex, int family); -void nm_system_enable_loopback (void); -void nm_system_update_dns (void); - gboolean nm_system_apply_ip4_config (int ifindex, NMIP4Config *config, int priority, @@ -83,10 +82,42 @@ gboolean nm_system_iface_set_up (int ifindex, gboolean up, gboolean *no_firmware); +guint32 nm_system_iface_get_flags (int ifindex); gboolean nm_system_iface_is_up (int ifindex); gboolean nm_system_iface_set_mtu (int ifindex, guint32 mtu); gboolean nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac); +gboolean nm_system_apply_bonding_config (const char *iface, + NMSettingBond *s_bond); +gboolean nm_system_add_bonding_master (const char *iface); + +gboolean nm_system_iface_enslave (gint master_ifindex, + const char *master_iface, + gint slave_ifindex, + const char *slave_iface); +gboolean nm_system_iface_release (gint master_ifindex, + const char *master_iface, + gint slave_ifindex, + const char *slave_iface); + +enum { + NM_IFACE_TYPE_UNSPEC = 0, + NM_IFACE_TYPE_BOND, + NM_IFACE_TYPE_VLAN, + NM_IFACE_TYPE_DUMMY, +}; + +int nm_system_get_iface_type (int ifindex, const char *name); + +gboolean nm_system_get_iface_vlan_info (int ifindex, + int *out_parent_ifindex, + int *out_vlan_id); + +gboolean nm_system_add_vlan_iface (NMConnection *connection, + const char *iface, + int parent_ifindex); +gboolean nm_system_del_vlan_iface (const char *iface); + #endif diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index e8c6b822..45262f87 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -15,32 +15,19 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2011 Red Hat, Inc. + * Copyright (C) 2009 - 2012 Red Hat, Inc. */ #include <config.h> -#include <signal.h> -#include <string.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include <unistd.h> - -#include "wireless-helper.h" +#include <net/if_arp.h> +#include <gmodule.h> #include <gudev/gudev.h> #include "nm-udev-manager.h" #include "nm-marshal.h" #include "nm-logging.h" -#include "NetworkManagerUtils.h" -#include "nm-device-wifi.h" -#include "nm-device-olpc-mesh.h" -#include "nm-device-ethernet.h" -#if WITH_WIMAX -#include "nm-device-wimax.h" -#endif +#include "nm-system.h" typedef struct { GUdevClient *client; @@ -342,69 +329,52 @@ rfkill_remove (NMUdevManager *self, } } -static gboolean -is_wireless (GUdevDevice *device) +static void +net_add (NMUdevManager *self, GUdevDevice *udev_device) { - char phy80211_path[255]; - struct stat s; - int fd; - struct iwreq iwr; - const char *ifname, *path; - gboolean is_wifi = FALSE; - - ifname = g_udev_device_get_name (device); - g_assert (ifname); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd == -1) - return FALSE; - - strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ); - - path = g_udev_device_get_sysfs_path (device); - snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path); + GUdevDevice *parent = NULL, *grandparent = NULL; + gint ifindex; + gint etype; + const char *ifname, *driver, *path, *subsys, *tmp; + gboolean is_ctc; - if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0) - || (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) - is_wifi = TRUE; + g_return_if_fail (udev_device != NULL); - close (fd); - return is_wifi; -} + ifname = g_udev_device_get_name (udev_device); + if (!ifname) { + nm_log_dbg (LOGD_HW, "failed to get device's interface"); + return; + } -static gboolean -is_olpc_mesh (GUdevDevice *device) -{ - const gchar *prop = g_udev_device_get_property (device, "ID_NM_OLPC_MESH"); - return (prop != NULL); -} + etype = g_udev_device_get_sysfs_attr_as_int (udev_device, "type"); + is_ctc = (strncmp (ifname, "ctc", 3) == 0) && (etype == 256); -static gboolean -is_wimax (const char *driver) -{ - /* FIXME: check 'DEVTYPE' instead; but since we only support Intel - * WiMAX devices for now this is appropriate. + /* Ignore devices that don't report Ethernet encapsulation, except for + * s390 CTC-type devices that report 256 for some reason. + * FIXME: use something other than interface name to detect CTC here. */ - return g_strcmp0 (driver, "i2400m_usb") == 0; -} - -static GObject * -device_creator (NMUdevManager *manager, - GUdevDevice *udev_device, - gboolean sleeping) -{ - GObject *device = NULL; - const char *ifname, *driver, *path, *subsys; - GUdevDevice *parent = NULL, *grandparent = NULL; - gint ifindex; + if ((etype != ARPHRD_ETHER) && (etype != ARPHRD_INFINIBAND) && (is_ctc == FALSE)) { + nm_log_dbg (LOGD_HW, "(%s): ignoring interface with type %d", ifname, etype); + return; + } - ifname = g_udev_device_get_name (udev_device); - g_assert (ifname); + /* Not all ethernet devices are immediately usable; newer mobile broadband + * devices (Ericsson, Option, Sierra) require setup on the tty before the + * ethernet device is usable. 2.6.33 and later kernels set the 'DEVTYPE' + * uevent variable which we can use to ignore the interface as a NMDevice + * subclass. ModemManager will pick it up though and so we'll handle it + * through the mobile broadband stuff. + */ + tmp = g_udev_device_get_property (udev_device, "DEVTYPE"); + if (g_strcmp0 (tmp, "wwan") == 0) { + nm_log_dbg (LOGD_HW, "(%s): ignoring interface with devtype '%s'", ifname, tmp); + return; + } path = g_udev_device_get_sysfs_path (udev_device); if (!path) { nm_log_warn (LOGD_HW, "couldn't determine device path; ignoring..."); - return NULL; + return; } driver = g_udev_device_get_driver (udev_device); @@ -429,94 +399,39 @@ device_creator (NMUdevManager *manager, } } - if (!driver) { - if (g_str_has_prefix (ifname, "easytether")) { - driver = "easytether"; - } else { - nm_log_warn (LOGD_HW, "%s: couldn't determine device driver; ignoring...", path); - goto out; - } - } - ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); if (ifindex <= 0) { nm_log_warn (LOGD_HW, "%s: device had invalid ifindex %d; ignoring...", path, (guint32) ifindex); goto out; } - if (is_olpc_mesh (udev_device)) /* must be before is_wireless */ - device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver); - else if (is_wireless (udev_device)) - device = (GObject *) nm_device_wifi_new (path, ifname, driver); - else if (is_wimax (driver)) { -#if WITH_WIMAX - device = (GObject *) nm_device_wimax_new (path, ifname, driver); -#endif - } else - device = (GObject *) nm_device_ethernet_new (path, ifname, driver); + if (!driver) { + switch (nm_system_get_iface_type (ifindex, ifname)) { + case NM_IFACE_TYPE_BOND: + driver = "bonding"; + break; + case NM_IFACE_TYPE_VLAN: + driver = "8021q"; + break; + default: + if (g_str_has_prefix (ifname, "easytether")) + driver = "easytether"; + break; + } + + if (!driver) { + nm_log_warn (LOGD_HW, "%s: couldn't determine device driver; ignoring...", path); + goto out; + } + } + + g_signal_emit (self, signals[DEVICE_ADDED], 0, udev_device, ifname, path, driver, ifindex); out: if (grandparent) g_object_unref (grandparent); if (parent) g_object_unref (parent); - return device; -} - -static void -net_add (NMUdevManager *self, GUdevDevice *device) -{ - gint etype; - const char *iface; - const char *tmp; - gboolean is_ctc; - - g_return_if_fail (device != NULL); - - iface = g_udev_device_get_name (device); - if (!iface) { - nm_log_dbg (LOGD_HW, "failed to get device's interface"); - return; - } - - etype = g_udev_device_get_sysfs_attr_as_int (device, "type"); - is_ctc = (strncmp (iface, "ctc", 3) == 0) && (etype == 256); - - /* Ignore devices that don't report Ethernet encapsulation, except for - * s390 CTC-type devices that report 256 for some reason. - * FIXME: use something other than interface name to detect CTC here. - */ - if ((etype != 1) && (is_ctc == FALSE)) { - nm_log_dbg (LOGD_HW, "(%s): ignoring interface with type %d", iface, etype); - return; - } - - /* Not all ethernet devices are immediately usable; newer mobile broadband - * devices (Ericsson, Option, Sierra) require setup on the tty before the - * ethernet device is usable. 2.6.33 and later kernels set the 'DEVTYPE' - * uevent variable which we can use to ignore the interface as a NMDevice - * subclass. ModemManager will pick it up though and so we'll handle it - * through the mobile broadband stuff. - */ - tmp = g_udev_device_get_property (device, "DEVTYPE"); - if (g_strcmp0 (tmp, "wwan") == 0) { - nm_log_dbg (LOGD_HW, "(%s): ignoring interface with devtype '%s'", iface, tmp); - return; - } - - /* Ignore Nokia cdc-ether interfaces in PC-Suite mode since we need to - * talk phonet to use them, which ModemManager doesn't do yet. - */ - tmp = g_udev_device_get_property (device, "ID_VENDOR_ID"); - if (g_strcmp0 (tmp, "0421") == 0) { /* Nokia vendor ID */ - tmp = g_udev_device_get_property (device, "ID_MODEL"); - if (tmp && (strstr (tmp, "PC-Suite") || strstr (tmp, "PC Suite"))) { - nm_log_dbg (LOGD_HW, "(%s): ignoring Nokia PC-Suite ethernet interface", iface); - return; - } - } - - g_signal_emit (self, signals[DEVICE_ADDED], 0, device, device_creator); } static void @@ -638,8 +553,8 @@ nm_udev_manager_class_init (NMUdevManagerClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMUdevManagerClass, device_added), NULL, NULL, - _nm_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); + _nm_marshal_VOID__POINTER_POINTER_POINTER_POINTER_INT, + G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_INT); signals[DEVICE_REMOVED] = g_signal_new ("device-removed", diff --git a/src/nm-udev-manager.h b/src/nm-udev-manager.h index e7866f96..61d3b7cf 100644 --- a/src/nm-udev-manager.h +++ b/src/nm-udev-manager.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. */ #ifndef NM_UDEV_MANAGER_H @@ -52,7 +52,10 @@ typedef struct { /* Virtual functions */ void (*device_added) (NMUdevManager *manager, GUdevDevice *device, - NMDeviceCreatorFn creator_fn); + const char *iface, + const char *sysfs_path, + const char *driver, + int ifindex); void (*device_removed) (NMUdevManager *manager, GUdevDevice *device); diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index be836df0..92a99b69 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -19,10 +19,9 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include "wireless-helper.h" - #include <string.h> #include <stdlib.h> +#include <netinet/ether.h> #include "nm-wifi-ap.h" #include "nm-wifi-ap-utils.h" @@ -30,7 +29,7 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-dbus-manager.h" -#include "wpa.h" + #include "nm-properties-changed-signal.h" #include "nm-setting-wireless.h" #include "nm-glib-compat.h" @@ -43,6 +42,7 @@ typedef struct { char *dbus_path; + char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */ /* Scanned or cached values */ GByteArray * ssid; @@ -107,6 +107,7 @@ finalize (GObject *object) NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object); g_free (priv->dbus_path); + g_free (priv->supplicant_path); if (priv->ssid) g_byte_array_free (priv->ssid, TRUE); @@ -183,7 +184,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->freq); break; case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop (&priv->address)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->address, ARPHRD_ETHER)); break; case PROP_MODE: g_value_set_uint (value, priv->mode); @@ -346,15 +347,10 @@ nm_ap_export_to_dbus (NMAccessPoint *ap) * Create a new, blank user access point info structure * */ -NMAccessPoint *nm_ap_new (void) +static NMAccessPoint * +nm_ap_new (void) { - GObject *object; - - object = g_object_new (NM_TYPE_AP, NULL); - if (!object) - return NULL; - - return (NMAccessPoint *) object; + return (NMAccessPoint *) g_object_new (NM_TYPE_AP, NULL); } static NM80211ApSecurityFlags @@ -431,7 +427,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) GArray *array = g_value_get_boxed (variant); if (!strcmp (key, "SSID")) { - guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len); + guint32 len = MIN (32, array->len); GByteArray *ssid; /* Stupid ieee80211 layer uses <hidden> */ @@ -510,7 +506,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) } NMAccessPoint * -nm_ap_new_from_properties (GHashTable *properties) +nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties) { NMAccessPoint *ap; GTimeVal cur_time; @@ -525,6 +521,8 @@ nm_ap_new_from_properties (GHashTable *properties) g_object_freeze_notify (G_OBJECT (ap)); g_hash_table_foreach (properties, foreach_property_cb, ap); + nm_ap_set_supplicant_path (ap, supplicant_path); + /* ignore APs with invalid BSSIDs */ addr = nm_ap_get_address (ap); if ( !(memcmp (addr->ether_addr_octet, bad_bssid1, ETH_ALEN)) @@ -635,7 +633,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection) g_return_val_if_fail (connection != NULL, NULL); - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wireless != NULL, NULL); ssid = nm_setting_wireless_get_ssid (s_wireless); @@ -672,7 +670,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection) nm_ap_set_freq (ap, freq); } - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); /* Assume presence of a security setting means the AP is encrypted */ if (!s_wireless_sec) goto done; @@ -784,6 +782,24 @@ nm_ap_get_dbus_path (NMAccessPoint *ap) return NM_AP_GET_PRIVATE (ap)->dbus_path; } +const char * +nm_ap_get_supplicant_path (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_AP (ap), NULL); + + return NM_AP_GET_PRIVATE (ap)->supplicant_path; +} + +void +nm_ap_set_supplicant_path (NMAccessPoint *ap, const char *path) +{ + g_return_if_fail (NM_IS_AP (ap)); + g_return_if_fail (path != NULL); + + g_free (NM_AP_GET_PRIVATE (ap)->supplicant_path); + NM_AP_GET_PRIVATE (ap)->supplicant_path = g_strdup (path); +} + /* * Get/set functions for ssid * @@ -1130,7 +1146,7 @@ nm_ap_check_compatible (NMAccessPoint *self, priv = NM_AP_GET_PRIVATE (self); - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); if (s_wireless == NULL) return FALSE; @@ -1168,8 +1184,7 @@ nm_ap_check_compatible (NMAccessPoint *self, return FALSE; } - s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); return nm_setting_wireless_ap_security_compatible (s_wireless, s_wireless_sec, diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h index 31100d34..a0087323 100644 --- a/src/nm-wifi-ap.h +++ b/src/nm-wifi-ap.h @@ -57,13 +57,17 @@ typedef struct { GType nm_ap_get_type (void); -NMAccessPoint * nm_ap_new (void); -NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties); +NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path, + GHashTable *properties); NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection); void nm_ap_export_to_dbus (NMAccessPoint *ap); const char * nm_ap_get_dbus_path (NMAccessPoint *ap); +const char * nm_ap_get_supplicant_path (NMAccessPoint *ap); +void nm_ap_set_supplicant_path (NMAccessPoint *ap, + const char *path); + const GByteArray * nm_ap_get_ssid (const NMAccessPoint * ap); void nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid); diff --git a/src/NetworkManager.conf b/src/org.freedesktop.NetworkManager.conf index 15b11b7e..15b11b7e 100644 --- a/src/NetworkManager.conf +++ b/src/org.freedesktop.NetworkManager.conf diff --git a/src/ppp-manager/Makefile.am b/src/ppp-manager/Makefile.am index 540e5855..8df2f584 100644 --- a/src/ppp-manager/Makefile.am +++ b/src/ppp-manager/Makefile.am @@ -1,10 +1,13 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ + -I${top_srcdir}/src/logging noinst_LTLIBRARIES = libppp-manager.la @@ -28,7 +31,7 @@ libppp_manager_la_CPPFLAGS = \ -DPLUGINDIR=\"$(PPPD_PLUGIN_DIR)\" libppp_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in index 90f855b3..55355a7d 100644 --- a/src/ppp-manager/Makefile.in +++ b/src/ppp-manager/Makefile.in @@ -79,7 +79,7 @@ am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pppd_plugin_LTLIBRARIES) am__DEPENDENCIES_1 = libppp_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libppp_manager_la_OBJECTS = libppp_manager_la-nm-ppp-manager.lo @@ -177,6 +177,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -231,11 +233,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -246,6 +252,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -285,6 +292,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -351,10 +360,13 @@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ + -I${top_srcdir}/src/logging noinst_LTLIBRARIES = libppp-manager.la libppp_manager_la_SOURCES = \ @@ -371,7 +383,7 @@ libppp_manager_la_CPPFLAGS = \ -DPLUGINDIR=\"$(PPPD_PLUGIN_DIR)\" libppp_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 3546f8d7..59698c34 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #include <config.h> @@ -374,7 +374,7 @@ extract_details_from_connection (NMConnection *connection, g_return_val_if_fail (username != NULL, FALSE); g_return_val_if_fail (password != NULL, FALSE); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); connection_type = nm_setting_connection_get_connection_type (s_con); @@ -579,7 +579,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); /* Merge in custom MTU */ - s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + s_ppp = nm_connection_get_setting_ppp (connection); if (s_ppp) { guint32 mtu = nm_setting_ppp_get_mtu (s_ppp); @@ -935,12 +935,6 @@ pppoe_fill_defaults (NMSettingPPP *setting) if (!nm_setting_ppp_get_mru (setting)) g_object_set (setting, NM_SETTING_PPP_MRU, (guint32) 1492, NULL); - if (!nm_setting_ppp_get_lcp_echo_interval (setting)) - g_object_set (setting, NM_SETTING_PPP_LCP_ECHO_INTERVAL, (guint32) 20, NULL); - - if (!nm_setting_ppp_get_lcp_echo_failure (setting)) - g_object_set (setting, NM_SETTING_PPP_LCP_ECHO_FAILURE, (guint32) 3, NULL); - g_object_set (setting, NM_SETTING_PPP_NOAUTH, TRUE, NM_SETTING_PPP_NODEFLATE, TRUE, @@ -999,7 +993,7 @@ nm_ppp_manager_start (NMPPPManager *manager, connection = nm_act_request_get_connection (req); g_assert (connection); - s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { /* If the PPP settings are all default we may not have a PPP setting yet, * so just make a default one here. @@ -1008,7 +1002,7 @@ nm_ppp_manager_start (NMPPPManager *manager, s_ppp_created = TRUE; } - pppoe_setting = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); + pppoe_setting = nm_connection_get_setting_pppoe (connection); if (pppoe_setting) pppoe_fill_defaults (s_ppp); diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index 21dc5bb0..8024d541 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -2,10 +2,13 @@ SUBDIRS=plugins . tests INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la @@ -64,7 +67,7 @@ libsettings_la_CPPFLAGS = \ libsettings_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ $(DBUS_LIBS) \ diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in index b4f4508f..d1278206 100644 --- a/src/settings/Makefile.in +++ b/src/settings/Makefile.in @@ -58,7 +58,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libsettings_la_DEPENDENCIES = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -203,6 +203,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -257,11 +259,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -272,6 +278,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -311,6 +318,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -377,10 +386,13 @@ top_srcdir = @top_srcdir@ SUBDIRS = plugins . tests INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src \ - -I${top_builddir}/marshallers + -I${top_srcdir}/src noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la libtest_settings_utils_la_SOURCES = \ @@ -438,7 +450,7 @@ libsettings_la_CPPFLAGS = \ libsettings_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ $(DBUS_LIBS) \ diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 5ccbdc67..b7057400 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -36,6 +36,7 @@ #include "nm-manager-auth.h" #include "nm-setting-vpn.h" #include "nm-setting-connection.h" +#include "nm-enum-types.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -88,17 +89,6 @@ static void impl_agent_manager_unregister (NMAgentManager *self, /********************************************************************/ #define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ()) -#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) - -typedef enum { - NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, - NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, - NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, - NM_AGENT_MANAGER_ERROR_NO_SECRETS -} NMAgentManagerError; static GQuark nm_agent_manager_error_quark (void) @@ -110,37 +100,6 @@ nm_agent_manager_error_quark (void) return ret; } -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_agent_manager_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Unable to determine caller's sender or UID */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "SenderUnknown"), - /* Permission for some operation was denied */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"), - /* The caller's session could not be determined */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "SessionNotFound"), - /* The identifier was invalid */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "InvalidIdentifier"), - /* Request was not from a registered agent */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"), - /* Some internal error occurred */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"), - /* No secrets were available */ - ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NoSecrets"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("NMAgentManagerError", values); - } - return etype; -} - /*************************************************************/ static gboolean @@ -962,7 +921,7 @@ get_next_cb (Request *req) * we use the 'modify.own' permission instead of 'modify.system'. If the * request affects more than just the caller, require 'modify.system'. */ - s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (req->connection); g_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index e49f579d..9e8de44b 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -34,6 +34,16 @@ #define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) #define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) +typedef enum { + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, /*< nick=SenderUnknown >*/ + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, /*< nick=SessionNotFound >*/ + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, /*< nick=InvalidIdentifier >*/ + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, /*< nick=NotRegistered >*/ + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, /*< nick=InternalError >*/ + NM_AGENT_MANAGER_ERROR_NO_SECRETS /*< nick=NoSecrets >*/ +} NMAgentManagerError; + typedef struct { GObject parent; } NMAgentManager; diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index cdad8325..5d240c77 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -221,7 +221,7 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self) priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); g_assert (s_con); /* Check every user in the ACL for a session */ @@ -1024,7 +1024,7 @@ check_writable (NMConnection *connection, GError **error) g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if (!s_con) { g_set_error_literal (error, NM_SETTINGS_ERROR, @@ -1175,11 +1175,11 @@ get_modify_permission_update (NMConnection *old, NMConnection *new) NMSettingConnection *s_con; guint32 orig_num = 0, new_num = 0; - s_con = (NMSettingConnection *) nm_connection_get_setting (old, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (old); g_assert (s_con); orig_num = nm_setting_connection_get_num_permissions (s_con); - s_con = (NMSettingConnection *) nm_connection_get_setting (new, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (new); g_assert (s_con); new_num = nm_setting_connection_get_num_permissions (s_con); @@ -1283,7 +1283,7 @@ get_modify_permission_basic (NMSettingsConnection *connection) * we use the 'modify.own' permission instead of 'modify.system'. If the * request affects more than just the caller, require 'modify.system'. */ - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; @@ -1422,11 +1422,14 @@ nm_settings_connection_get_timestamp (NMSettingsConnection *connection) * @connection: the #NMSettingsConnection * @timestamp: timestamp to set into the connection and to store into * the timestamps database + * @flush_to_disk: if %TRUE, commit timestamp update to persistent storage * * Updates the connection and timestamps database with the provided timestamp. **/ void -nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp) +nm_settings_connection_update_timestamp (NMSettingsConnection *connection, + guint64 timestamp, + gboolean flush_to_disk) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); const char *connection_uuid; @@ -1438,6 +1441,9 @@ nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint /* Update timestamp in private storage */ priv->timestamp = timestamp; + if (flush_to_disk == FALSE) + return; + /* Save timestamp to timestamps database file */ timestamps_file = g_key_file_new (); if (!g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, &error)) { @@ -1576,7 +1582,7 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, return; /* Already in the list */ /* Add the new BSSID; let the hash take ownership of the allocated BSSID string */ - bssid_str = nm_ether_ntop (seen_bssid); + bssid_str = nm_utils_hwaddr_ntoa (seen_bssid, ARPHRD_ETHER); g_return_if_fail (bssid_str != NULL); g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str); diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index bc9e3c47..077a145d 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -124,7 +124,9 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self); guint64 nm_settings_connection_get_timestamp (NMSettingsConnection *connection); -void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp); +void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, + guint64 timestamp, + gboolean flush_to_disk); void nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection); diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c index 7e24fb71..fd4eca36 100644 --- a/src/settings/nm-settings-error.c +++ b/src/settings/nm-settings-error.c @@ -31,53 +31,3 @@ nm_settings_error_quark (void) return ret; } - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_settings_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - ENUM_ENTRY (NM_SETTINGS_ERROR_GENERAL, "GeneralError"), - - /* The connection was invalid. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"), - /* The connection is read-only; modifications are not allowed. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), - /* A bug in the settings service caused the error. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"), - /* Retrieval or request of secrets failed. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), - /* The request for secrets was canceled. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), - /* The request could not be completed because permission was denied. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), - /* The requested setting does not existing in this connection. */ - ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), - /* The caller does not have permission to perform this operation */ - ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), - /* No plugin supports adding new connections */ - ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), - /* The plugin providing this connection does not support updating it */ - ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), - /* The plugin providing this connection does not support deleting it */ - ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), - /* Failed to add the connection */ - ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), - /* No plugin supports modifying the system hostname */ - ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), - /* Saving the system hostname failed */ - ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), - /* A connection with this UUID already exists */ - ENUM_ENTRY (NM_SETTINGS_ERROR_UUID_EXISTS, "UuidExists"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("NMSettingsError", values); - } - - return etype; -} diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h index b782a779..82132c6f 100644 --- a/src/settings/nm-settings-error.h +++ b/src/settings/nm-settings-error.h @@ -25,24 +25,24 @@ #include <glib.h> #include <glib-object.h> -enum { - NM_SETTINGS_ERROR_GENERAL = 0, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, - NM_SETTINGS_ERROR_INTERNAL_ERROR, - NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, - NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_SETTINGS_ERROR_INVALID_SETTING, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, - NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, - NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, - NM_SETTINGS_ERROR_ADD_FAILED, - NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, - NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, - NM_SETTINGS_ERROR_UUID_EXISTS, -}; +typedef enum { + NM_SETTINGS_ERROR_GENERAL = 0, /*< nick=GeneralError >*/ + NM_SETTINGS_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, /*< nick=ReadOnlyConnection >*/ + NM_SETTINGS_ERROR_INTERNAL_ERROR, /*< nick=InternalError >*/ + NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, /*< nick=SecretsUnavailable >*/ + NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, /*< nick=SecretsRequestCanceled >*/ + NM_SETTINGS_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_SETTINGS_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ + NM_SETTINGS_ERROR_NOT_PRIVILEGED, /*< nick=NotPrivileged >*/ + NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, /*< nick=AddNotSupported >*/ + NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, /*< nick=UpdateNotSupported >*/ + NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, /*< nick=DeleteNotSupported >*/ + NM_SETTINGS_ERROR_ADD_FAILED, /*< nick=AddFailed >*/ + NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, /*< nick=SaveHostnameNotSupported >*/ + NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, /*< nick=SaveHostnameFailed >*/ + NM_SETTINGS_ERROR_UUID_EXISTS, /*< nick=UuidExists >*/ +} NMSettingsError; #define NM_SETTINGS_ERROR (nm_settings_error_quark ()) GQuark nm_settings_error_quark (void); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index f0bfc162..1ead4f8b 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -29,8 +29,7 @@ #include <string.h> #include <ctype.h> #include <gmodule.h> -#include <net/ethernet.h> -#include <netinet/ether.h> +#include <net/if_arp.h> #include <pwd.h> #include <dbus/dbus.h> #include <dbus/dbus-glib-lowlevel.h> @@ -52,8 +51,11 @@ #include <nm-setting-wired.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> +#include <nm-setting-bond.h> +#include <nm-utils.h> #include "../nm-device-ethernet.h" +#include "../nm-device-wired.h" #include "nm-dbus-glib-types.h" #include "nm-settings.h" #include "nm-settings-connection.h" @@ -226,36 +228,49 @@ impl_settings_list_connections (NMSettings *self, return TRUE; } -static gboolean -impl_settings_get_connection_by_uuid (NMSettings *self, - const char *uuid, - char **out_object_path, - GError **error) +NMSettingsConnection * +nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv; + NMSettingsConnection *candidate; GHashTableIter iter; - NMConnection *candidate = NULL; - gboolean found = FALSE; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + g_return_val_if_fail (uuid != NULL, NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); load_connections (self); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (uuid, nm_connection_get_uuid (candidate)) == 0) { - *out_object_path = g_strdup (nm_connection_get_path (candidate)); - found = TRUE; - break; - } + if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0) + return candidate; } - if (!found) { + return NULL; +} + +static gboolean +impl_settings_get_connection_by_uuid (NMSettings *self, + const char *uuid, + char **out_object_path, + GError **error) +{ + NMSettingsConnection *connection = NULL; + + connection = nm_settings_get_connection_by_uuid (self, uuid); + if (connection) + *out_object_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); + else { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No connection with the UUID was found."); } - return found; + return !!connection; } static int @@ -267,9 +282,9 @@ connection_sort (gconstpointer pa, gconstpointer pb) NMSettingConnection *con_b; guint64 ts_a, ts_b; - con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); + con_a = nm_connection_get_setting_connection (a); g_assert (con_a); - con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + con_b = nm_connection_get_setting_connection (b); g_assert (con_b); if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { @@ -549,6 +564,7 @@ find_plugin (GSList *list, const char *pname) static gboolean load_plugins (NMSettings *self, const char **plugins, GError **error) { + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *list = NULL; const char **iter; gboolean success = TRUE; @@ -558,7 +574,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) char *full_name, *path; const char *pname = *iter; GObject *obj; - GObject * (*factory_func) (void); + GObject * (*factory_func) (const char *); /* strip leading spaces */ while (isblank (*pname)) @@ -601,7 +617,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) break; } - obj = (*factory_func) (); + obj = (*factory_func) (priv->config_file); if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) { g_set_error (error, 0, 0, "Plugin '%s' returned invalid system config object.", @@ -901,6 +917,45 @@ add_new_connection (NMSettings *self, return NULL; } +static gboolean +secrets_filter_cb (NMSetting *setting, + const char *secret, + NMSettingSecretFlags flags, + gpointer user_data) +{ + NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data); + + /* Returns TRUE to remove the secret */ + + /* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */ + if ( (flags == NM_SETTING_SECRET_FLAG_NONE) + && (filter_flags == NM_SETTING_SECRET_FLAG_NONE)) + return FALSE; + + /* Otherwise if the secret has at least one of the desired flags keep it */ + return (flags & filter_flags) ? FALSE : TRUE; +} + +static void +send_agent_owned_secrets (NMSettings *self, + NMSettingsConnection *connection, + gulong caller_uid) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMConnection *for_agent; + + /* Dupe the connection so we can clear out non-agent-owned secrets, + * as agent-owned secrets are the only ones we send back to be saved. + * Only send secrets to agents of the same UID that called update too. + */ + for_agent = nm_connection_duplicate (NM_CONNECTION (connection)); + nm_connection_clear_secrets_with_flags (for_agent, + secrets_filter_cb, + GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); + nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, caller_uid); + g_object_unref (for_agent); +} + static void pk_add_cb (NMAuthChain *chain, GError *chain_error, @@ -915,6 +970,7 @@ pk_add_cb (NMAuthChain *chain, NMSettingsConnection *added = NULL; NMSettingsAddCallback callback; gpointer callback_data; + gulong caller_uid; const char *perm; priv->auths = g_slist_remove (priv->auths, chain); @@ -954,9 +1010,14 @@ pk_add_cb (NMAuthChain *chain, done: callback = nm_auth_chain_get_data (chain, "callback"); callback_data = nm_auth_chain_get_data (chain, "callback-data"); + caller_uid = nm_auth_chain_get_data_ulong (chain, "caller-uid"); callback (self, added, error, context, callback_data); + /* Send agent-owned secrets to the agents */ + if (!error && added) + send_agent_owned_secrets (self, added, caller_uid); + g_clear_error (&error); nm_auth_chain_unref (chain); } @@ -974,6 +1035,38 @@ add_cb (NMSettings *self, dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection))); } +/* FIXME: remove if/when kernel supports adhoc wpa */ +static gboolean +is_adhoc_wpa (NMConnection *connection) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char *mode, *key_mgmt; + + /* The kernel doesn't support Ad-Hoc WPA connections well at this time, + * and turns them into open networks. It's been this way since at least + * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. + */ + + s_wifi = nm_connection_get_setting_wireless (connection); + if (!s_wifi) + return FALSE; + + mode = nm_setting_wireless_get_mode (s_wifi); + if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) != 0) + return FALSE; + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (!s_wsec) + return FALSE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + if (g_strcmp0 (key_mgmt, "wpa-none") != 0) + return FALSE; + + return TRUE; +} + void nm_settings_add_connection (NMSettings *self, NMConnection *connection, @@ -1001,6 +1094,19 @@ nm_settings_add_connection (NMSettings *self, return; } + /* The kernel doesn't support Ad-Hoc WPA connections well at this time, + * and turns them into open networks. It's been this way since at least + * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. + */ + if (is_adhoc_wpa (connection)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "WPA Ad-Hoc disabled due to kernel bugs"); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { error = g_error_new_literal (NM_SETTINGS_ERROR, @@ -1044,7 +1150,7 @@ nm_settings_add_connection (NMSettings *self, * we use the 'modify.own' permission instead of 'modify.system'. If the * request affects more than just the caller, require 'modify.system'. */ - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; @@ -1060,6 +1166,7 @@ nm_settings_add_connection (NMSettings *self, nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); nm_auth_chain_set_data (chain, "callback", callback, NULL); nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); + nm_auth_chain_set_data_ulong (chain, "caller-uid", caller_uid); } static void @@ -1172,13 +1279,14 @@ impl_settings_save_hostname (NMSettings *self, } static gboolean -have_connection_for_device (NMSettings *self, GByteArray *mac) +have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; + NMSettingInfiniband *s_infiniband; const GByteArray *setting_mac; gboolean ret = FALSE; @@ -1189,16 +1297,27 @@ have_connection_for_device (NMSettings *self, GByteArray *mac) g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) { NMConnection *connection = NM_CONNECTION (data); - const char *ctype; + const char *ctype, *iface; s_con = nm_connection_get_setting_connection (connection); ctype = nm_setting_connection_get_connection_type (s_con); + iface = nm_connection_get_virtual_iface_name (connection); + if (iface) { + if (!strcmp (iface, nm_device_get_iface (device))) { + ret = TRUE; + break; + } else + continue; + } + if ( strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) + && strcmp (ctype, NM_SETTING_INFINIBAND_SETTING_NAME) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; s_wired = nm_connection_get_setting_wired (connection); + s_infiniband = nm_connection_get_setting_infiniband (connection); /* No wired setting; therefore the PPPoE connection applies to any device */ if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { @@ -1206,10 +1325,15 @@ have_connection_for_device (NMSettings *self, GByteArray *mac) break; } - setting_mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (s_wired != NULL || s_infiniband != NULL); + + setting_mac = s_wired ? + nm_setting_wired_get_mac_address (s_wired) : + nm_setting_infiniband_get_mac_address (s_infiniband); if (setting_mac) { /* A connection mac-locked to this device */ - if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) { + if (mac->len == setting_mac->len && + !memcmp (setting_mac->data, mac->data, mac->len)) { ret = TRUE; break; } @@ -1225,7 +1349,7 @@ have_connection_for_device (NMSettings *self, GByteArray *mac) /* Search through the list of blacklisted MAC addresses in the config file. */ static gboolean -is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) +is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac, int hwaddr_type) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GKeyFile *config; @@ -1249,15 +1373,15 @@ is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); for (iter = list; iter && *iter; iter++) { - struct ether_addr *candidate; + guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX]; - if (strcmp(g_strstrip(*iter), "*") == 0) { + if (strcmp (g_strstrip (*iter), "*") == 0) { found = TRUE; break; } - candidate = ether_aton (*iter); - if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { + candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer); + if (candidate && !memcmp (mac->data, candidate, mac->len)) { found = TRUE; break; } @@ -1280,6 +1404,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired, { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingConnection *s_con; + int hwaddr_type; char *tmp; GKeyFile *config; char **list, **iter, **updated; @@ -1297,8 +1422,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired, * connection for that device again. */ - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired), - NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (wired)); g_assert (s_con); /* Ignore removals of read-only connections, since they couldn't have @@ -1311,20 +1435,27 @@ default_wired_deleted (NMDefaultWiredConnection *wired, if (!config) goto cleanup; + if (nm_connection_get_setting_wired (NM_CONNECTION (wired))) + hwaddr_type = ARPHRD_ETHER; + else if (nm_connection_get_setting_infiniband (NM_CONNECTION (wired))) + hwaddr_type = ARPHRD_INFINIBAND; + else + goto cleanup; + g_key_file_set_list_separator (config, ','); g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL); list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); for (iter = list; iter && *iter; iter++) { - struct ether_addr *candidate; + guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX]; - if (strcmp(g_strstrip(*iter), "*") == 0) { + if (strcmp (g_strstrip (*iter), "*") == 0) { found = TRUE; break; } - candidate = ether_aton (*iter); - if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { + candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer); + if (candidate && !memcmp (mac->data, candidate, mac->len)) { found = TRUE; break; } @@ -1332,9 +1463,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired, /* Add this device's MAC to the list */ if (!found) { - tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x", - mac->data[0], mac->data[1], mac->data[2], - mac->data[3], mac->data[4], mac->data[5]); + tmp = nm_utils_hwaddr_ntoa (mac->data, hwaddr_type); /* New list; size + 1 for the new element, + 1 again for ending NULL */ updated = g_malloc0 (sizeof (char*) * (len + 2)); @@ -1424,13 +1553,14 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GByteArray *mac = NULL; - struct ether_addr tmp; + const guint8 *hwaddr; + int hwaddr_type; NMDefaultWiredConnection *wired; gboolean read_only = TRUE; const char *id; char *defname; - if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + if (!NM_IS_DEVICE_WIRED (device)) return; /* If the device isn't managed or it already has a default wired connection, @@ -1440,13 +1570,14 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG)) return; - nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp); + hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)); + hwaddr_type = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (device)); - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN); + mac = g_byte_array_new (); + g_byte_array_append (mac, hwaddr, nm_utils_hwaddr_len (hwaddr_type)); - if ( have_connection_for_device (self, mac) - || is_mac_auto_wired_blacklisted (self, mac)) + if ( have_connection_for_device (self, mac, device) + || is_mac_auto_wired_blacklisted (self, mac, hwaddr_type)) goto ignore; if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) @@ -1480,7 +1611,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device) { NMDefaultWiredConnection *connection; - if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + if (!NM_IS_DEVICE_WIRED (device)) return; connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); @@ -1518,7 +1649,7 @@ nm_settings_new (const char *config_file, } /* Add the keyfile plugin last */ - keyfile_plugin = nm_settings_keyfile_plugin_new (); + keyfile_plugin = nm_settings_keyfile_plugin_new (config_file); g_assert (keyfile_plugin); add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin)); diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 77485e19..9a02f8fe 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -108,6 +108,9 @@ GSList *nm_settings_get_connections (NMSettings *settings); NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings, const char *path); +NMSettingsConnection *nm_settings_get_connection_by_uuid (NMSettings *settings, + const char *uuid); + const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); char *nm_settings_get_hostname (NMSettings *self); diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index 96a64061..bbe74d49 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -39,7 +39,7 @@ G_BEGIN_DECLS /* Plugin's factory function that returns a GObject that implements * NMSystemConfigInterface. */ -GObject * nm_system_config_factory (void); +GObject * nm_system_config_factory (const char *config_file); #define NM_TYPE_SYSTEM_CONFIG_INTERFACE (nm_system_config_interface_get_type ()) #define NM_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in index 7c9c8784..0997f445 100644 --- a/src/settings/plugins/Makefile.in +++ b/src/settings/plugins/Makefile.in @@ -152,6 +152,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -206,11 +208,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -221,6 +227,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -260,6 +267,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/settings/plugins/ifcfg-rh/Makefile.am b/src/settings/plugins/ifcfg-rh/Makefile.am index 9874d352..8b5b0f24 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/Makefile.am @@ -23,11 +23,12 @@ libifcfg_rh_io_la_SOURCES = \ utils.h INCLUDES = \ + -I$(top_srcdir)/src/wifi \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/marshallers + -I$(top_srcdir)/libnm-util libifcfg_rh_io_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ @@ -38,6 +39,7 @@ libifcfg_rh_io_la_CPPFLAGS = \ -DSBINDIR=\"$(sbindir)\" libifcfg_rh_io_la_LIBADD = \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(GLIB_LIBS) \ $(NSS_LIBS) @@ -59,7 +61,6 @@ libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib.la \ - $(top_builddir)/marshallers/libmarshallers.la \ libifcfg-rh-io.la \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in index 79b66b2d..3325c7e8 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -81,6 +81,7 @@ am__installdirs = "$(DESTDIR)$(pkglibdir)" \ LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = libifcfg_rh_io_la_DEPENDENCIES = \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_libifcfg_rh_io_la_OBJECTS = libifcfg_rh_io_la-shvar.lo \ @@ -92,9 +93,8 @@ am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - $(top_builddir)/marshallers/libmarshallers.la \ - libifcfg-rh-io.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(top_builddir)/libnm-glib/libnm-glib.la libifcfg-rh-io.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \ libnm_settings_plugin_ifcfg_rh_la-plugin.lo \ @@ -222,6 +222,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -276,11 +278,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -291,6 +297,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -330,6 +337,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -412,11 +421,12 @@ libifcfg_rh_io_la_SOURCES = \ utils.h INCLUDES = \ + -I$(top_srcdir)/src/wifi \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/marshallers + -I$(top_srcdir)/libnm-util libifcfg_rh_io_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ @@ -427,6 +437,7 @@ libifcfg_rh_io_la_CPPFLAGS = \ -DSBINDIR=\"$(sbindir)\" libifcfg_rh_io_la_LIBADD = \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(GLIB_LIBS) \ $(NSS_LIBS) @@ -448,7 +459,6 @@ libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib.la \ - $(top_builddir)/marshallers/libmarshallers.la \ libifcfg-rh-io.la \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index 74a77c4c..fc8ce22a 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 - 2010 Red Hat, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. */ #ifndef __COMMON_H__ @@ -41,9 +41,12 @@ #define IFCFG_PLUGIN_NAME "ifcfg-rh" #define IFCFG_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." -#define TYPE_ETHERNET "Ethernet" -#define TYPE_WIRELESS "Wireless" -#define TYPE_BRIDGE "Bridge" +#define TYPE_ETHERNET "Ethernet" +#define TYPE_WIRELESS "Wireless" +#define TYPE_INFINIBAND "InfiniBand" +#define TYPE_BRIDGE "Bridge" +#define TYPE_BOND "Bond" +#define TYPE_VLAN "Vlan" #define SECRET_FLAG_AGENT "user" #define SECRET_FLAG_NOT_SAVED "ask" diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index b4be4cba..04d5463c 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -569,7 +569,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, return FALSE; } - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); if (!s_con) { g_set_error (error, NM_SETTINGS_ERROR, @@ -790,7 +790,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c } G_MODULE_EXPORT GObject * -nm_system_config_factory (void) +nm_system_config_factory (const char *config_file) { static SCPluginIfcfg *singleton = NULL; SCPluginIfcfgPrivate *priv; diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 910cca35..01d83c1b 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2011 Red Hat, Inc. + * Copyright (C) 2008 - 2012 Red Hat, Inc. */ #include <config.h> @@ -33,25 +33,22 @@ #include <netinet/ether.h> #include <linux/if.h> -#ifndef __user -#define __user -#endif -#include <linux/types.h> -#include <wireless.h> -#undef __user - #include <glib.h> #include <glib/gi18n.h> #include <nm-connection.h> #include <NetworkManager.h> #include <nm-setting-connection.h> #include <nm-setting-ip4-config.h> +#include <nm-setting-vlan.h> #include <nm-setting-ip6-config.h> #include <nm-setting-wired.h> #include <nm-setting-wireless.h> #include <nm-setting-8021x.h> +#include <nm-setting-bond.h> #include <nm-utils.h> +#include "wifi-utils.h" + #include "common.h" #include "shvar.h" #include "utils.h" @@ -77,16 +74,46 @@ get_int (const char *str, int *value) return TRUE; } +static char * +make_connection_name (shvarFile *ifcfg, + const char *ifcfg_name, + const char *suggested, + const char *prefix) +{ + char *full_name = NULL, *name; + + /* If the ifcfg file already has a NAME, always use that */ + name = svGetValue (ifcfg, "NAME", FALSE); + if (name && strlen (name)) + return name; + + /* Otherwise construct a new NAME */ + g_free (name); + if (!prefix) + prefix = _("System"); + + /* For cosmetic reasons, if the suggested name is the same as + * the ifcfg files name, don't use it. Mainly for wifi so that + * the SSID is shown in the connection ID instead of just "wlan0". + */ + if (suggested && strcmp (ifcfg_name, suggested)) + full_name = g_strdup_printf ("%s %s (%s)", prefix, suggested, ifcfg_name); + else + full_name = g_strdup_printf ("%s %s", prefix, ifcfg_name); + + return full_name; +} + static NMSetting * make_connection_setting (const char *file, shvarFile *ifcfg, const char *type, - const char *suggested) + const char *suggested, + const char *prefix) { NMSettingConnection *s_con; const char *ifcfg_name = NULL; - char *new_id = NULL, *uuid = NULL, *value; - char *ifcfg_id; + char *new_id, *uuid = NULL, *zone = NULL, *value; ifcfg_name = utils_get_ifcfg_name (file, TRUE); if (!ifcfg_name) @@ -94,32 +121,9 @@ make_connection_setting (const char *file, s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - /* Try the ifcfg file's internally defined name if available */ - ifcfg_id = svGetValue (ifcfg, "NAME", FALSE); - if (ifcfg_id && strlen (ifcfg_id)) - g_object_set (s_con, NM_SETTING_CONNECTION_ID, ifcfg_id, NULL); - - if (!nm_setting_connection_get_id (s_con)) { - if (suggested) { - /* For cosmetic reasons, if the suggested name is the same as - * the ifcfg files name, don't use it. Mainly for wifi so that - * the SSID is shown in the connection ID instead of just "wlan0". - */ - if (strcmp (ifcfg_name, suggested)) { - new_id = g_strdup_printf ("%s %s (%s)", reader_get_prefix (), suggested, ifcfg_name); - g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); - } - } - - /* Use the ifcfg file's name as a last resort */ - if (!nm_setting_connection_get_id (s_con)) { - new_id = g_strdup_printf ("%s %s", reader_get_prefix (), ifcfg_name); - g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); - } - } - + new_id = make_connection_name (ifcfg, ifcfg_name, suggested, prefix); + g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); g_free (new_id); - g_free (ifcfg_id); /* Try for a UUID key before falling back to hashing the file name */ uuid = svGetValue (ifcfg, "UUID", FALSE); @@ -127,6 +131,7 @@ make_connection_setting (const char *file, g_free (uuid); uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); } + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_UUID, uuid, @@ -153,14 +158,23 @@ make_connection_setting (const char *file, g_strfreev (items); } + + zone = svGetValue(ifcfg, "ZONE", FALSE); + if (!zone || !strlen (zone)) { + g_free (zone); + zone = NULL; + } + g_object_set (s_con, NM_SETTING_CONNECTION_ZONE, zone, NULL); + g_free (zone); + return NM_SETTING (s_con); } static gboolean -read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error) +read_mac_address (shvarFile *ifcfg, const char *key, int type, + GByteArray **array, GError **error) { char *value = NULL; - struct ether_addr *mac; g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (array != NULL, FALSE); @@ -174,8 +188,8 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError return TRUE; } - mac = ether_aton (value); - if (!mac) { + *array = nm_utils_hwaddr_atoba (value, type); + if (!*array) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "%s: the MAC address '%s' was invalid.", key, value); g_free (value); @@ -183,8 +197,6 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError } g_free (value); - *array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); return TRUE; } @@ -266,7 +278,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg, goto done; } - if (!read_mac_address (ifcfg, "HWADDR", &ifcfg_mac, error)) + if (!read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &ifcfg_mac, error)) goto done; /* Ensure we got a MAC */ if (!ifcfg_mac) { @@ -627,7 +639,6 @@ read_one_ip4_route (shvarFile *ifcfg, g_return_val_if_fail (ifcfg != NULL, NULL); g_return_val_if_fail (network_file != NULL, NULL); - g_return_val_if_fail (which >= 0, NULL); route = nm_ip4_route_new (); @@ -1115,7 +1126,7 @@ static NMSetting * make_ip4_setting (shvarFile *ifcfg, const char *network_file, const char *iscsiadm_path, - gboolean valid_ip6_config, + gboolean can_disable_ip4, GError **error) { NMSettingIP4Config *s_ip4 = NULL; @@ -1230,7 +1241,7 @@ make_ip4_setting (shvarFile *ifcfg, && !tmp_ip4_0 && !tmp_prefix_0 && !tmp_netmask_0 && !tmp_ip4_1 && !tmp_prefix_1 && !tmp_netmask_1 && !tmp_ip4_2 && !tmp_prefix_2 && !tmp_netmask_2) { - if (valid_ip6_config) + if (can_disable_ip4) /* Nope, no IPv4 */ method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; else @@ -1255,7 +1266,7 @@ make_ip4_setting (shvarFile *ifcfg, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE), NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, - NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", TRUE), + NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE), NULL); if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) @@ -1424,6 +1435,9 @@ make_ip6_setting (shvarFile *ifcfg, guint32 i; shvarFile *network_ifcfg; gboolean never_default = FALSE, tmp_success; + gboolean ip6_privacy, ip6_privacy_prefer_public_ip; + char *ip6_privacy_str; + NMSettingIP6ConfigPrivacy ip6_privacy_val; s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); if (!s_ip6) { @@ -1510,12 +1524,29 @@ make_ip6_setting (shvarFile *ifcfg, } /* TODO - handle other methods */ + /* Read IPv6 Privacy Extensions configuration */ + ip6_privacy_str = svGetValue (ifcfg, "IPV6_PRIVACY", FALSE); + if (ip6_privacy_str) { + ip6_privacy = svTrueValue (ifcfg, "IPV6_PRIVACY", FALSE); + if (!ip6_privacy) + ip6_privacy = g_strcmp0 (ip6_privacy_str, "rfc4941") == 0 || + g_strcmp0 (ip6_privacy_str, "rfc3041") == 0; + } + ip6_privacy_prefer_public_ip = svTrueValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE); + ip6_privacy_val = ip6_privacy_str ? + (ip6_privacy ? + (ip6_privacy_prefer_public_ip ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) : + NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) : + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + g_free (ip6_privacy_str); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, method, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE), NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val, NULL); /* Don't bother to read IP, DNS and routes when IPv6 is disabled */ @@ -1926,6 +1957,7 @@ parse_wpa_psk (shvarFile *ifcfg, { shvarFile *keys_ifcfg; char *psk = NULL, *p, *hashed = NULL; + size_t plen; gboolean quoted = FALSE; /* Passphrase must be between 10 and 66 characters in length because WPA @@ -1949,8 +1981,10 @@ parse_wpa_psk (shvarFile *ifcfg, return NULL; p = psk; + plen = strlen (p); - if (p[0] == '"' && psk[strlen (psk) - 1] == '"') + if ( (plen >= 2 && (p[0] == '"' || p[0] == '\'') && p[0] == p[plen - 1]) + || (plen >= 3 && p[0] == '$' && p[1] == '\'' && p[1] == p[plen - 1])) quoted = TRUE; if (!quoted && (strlen (psk) == 64)) { @@ -1970,21 +2004,18 @@ parse_wpa_psk (shvarFile *ifcfg, * and between 8 and 63 characters as a passphrase. */ - if (quoted) { - /* Get rid of the quotes */ - p++; - p[strlen (p) - 1] = '\0'; - } + /* Get rid of the quotes */ + hashed = utils_single_unquote_string (p); /* Length check */ - if (strlen (p) < 8 || strlen (p) > 63) { + if (strlen (hashed) < 8 || strlen (hashed) > 63) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid WPA_PSK (passphrases must be between " "8 and 63 characters long (inclusive))"); + g_free (hashed); + hashed = NULL; goto out; } - - hashed = g_strdup (p); } if (!hashed) { @@ -2045,18 +2076,18 @@ eap_simple_reader (const char *eap_method, } static char * -get_cert_file (const char *ifcfg_path, const char *cert_path) +get_full_file_path (const char *ifcfg_path, const char *file_path) { - const char *base = cert_path; + const char *base = file_path; char *p, *ret, *dirname; g_return_val_if_fail (ifcfg_path != NULL, NULL); - g_return_val_if_fail (cert_path != NULL, NULL); + g_return_val_if_fail (file_path != NULL, NULL); - if (cert_path[0] == '/') - return g_strdup (cert_path); + if (file_path[0] == '/') + return g_strdup (file_path); - p = strrchr (cert_path, '/'); + p = strrchr (file_path, '/'); if (p) base = p + 1; @@ -2102,7 +2133,7 @@ eap_tls_reader (const char *eap_method, ca_cert = svGetValue (ifcfg, ca_cert_key, FALSE); if (ca_cert) { - real_path = get_cert_file (ifcfg->fileName, ca_cert); + real_path = get_full_file_path (ifcfg->fileName, ca_cert); if (phase2) { if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, real_path, @@ -2159,7 +2190,7 @@ eap_tls_reader (const char *eap_method, goto done; } - real_path = get_cert_file (ifcfg->fileName, privkey); + real_path = get_full_file_path (ifcfg->fileName, privkey); if (phase2) { if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, real_path, @@ -2196,7 +2227,7 @@ eap_tls_reader (const char *eap_method, goto done; } - real_path = get_cert_file (ifcfg->fileName, client_cert); + real_path = get_full_file_path (ifcfg->fileName, client_cert); if (phase2) { if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, real_path, @@ -2246,7 +2277,7 @@ eap_peap_reader (const char *eap_method, ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE); if (ca_cert) { - real_cert_path = get_cert_file (ifcfg->fileName, ca_cert); + real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert); if (!nm_setting_802_1x_set_ca_cert (s_8021x, real_cert_path, NM_SETTING_802_1X_CK_SCHEME_PATH, @@ -2352,7 +2383,7 @@ eap_ttls_reader (const char *eap_method, ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE); if (ca_cert) { - real_cert_path = get_cert_file (ifcfg->fileName, ca_cert); + real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert); if (!nm_setting_802_1x_set_ca_cert (s_8021x, real_cert_path, NM_SETTING_802_1X_CK_SCHEME_PATH, @@ -2422,6 +2453,111 @@ done: return success; } +static gboolean +eap_fast_reader (const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + char *anon_ident = NULL; + char *pac_file = NULL; + char *real_pac_path = NULL; + char *inner_auth = NULL; + char *fast_provisioning = NULL; + char *lower; + char **list = NULL, **iter; + const char* pac_prov_str; + gboolean allow_unauth = FALSE, allow_auth = FALSE; + gboolean success = FALSE; + + pac_file = svGetValue (ifcfg, "IEEE_8021X_PAC_FILE", FALSE); + if (pac_file) { + real_pac_path = get_full_file_path (ifcfg->fileName, pac_file); + g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, real_pac_path, NULL); + } + + fast_provisioning = svGetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", FALSE); + if (fast_provisioning) { + list = g_strsplit_set (fast_provisioning, " \t", 0); + for (iter = list; iter && *iter; iter++) { + if (**iter == '\0') + continue; + if (strcmp (*iter, "allow-unauth") == 0) + allow_unauth = TRUE; + else if (strcmp (*iter, "allow-auth") == 0) + allow_auth = TRUE; + else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid IEEE_8021X_FAST_PROVISIONING '%s' " + "(space-separated list of these values [allow-auth, allow-unauth] expected)", + *iter); + } + } + g_strfreev (list); + list = NULL; + } + pac_prov_str = allow_unauth ? (allow_auth ? "3" : "1") : (allow_auth ? "2" : "0"); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL); + + if (!pac_file && !(allow_unauth || allow_auth)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled."); + goto done; + } + + anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE); + if (anon_ident && strlen (anon_ident)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL); + + inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); + if (!inner_auth) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + + /* Handle options for the inner auth method */ + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + if (!strlen (*iter)) + continue; + + if ( !strcmp (*iter, "MSCHAPV2") + || !strcmp (*iter, "GTC")) { + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + + lower = g_ascii_strdown (*iter, -1); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL); + g_free (lower); + break; + } + + if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "No valid IEEE_8021X_INNER_AUTH_METHODS found."); + goto done; + } + + success = TRUE; + +done: + g_strfreev (list); + g_free (inner_auth); + g_free (fast_provisioning); + g_free (real_pac_path); + g_free (pac_file); + g_free (anon_ident); + return success; +} + typedef struct { const char *method; gboolean (*reader)(const char *eap_method, @@ -2443,6 +2579,7 @@ static EAPReader eap_readers[] = { { "tls", eap_tls_reader, FALSE }, { "peap", eap_peap_reader, FALSE }, { "ttls", eap_ttls_reader, FALSE }, + { "fast", eap_fast_reader, FALSE }, { NULL, NULL } }; @@ -2749,7 +2886,7 @@ make_wireless_setting (shvarFile *ifcfg, s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - if (read_mac_address (ifcfg, "HWADDR", &array, error)) { + if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &array, error)) { if (array) { g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL); @@ -2773,7 +2910,7 @@ make_wireless_setting (shvarFile *ifcfg, } array = NULL; - if (read_mac_address (ifcfg, "MACADDR", &array, error)) { + if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &array, error)) { if (array) { g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL); g_byte_array_free (array, TRUE); @@ -2901,19 +3038,16 @@ make_wireless_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "BSSID", FALSE); if (value) { - struct ether_addr *eth; GByteArray *bssid; - eth = ether_aton (value); - if (!eth) { + bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!bssid) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid BSSID '%s'", value); g_free (value); goto error; } - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL); g_byte_array_free (bssid, TRUE); g_free (value); @@ -3032,7 +3166,7 @@ wireless_connection_from_ifcfg (const char *file, /* Connection */ con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRELESS_SETTING_NAME, - printable_ssid); + printable_ssid, NULL); g_free (printable_ssid); if (!con_setting) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, @@ -3082,7 +3216,7 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } - if (read_mac_address (ifcfg, "HWADDR", &mac, error)) { + if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &mac, error)) { if (mac) { g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); @@ -3193,7 +3327,7 @@ make_wired_setting (shvarFile *ifcfg, } mac = NULL; - if (read_mac_address (ifcfg, "MACADDR", &mac, error)) { + if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &mac, error)) { if (mac) { g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL); g_byte_array_free (mac, TRUE); @@ -3260,6 +3394,7 @@ wired_connection_from_ifcfg (const char *file, NMSetting *con_setting = NULL; NMSetting *wired_setting = NULL; NMSetting8021x *s_8021x = NULL; + char *value; g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); @@ -3271,7 +3406,7 @@ wired_connection_from_ifcfg (const char *file, return NULL; } - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL); + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL); if (!con_setting) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Failed to create connection setting."); @@ -3280,6 +3415,238 @@ wired_connection_from_ifcfg (const char *file, } nm_connection_add_setting (connection, con_setting); + /* Might be a bond slave; handle master device or connection */ + value = svGetValue (ifcfg, "MASTER", FALSE); + if (value) { + g_object_set (con_setting, NM_SETTING_CONNECTION_MASTER, value, NULL); + g_object_set (con_setting, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + g_free (value); + } + + wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error); + if (!wired_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + if (!nm_connection_verify (connection, error)) { + g_object_unref (connection); + return NULL; + } + + return connection; +} + +static NMSetting * +make_infiniband_setting (shvarFile *ifcfg, + const char *file, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMSettingInfiniband *s_infiniband; + char *value = NULL; + GByteArray *mac = NULL; + int mtu; + + s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ()); + + value = svGetValue (ifcfg, "MTU", FALSE); + if (value) { + if (get_int (value, &mtu)) { + if (mtu >= 0 && mtu < 65536) + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu, NULL); + } else { + /* Shouldn't be fatal... */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid MTU '%s'", value); + } + g_free (value); + } + + if (read_mac_address (ifcfg, "HWADDR", ARPHRD_INFINIBAND, &mac, error)) { + if (mac) { + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); + + /* A connection can only be unmanaged if we know the MAC address */ + if (!nm_controlled) { + char *mac_str = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND); + *unmanaged = g_strdup_printf ("mac:%s", mac_str); + g_free (mac_str); + } + + g_byte_array_free (mac, TRUE); + } + } else { + g_object_unref (s_infiniband); + return NULL; + } + + if (svTrueValue (ifcfg, "CONNECTED_MODE", FALSE)) + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); + else + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + + if (!nm_controlled && !*unmanaged) { + /* If NM_CONTROLLED=no but there wasn't a MAC address, notify + the user that the device cannot be unmanaged. + */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed"); + } + + return (NMSetting *) s_infiniband; +} + +static NMConnection * +infiniband_connection_from_ifcfg (const char *file, + shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMConnection *connection = NULL; + NMSetting *con_setting = NULL; + NMSetting *infiniband_setting = NULL; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + + connection = nm_connection_new (); + if (!connection) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to allocate new connection for %s.", file); + return NULL; + } + + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL); + if (!con_setting) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to create connection setting."); + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, con_setting); + + infiniband_setting = make_infiniband_setting (ifcfg, file, nm_controlled, unmanaged, error); + if (!infiniband_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, infiniband_setting); + + if (!nm_connection_verify (connection, error)) { + g_object_unref (connection); + return NULL; + } + + return connection; +} + +static void +handle_bond_option (NMSettingBond *s_bond, + const char *key, + const char *value) +{ + if (!nm_setting_bond_add_option (s_bond, key, value)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid bonding option '%s'", key); +} + +static NMSetting * +make_bond_setting (shvarFile *ifcfg, + const char *file, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMSettingBond *s_bond; + char *value; + + s_bond = NM_SETTING_BOND (nm_setting_bond_new ()); + + value = svGetValue (ifcfg, "DEVICE", FALSE); + if (!value || !strlen (value)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "mandatory DEVICE keyword missing"); + goto error; + } + + g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, value, NULL); + g_free (value); + + value = svGetValue (ifcfg, "BONDING_OPTS", FALSE); + if (value) { + char **items, **iter; + + items = g_strsplit_set (value, " ", -1); + for (iter = items; iter && *iter; iter++) { + if (strlen (*iter)) { + char **keys, *key, *val; + + keys = g_strsplit_set (*iter, "=", 2); + if (keys && *keys) { + key = *keys; + val = *(keys + 1); + if (val && strlen(key) && strlen(val)) + handle_bond_option (s_bond, key, val); + } + + g_strfreev (keys); + } + } + g_free (value); + g_strfreev (items); + } + + return (NMSetting *) s_bond; + +error: + g_object_unref (s_bond); + return NULL; +} + +static NMConnection * +bond_connection_from_ifcfg (const char *file, + shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMConnection *connection = NULL; + NMSetting *con_setting = NULL; + NMSetting *bond_setting = NULL; + NMSetting *wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + + connection = nm_connection_new (); + if (!connection) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to allocate new connection for %s.", file); + return NULL; + } + + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond")); + if (!con_setting) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to create connection setting."); + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, con_setting); + + bond_setting = make_bond_setting (ifcfg, file, nm_controlled, unmanaged, error); + if (!bond_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, bond_setting); + wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error); if (!wired_setting) { g_object_unref (connection); @@ -3299,50 +3666,245 @@ wired_connection_from_ifcfg (const char *file, } static gboolean -is_wireless_device (const char *iface) +is_bond_device (const char *name, shvarFile *parsed) { - int fd; - struct iw_range range; - struct iwreq wrq; - gboolean is_wireless = FALSE; + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (parsed != NULL, FALSE); + + if (svTrueValue (parsed, "BONDING_MASTER", FALSE)) + return TRUE; + + /* XXX: Check for "bond[\d]+"? */ - g_return_val_if_fail (iface != NULL, FALSE); + return FALSE; +} - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) - return FALSE; +static gboolean +is_vlan_device (const char *name, shvarFile *parsed) +{ + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (parsed != NULL, FALSE); - memset (&wrq, 0, sizeof (struct iwreq)); - memset (&range, 0, sizeof (struct iw_range)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - wrq.u.data.pointer = (caddr_t) ⦥ - wrq.u.data.length = sizeof (struct iw_range); + if (svTrueValue (parsed, "VLAN", FALSE)) + return TRUE; - if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0) - is_wireless = TRUE; - else { - if (errno == EOPNOTSUPP) - is_wireless = FALSE; - else { - /* Sigh... some wired devices (kvm/qemu) return EINVAL when the - * device is down even though it's not a wireless device. So try - * IWNAME as a fallback. - */ - memset (&wrq, 0, sizeof (struct iwreq)); - strncpy (wrq.ifr_name, iface, IFNAMSIZ); - if (ioctl (fd, SIOCGIWNAME, &wrq) == 0) - is_wireless = TRUE; + return FALSE; +} + +static void +parse_prio_map_list (NMSettingVlan *s_vlan, + shvarFile *ifcfg, + const char *key, + NMVlanPriorityMap map) +{ + char *value; + gchar **list = NULL, **iter; + + value = svGetValue (ifcfg, key, FALSE); + if (!value) + return; + + list = g_strsplit_set (value, ",", -1); + g_free (value); + + for (iter = list; iter && *iter; iter++) { + if (!*iter || !strchr (*iter, ':')) + continue; + + if (!nm_setting_vlan_add_priority_str (s_vlan, map, *iter)) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid %s priority map item '%s'", + key, *iter); + } + } + g_strfreev (list); +} + +static NMSetting * +make_vlan_setting (shvarFile *ifcfg, + const char *file, + gboolean nm_controlled, + char **out_master, + char **unmanaged, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSettingVlan *s_vlan = NULL; + char *value = NULL; + char *iface_name = NULL; + char *parent = NULL; + const char *p = NULL, *w; + gboolean has_numbers = FALSE; + gint vlan_id = -1; + guint32 vlan_flags = 0; + + value = svGetValue (ifcfg, "VLAN_ID", FALSE); + if (value) { + errno = 0; + vlan_id = (gint) g_ascii_strtoll (value, NULL, 10); + if (vlan_id < 0 || vlan_id > 4096 || errno) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid VLAN_ID '%s'", value); + g_free (value); + return NULL; + } + g_free (value); + } + + /* Need DEVICE if we don't have a separate VLAN_ID property */ + iface_name = svGetValue (ifcfg, "DEVICE", FALSE); + if (!iface_name && vlan_id < 0) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + "Missing DEVICE property; cannot determine VLAN ID."); + return NULL; + } + + s_vlan = NM_SETTING_VLAN (nm_setting_vlan_new ()); + + if (iface_name) { + g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, iface_name, NULL); + + p = strchr (iface_name, '.'); + if (p) { + /* eth0.43; PHYSDEV is assumed from it */ + parent = g_strndup (iface_name, p - iface_name); + p++; + } else { + /* format like vlan43; PHYSDEV or MASTER must be set */ + if (g_str_has_prefix (iface_name, "vlan")) + p = iface_name + 4; } + + w = p; + while (*w && !has_numbers) + has_numbers = g_ascii_isdigit (*w); + + /* Grab VLAN ID from interface name; this takes precedence over the + * separate VLAN_ID property for backwards compat. + */ + if (has_numbers) { + errno = 0; + vlan_id = (gint) g_ascii_strtoll (p, NULL, 10); + if (vlan_id < 0 || vlan_id > 4095 || errno) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to determine VLAN ID from DEVICE '%s'", + iface_name); + goto error; + } + } + } + + if (vlan_id < 0) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to determine VLAN ID from DEVICE or VLAN_ID."); + goto error; } + g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); - close (fd); - return is_wireless; + if (!parent) + parent = svGetValue (ifcfg, "PHYSDEV", FALSE); + if (parent == NULL) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to determine VLAN parent from DEVICE or PHYSDEV"); + goto error; + } + g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); + + if (svTrueValue (ifcfg, "REORDER_HDR", FALSE)) + vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS; + + value = svGetValue (ifcfg, "VLAN_FLAGS", FALSE); + if (value) { + if (g_strstr_len (value, -1, "GVRP")) + vlan_flags |= NM_VLAN_FLAG_GVRP; + if (g_strstr_len (value, -1, "LOOSE_BINDING")) + vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING; + } + + g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL); + g_free (value); + + parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); + parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); + + if (out_master) + *out_master = svGetValue (ifcfg, "MASTER", FALSE); + return (NMSetting *) s_vlan; + +error: + g_free (parent); + g_free (iface_name); + g_object_unref (s_vlan); + return NULL; +} + +static NMConnection * +vlan_connection_from_ifcfg (const char *file, + shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMConnection *connection = NULL; + NMSetting *con_setting = NULL; + NMSetting *wired_setting = NULL; + NMSetting *vlan_setting = NULL; + NMSetting8021x *s_8021x = NULL; + char *master = NULL; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + + connection = nm_connection_new (); + if (!connection) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to allocate new connection for %s.", file); + return NULL; + } + + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan"); + if (!con_setting) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to create connection setting."); + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, con_setting); + + vlan_setting = make_vlan_setting (ifcfg, file, nm_controlled, &master, unmanaged, &s_8021x, error); + if (!vlan_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, vlan_setting); + + /* Handle master interface or connection */ + if (master) { + g_object_set (con_setting, NM_SETTING_CONNECTION_MASTER, master, NULL); + g_object_set (con_setting, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_VLAN_SETTING_NAME, + NULL); + g_free (master); + } + + wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error); + if (!wired_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + if (!nm_connection_verify (connection, error)) { + g_object_unref (connection); + return NULL; + } + + return connection; } enum { IGNORE_REASON_NONE = 0x00, IGNORE_REASON_BRIDGE = 0x01, - IGNORE_REASON_VLAN = 0x02, }; NMConnection * @@ -3363,7 +3925,7 @@ connection_from_file (const char *filename, NMSetting *s_ip4, *s_ip6; const char *ifcfg_name = NULL; gboolean nm_controlled = TRUE; - gboolean ip6_used = FALSE; + gboolean can_disable_ip4 = FALSE; GError *error = NULL; guint32 ignore_reason = IGNORE_REASON_NONE; @@ -3402,9 +3964,6 @@ connection_from_file (const char *filename, if (!type) { char *device; - /* If no type, if the device has wireless extensions, it's wifi, - * otherwise it's ethernet. - */ device = svGetValue (parsed, "DEVICE", FALSE); if (!device) { g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, @@ -3422,8 +3981,12 @@ connection_from_file (const char *filename, } if (!test_type) { + if (is_bond_device (device, parsed)) + type = g_strdup (TYPE_BOND); + else if (is_vlan_device (device, parsed)) + type = g_strdup (TYPE_VLAN); /* Test wireless extensions */ - if (is_wireless_device (device)) + else if (wifi_utils_is_wifi (device, NULL)) type = g_strdup (TYPE_WIRELESS); else type = g_strdup (TYPE_ETHERNET); @@ -3456,7 +4019,14 @@ connection_from_file (const char *filename, g_free (lower); } - /* Ignore BRIDGE= and VLAN= connections for now too (rh #619863) */ + if (svTrueValue (parsed, "BONDING_MASTER", FALSE) && + strcasecmp (type, TYPE_BOND)) { + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "BONDING_MASTER=yes key only allowed in TYPE=bond connections"); + goto done; + } + + /* Ignore BRIDGE= connections for now too (rh #619863) */ tmp = svGetValue (parsed, "BRIDGE", FALSE); if (tmp) { g_free (tmp); @@ -3464,24 +4034,21 @@ connection_from_file (const char *filename, ignore_reason = IGNORE_REASON_BRIDGE; } - if (nm_controlled) { - tmp = svGetValue (parsed, "VLAN", FALSE); - if (tmp) { - g_free (tmp); - nm_controlled = FALSE; - ignore_reason = IGNORE_REASON_VLAN; - } - } - /* Construct the connection */ if (!strcasecmp (type, TYPE_ETHERNET)) connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); else if (!strcasecmp (type, TYPE_WIRELESS)) connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); - else if (!strcasecmp (type, TYPE_BRIDGE)) { + else if (!strcasecmp (type, TYPE_INFINIBAND)) + connection = infiniband_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); + else if (!strcasecmp (type, TYPE_BOND)) + connection = bond_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); + else if (!strcasecmp (type, TYPE_VLAN)) + connection = vlan_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); + else if (!strcasecmp (type, TYPE_BRIDGE)) g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, "Bridge connections are not yet supported"); - } else { + else { g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, "Unknown connection type '%s'", type); } @@ -3524,10 +4091,13 @@ connection_from_file (const char *filename, nm_connection_add_setting (connection, s_ip6); method = nm_setting_ip6_config_get_method (NM_SETTING_IP6_CONFIG (s_ip6)); if (method && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) - ip6_used = TRUE; + can_disable_ip4 = TRUE; } - s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, ip6_used, &error); + if (utils_disabling_ip4_config_allowed (connection)) + can_disable_ip4 = TRUE; + + s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, can_disable_ip4, &error); if (error) { g_object_unref (connection); connection = NULL; @@ -3544,7 +4114,7 @@ connection_from_file (const char *filename, && !g_ascii_strcasecmp (bootproto, "ibft")) { NMSettingConnection *s_con; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL); @@ -3569,9 +4139,3 @@ done: return connection; } -const char * -reader_get_prefix (void) -{ - return _("System"); -} - diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h index 2a031977..97c727cc 100644 --- a/src/settings/plugins/ifcfg-rh/reader.h +++ b/src/settings/plugins/ifcfg-rh/reader.h @@ -37,6 +37,4 @@ NMConnection *connection_from_file (const char *filename, GError **error, gboolean *ignore_error); -const char *reader_get_prefix (void); - #endif /* __READER_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am index 1b76a474..5b34ffe3 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am @@ -2,6 +2,7 @@ SUBDIRS=network-scripts INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ -I$(srcdir)/../ @@ -20,7 +21,9 @@ test_ifcfg_rh_CPPFLAGS = \ test_ifcfg_rh_LDADD = \ $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(builddir)/../libifcfg-rh-io.la \ + $(LIBM) $(DBUS_LIBS) test_ifcfg_rh_utils_SOURCES = \ diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in index 71c5d60b..5e8abf83 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -61,6 +61,7 @@ test_ifcfg_rh_OBJECTS = $(am_test_ifcfg_rh_OBJECTS) am__DEPENDENCIES_1 = test_ifcfg_rh_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(builddir)/../libifcfg-rh-io.la $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -183,6 +184,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -237,11 +240,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -252,6 +259,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -291,6 +299,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -357,6 +367,7 @@ top_srcdir = @top_srcdir@ SUBDIRS = network-scripts INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ -I$(srcdir)/../ @@ -373,8 +384,9 @@ test_ifcfg_rh_CPPFLAGS = \ test_ifcfg_rh_LDADD = \ $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/wifi/libwifi-utils.la \ $(builddir)/../libifcfg-rh-io.la \ - $(DBUS_LIBS) + $(LIBM) test_ifcfg_rh_utils_SOURCES = \ test-ifcfg-rh-utils.c @@ -833,6 +845,7 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am + $(DBUS_LIBS) @WITH_TESTS_TRUE@check-local: test-ifcfg-rh @WITH_TESTS_TRUE@ $(abs_builddir)/test-ifcfg-rh-utils diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 935d0ec4..776962f0 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -36,6 +36,8 @@ EXTRA_DIST = \ ifcfg-test-wifi-leap-always-ask \ ifcfg-test-wifi-wpa-psk \ keys-test-wifi-wpa-psk \ + ifcfg-test-wifi-wpa-psk-2 \ + keys-test-wifi-wpa-psk-2 \ ifcfg-test-wifi-wpa-psk-unquoted \ keys-test-wifi-wpa-psk-unquoted \ ifcfg-test-wifi-wpa-psk-unquoted2 \ @@ -79,11 +81,16 @@ EXTRA_DIST = \ ifcfg-test-bridge-main \ ifcfg-test-bridge-component \ ifcfg-test-vlan-interface \ + ifcfg-test-vlan-only-vlanid \ + ifcfg-test-vlan-only-device \ ifcfg-test-wifi-wep-no-keys \ ifcfg-test-permissions \ ifcfg-test-wifi-wep-agent-keys \ ifcfg-test-wifi-dynamic-wep-leap \ - keys-test-wifi-dynamic-wep-leap + keys-test-wifi-dynamic-wep-leap \ + ifcfg-test-infiniband \ + ifcfg-test-bond-main \ + ifcfg-test-bond-slave check-local: @for f in $(EXTRA_DIST); do \ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in index 6292f12c..4f34cfc3 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -107,6 +107,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -161,11 +163,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -176,6 +182,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -215,6 +222,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -316,6 +325,8 @@ EXTRA_DIST = \ ifcfg-test-wifi-leap-always-ask \ ifcfg-test-wifi-wpa-psk \ keys-test-wifi-wpa-psk \ + ifcfg-test-wifi-wpa-psk-2 \ + keys-test-wifi-wpa-psk-2 \ ifcfg-test-wifi-wpa-psk-unquoted \ keys-test-wifi-wpa-psk-unquoted \ ifcfg-test-wifi-wpa-psk-unquoted2 \ @@ -359,11 +370,16 @@ EXTRA_DIST = \ ifcfg-test-bridge-main \ ifcfg-test-bridge-component \ ifcfg-test-vlan-interface \ + ifcfg-test-vlan-only-vlanid \ + ifcfg-test-vlan-only-device \ ifcfg-test-wifi-wep-no-keys \ ifcfg-test-permissions \ ifcfg-test-wifi-wep-agent-keys \ ifcfg-test-wifi-dynamic-wep-leap \ - keys-test-wifi-dynamic-wep-leap + keys-test-wifi-dynamic-wep-leap \ + ifcfg-test-infiniband \ + ifcfg-test-bond-main \ + ifcfg-test-bond-slave all: all-am diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main new file mode 100644 index 00000000..4c4834d5 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main @@ -0,0 +1,5 @@ +DEVICE=bond0 +ONBOOT=no +TYPE=Bond +BOOTPROTO=dhcp +BONDING_OPTS="miimon=100" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave new file mode 100644 index 00000000..cfef2b16 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave @@ -0,0 +1,4 @@ +DEVICE=eth0 +HWADDR=00:22:15:59:62:97 +ONBOOT=no +MASTER=bond0 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband new file mode 100644 index 00000000..6c36f1de --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband @@ -0,0 +1,8 @@ +TYPE=InfiniBand +DEVICE=ib0 +HWADDR=80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22 +CONNECTED_MODE=yes +MTU=65520 +IPADDR=192.168.2.2 +NETMASK=255.255.255.0 +GATEWAY=192.168.2.1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface index 6c841855..ccd75d7f 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface @@ -1,7 +1,12 @@ -DEVICE=eth1.43 VLAN=yes +TYPE=Vlan +DEVICE=vlan43 +PHYSDEV=eth9 +REORDER_HDR=0 +VLAN_FLAGS=GVRP,LOOSE_BINDING +VLAN_INGRESS_PRIORITY_MAP=0:1,2:5 +VLAN_EGRESS_PRIORITY_MAP=12:3,14:7,3:1 ONBOOT=yes -BOOTPROTO=none +BOOTPROTO=static IPADDR=192.168.43.149 NETMASK=255.255.255.0 - diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device new file mode 100644 index 00000000..4ba06f28 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device @@ -0,0 +1,4 @@ +VLAN=yes +TYPE=Vlan +DEVICE=eth0.9 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid new file mode 100644 index 00000000..622d41ec --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid @@ -0,0 +1,6 @@ +VLAN=yes +TYPE=Vlan +PHYSDEV=eth9 +VLAN_ID=43 +ONBOOT=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2 new file mode 100644 index 00000000..038b656d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2 @@ -0,0 +1,19 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=ipsum +CHANNEL=6 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-PSK +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2 new file mode 100644 index 00000000..bf98da5a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2 @@ -0,0 +1,2 @@ +WPA_PSK=$'They\'re really saying I love you. >>`<<' + diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index e32266cb..62882a76 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -23,6 +23,7 @@ #include <unistd.h> #include <string.h> #include <netinet/ether.h> +#include <linux/if_infiniband.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> @@ -43,6 +44,7 @@ #include <nm-setting-gsm.h> #include <nm-setting-cdma.h> #include <nm-setting-serial.h> +#include <nm-setting-vlan.h> #include "nm-test-helpers.h" @@ -235,7 +237,7 @@ test_read_minimal (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "minimal-wired-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_MINIMAL, @@ -275,7 +277,7 @@ test_read_minimal (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "minimal-wired-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_MINIMAL, @@ -307,7 +309,7 @@ test_read_minimal (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "minimal-wired-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_MINIMAL, @@ -379,7 +381,7 @@ test_read_unmanaged (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "unmanaged-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_UNMANAGED, @@ -417,7 +419,7 @@ test_read_unmanaged (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "unmanaged-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_UNMANAGED, @@ -443,7 +445,7 @@ test_read_unmanaged (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 == NULL, "unmanaged-verify-ip4", "failed to verify %s: unexpected %s setting", TEST_IFCFG_UNMANAGED, @@ -504,7 +506,7 @@ test_read_wired_static (const char *file, const char *expected_id) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-static-verify-connection", "failed to verify %s: missing %s setting", file, @@ -539,7 +541,7 @@ test_read_wired_static (const char *file, const char *expected_id) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-static-verify-wired", "failed to verify %s: missing %s setting", file, @@ -571,7 +573,7 @@ test_read_wired_static (const char *file, const char *expected_id) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-static-verify-ip4", "failed to verify %s: missing %s setting", file, @@ -586,7 +588,7 @@ test_read_wired_static (const char *file, const char *expected_id) NM_SETTING_IP4_CONFIG_METHOD); /* Implicit may-fail */ - ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == FALSE, + ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == TRUE, "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, @@ -666,7 +668,7 @@ test_read_wired_static (const char *file, const char *expected_id) if (!strcmp (expected_id, "System test-wired-static")) { /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-static-verify-ip6", "failed to verify %s: missing %s setting", file, @@ -807,7 +809,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s setting", file, @@ -829,7 +831,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing %s setting", file, @@ -916,7 +918,7 @@ test_read_wired_dhcp (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-dhcp-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP, @@ -951,7 +953,7 @@ test_read_wired_dhcp (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-dhcp-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP, @@ -977,7 +979,7 @@ test_read_wired_dhcp (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-dhcp-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP, @@ -1089,7 +1091,7 @@ test_read_wired_global_gateway (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, @@ -1110,7 +1112,7 @@ test_read_wired_global_gateway (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, @@ -1118,7 +1120,7 @@ test_read_wired_global_gateway (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, @@ -1216,7 +1218,7 @@ test_read_wired_never_default (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-never-default-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_NEVER_DEFAULT, @@ -1237,7 +1239,7 @@ test_read_wired_never_default (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-never-default-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_NEVER_DEFAULT, @@ -1245,7 +1247,7 @@ test_read_wired_never_default (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-never-default-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_NEVER_DEFAULT, @@ -1274,7 +1276,7 @@ test_read_wired_never_default (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-never-default-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_NEVER_DEFAULT, @@ -1341,7 +1343,7 @@ test_read_wired_defroute_no (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-defroute-no-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO, @@ -1362,7 +1364,7 @@ test_read_wired_defroute_no (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-defroute-no-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO, @@ -1370,7 +1372,7 @@ test_read_wired_defroute_no (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-defroute-no-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO, @@ -1392,7 +1394,7 @@ test_read_wired_defroute_no (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-defroute-no-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO, @@ -1468,7 +1470,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, @@ -1489,7 +1491,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-defroute-no-gatewaydev-yes-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, @@ -1497,7 +1499,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, @@ -1519,7 +1521,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, @@ -1597,7 +1599,7 @@ test_read_wired_static_routes (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-static-routes-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES, @@ -1618,7 +1620,7 @@ test_read_wired_static_routes (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-static-routes-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES, @@ -1626,7 +1628,7 @@ test_read_wired_static_routes (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-static-routes-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES, @@ -1764,7 +1766,7 @@ test_read_wired_static_routes_legacy (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, @@ -1785,7 +1787,7 @@ test_read_wired_static_routes_legacy (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, @@ -1793,7 +1795,7 @@ test_read_wired_static_routes_legacy (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, @@ -1961,7 +1963,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-ipv4-manual-verify-connection", "failed to verify %s: missing %s setting", file, @@ -1982,7 +1984,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-ipv4-manual-verify-wired", "failed to verify %s: missing %s setting", file, @@ -1990,7 +1992,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-ipv4-manual-verify-ip4", "failed to verify %s: missing %s setting", file, @@ -2124,7 +2126,7 @@ test_read_wired_ipv6_manual (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2145,7 +2147,7 @@ test_read_wired_ipv6_manual (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-ipv6-manual-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2153,7 +2155,7 @@ test_read_wired_ipv6_manual (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2211,7 +2213,7 @@ test_read_wired_ipv6_manual (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2415,7 +2417,7 @@ test_read_wired_ipv6_only (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2436,7 +2438,7 @@ test_read_wired_ipv6_only (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-ipv6-only-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2444,7 +2446,7 @@ test_read_wired_ipv6_only (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2459,7 +2461,7 @@ test_read_wired_ipv6_only (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-ipv6-only-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_IPV6_MANUAL, @@ -2568,7 +2570,7 @@ test_read_wired_dhcp6_only (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP6_ONLY, @@ -2589,7 +2591,7 @@ test_read_wired_dhcp6_only (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-dhcp6-only-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP6_ONLY, @@ -2597,7 +2599,7 @@ test_read_wired_dhcp6_only (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-dhcp6-only-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP6_ONLY, @@ -2612,7 +2614,7 @@ test_read_wired_dhcp6_only (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "wired-dhcp6-only-verify-ip6", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_DHCP6_ONLY, @@ -2668,7 +2670,7 @@ test_read_onboot_no (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "onboot-no-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_ONBOOT_NO, @@ -2734,7 +2736,7 @@ test_read_wired_8021x_peap_mschapv2 (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-8021x-peap-mschapv2-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, @@ -2742,7 +2744,7 @@ test_read_wired_8021x_peap_mschapv2 (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, @@ -2757,7 +2759,7 @@ test_read_wired_8021x_peap_mschapv2 (void) NM_SETTING_IP4_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ - s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + s_8021x = nm_connection_get_setting_802_1x (connection); ASSERT (s_8021x != NULL, "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, @@ -2929,11 +2931,11 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags g_assert (success); /* ===== WIRED SETTING ===== */ - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired); /* ===== 802.1x SETTING ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls"); @@ -3001,7 +3003,7 @@ test_read_wifi_open (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-open-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN, @@ -3041,7 +3043,7 @@ test_read_wifi_open (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-open-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN, @@ -3120,7 +3122,7 @@ test_read_wifi_open (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-open-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN, @@ -3177,7 +3179,7 @@ test_read_wifi_open_auto (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-open-auto-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_AUTO, @@ -3198,7 +3200,7 @@ test_read_wifi_open_auto (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_AUTO, @@ -3260,7 +3262,7 @@ test_read_wifi_open_ssid_hex (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_SSID_HEX, @@ -3281,7 +3283,7 @@ test_read_wifi_open_ssid_hex (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_SSID_HEX, @@ -3379,7 +3381,7 @@ test_read_wifi_open_ssid_quoted (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, @@ -3400,7 +3402,7 @@ test_read_wifi_open_ssid_quoted (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, @@ -3476,7 +3478,7 @@ test_read_wifi_wep (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP, @@ -3516,7 +3518,7 @@ test_read_wifi_wep (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP, @@ -3608,7 +3610,7 @@ test_read_wifi_wep (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP, @@ -3687,7 +3689,7 @@ test_read_wifi_wep (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wep-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP, @@ -3752,7 +3754,7 @@ test_read_wifi_wep_adhoc (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_ADHOC, @@ -3785,7 +3787,7 @@ test_read_wifi_wep_adhoc (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_ADHOC, @@ -3852,7 +3854,7 @@ test_read_wifi_wep_adhoc (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_ADHOC, @@ -3919,7 +3921,7 @@ test_read_wifi_wep_adhoc (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_ADHOC, @@ -4015,7 +4017,7 @@ test_read_wifi_wep_passphrase (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-passphrase-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_PASSPHRASE, @@ -4023,7 +4025,7 @@ test_read_wifi_wep_passphrase (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_PASSPHRASE, @@ -4045,7 +4047,7 @@ test_read_wifi_wep_passphrase (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_PASSPHRASE, @@ -4153,7 +4155,7 @@ test_read_wifi_wep_40_ascii (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-40-ascii-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_40_ASCII, @@ -4161,7 +4163,7 @@ test_read_wifi_wep_40_ascii (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_40_ASCII, @@ -4182,7 +4184,7 @@ test_read_wifi_wep_40_ascii (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_40_ASCII, @@ -4290,7 +4292,7 @@ test_read_wifi_wep_104_ascii (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-104-ascii-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_104_ASCII, @@ -4298,7 +4300,7 @@ test_read_wifi_wep_104_ascii (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_104_ASCII, @@ -4319,7 +4321,7 @@ test_read_wifi_wep_104_ascii (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_104_ASCII, @@ -4428,7 +4430,7 @@ test_read_wifi_leap (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-leap-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_LEAP, @@ -4449,7 +4451,7 @@ test_read_wifi_leap (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_LEAP, @@ -4471,7 +4473,7 @@ test_read_wifi_leap (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_LEAP, @@ -4566,13 +4568,13 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte g_assert (success); /* ===== WIRELESS SETTING ===== */ - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); g_assert (g_strcmp0 (nm_setting_wireless_get_security (s_wifi), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0); @@ -4643,7 +4645,7 @@ test_read_wifi_wpa_psk (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK, @@ -4683,7 +4685,7 @@ test_read_wifi_wpa_psk (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK, @@ -4774,7 +4776,7 @@ test_read_wifi_wpa_psk (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK, @@ -4887,7 +4889,7 @@ test_read_wifi_wpa_psk (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wpa-psk-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK, @@ -4908,6 +4910,111 @@ test_read_wifi_wpa_psk (void) g_object_unref (connection); } +#define TEST_IFCFG_WIFI_WPA_PSK_2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-2" + +static void +test_read_wifi_wpa_psk_2 (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System ipsum (test-wifi-wpa-psk-2)"; + const char *expected_psk = "They're really saying I love you. >>`<<"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_2, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-psk-2-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_2, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-psk-2-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_2, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection (connection); + ASSERT (s_con != NULL, + "wifi-wpa-psk-2-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wpa-psk-2-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wpa-psk-2-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = nm_connection_get_setting_wireless (connection); + ASSERT (s_wireless != NULL, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = nm_connection_get_setting_wireless_security (connection); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* PSK */ + tmp = nm_setting_wireless_security_get_psk (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (strcmp (tmp, expected_psk) == 0, + "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_2, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + #define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted" static void @@ -4945,7 +5052,7 @@ test_read_wifi_wpa_psk_unquoted (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, @@ -4966,7 +5073,7 @@ test_read_wifi_wpa_psk_unquoted (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, @@ -4987,7 +5094,7 @@ test_read_wifi_wpa_psk_unquoted (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, @@ -5092,7 +5199,7 @@ test_read_wifi_wpa_psk_adhoc (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, @@ -5113,7 +5220,7 @@ test_read_wifi_wpa_psk_adhoc (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, @@ -5147,7 +5254,7 @@ test_read_wifi_wpa_psk_adhoc (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, @@ -5221,7 +5328,7 @@ test_read_wifi_wpa_psk_adhoc (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, @@ -5283,7 +5390,7 @@ test_read_wifi_wpa_psk_hex (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_HEX, @@ -5304,7 +5411,7 @@ test_read_wifi_wpa_psk_hex (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_HEX, @@ -5343,7 +5450,7 @@ test_read_wifi_wpa_psk_hex (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_HEX, @@ -5377,7 +5484,7 @@ test_read_wifi_wpa_psk_hex (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_PSK_HEX, @@ -5441,7 +5548,7 @@ test_read_wifi_wpa_eap_tls (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-eap-tls-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TLS, @@ -5449,7 +5556,7 @@ test_read_wifi_wpa_eap_tls (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TLS, @@ -5464,7 +5571,7 @@ test_read_wifi_wpa_eap_tls (void) NM_SETTING_IP4_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ - s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + s_8021x = nm_connection_get_setting_802_1x (connection); ASSERT (s_8021x != NULL, "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TLS, @@ -5591,7 +5698,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wpa-eap-ttls-tls-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, @@ -5599,7 +5706,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, @@ -5614,7 +5721,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) NM_SETTING_IP4_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ - s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + s_8021x = nm_connection_get_setting_802_1x (connection); ASSERT (s_8021x != NULL, "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, @@ -5756,13 +5863,13 @@ test_read_wifi_dynamic_wep_leap (void) /* ===== WIRELESS SETTING ===== */ - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); g_assert_cmpstr (nm_setting_wireless_get_security (s_wifi), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); /* ===== WiFi SECURITY SETTING ===== */ - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); /* Key management */ @@ -5778,7 +5885,7 @@ test_read_wifi_dynamic_wep_leap (void) g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, NULL); /* ===== 802.1x SETTING ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); /* EAP method should be "leap" */ @@ -5839,7 +5946,7 @@ test_read_wifi_wep_eap_ttls_chap (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-eap-ttls-chap-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, @@ -5847,7 +5954,7 @@ test_read_wifi_wep_eap_ttls_chap (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, @@ -5862,7 +5969,7 @@ test_read_wifi_wep_eap_ttls_chap (void) NM_SETTING_IP4_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, @@ -5882,7 +5989,7 @@ test_read_wifi_wep_eap_ttls_chap (void) NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); /* ===== 802.1x SETTING ===== */ - s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + s_8021x = nm_connection_get_setting_802_1x (connection); ASSERT (s_8021x != NULL, "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, @@ -6005,7 +6112,7 @@ test_read_wired_qeth_static (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wired-qeth-static-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_QETH_STATIC, @@ -6026,7 +6133,7 @@ test_read_wired_qeth_static (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "wired-qeth-static-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_QETH_STATIC, @@ -6116,7 +6223,7 @@ test_read_wired_qeth_static (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "wired-qeth-static-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_WIRED_QETH_STATIC, @@ -6247,7 +6354,7 @@ test_read_wifi_wep_no_keys (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_NO_KEYS, @@ -6273,7 +6380,7 @@ test_read_wifi_wep_no_keys (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_NO_KEYS, @@ -6295,7 +6402,7 @@ test_read_wifi_wep_no_keys (void) /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + s_wsec = nm_connection_get_setting_wireless_security (connection); ASSERT (s_wsec != NULL, "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", TEST_IFCFG_WIFI_WEP_NO_KEYS, @@ -6371,7 +6478,7 @@ test_read_permissions (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "permissions-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_PERMISSIONS, @@ -6451,13 +6558,13 @@ test_read_wifi_wep_agent_keys (void) */ /* ===== WIRELESS SETTING ===== */ - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); tmp = nm_setting_wireless_get_security (s_wifi); g_assert (g_strcmp0 (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0); @@ -6692,8 +6799,8 @@ test_write_wired_static (void) * However after re-reading they are dropped into IPv4 setting. * So, in order to comparison succeeded, move DNS domains back to IPv6 setting. */ - reread_s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG)); - reread_s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP6_CONFIG)); + reread_s_ip4 = nm_connection_get_setting_ip4_config (reread); + reread_s_ip6 = nm_connection_get_setting_ip6_config (reread); nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 2)); nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 3)); nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 3); @@ -7018,7 +7125,7 @@ test_read_write_static_routes_legacy (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, @@ -7041,7 +7148,7 @@ test_read_write_static_routes_legacy (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "read-write-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, @@ -7049,7 +7156,7 @@ test_read_write_static_routes_legacy (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, @@ -7628,7 +7735,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, * matter what scheme was used in the original connection they will be read * back in as paths. */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (reread); g_assert (s_8021x); g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); @@ -7657,7 +7764,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, * say it's not system-owned, and therefore it should not show up * in the re-read connection. */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); } @@ -10085,7 +10192,7 @@ test_write_wifi_wpa_then_open (void) g_object_unref (reread); /* Now change the connection to open and recheck */ - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); g_object_set (s_wifi, NM_SETTING_WIRELESS_SEC, NULL, NULL); nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); @@ -10534,7 +10641,7 @@ test_read_ibft_dhcp (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "ibft-dhcp-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_DHCP, @@ -10581,7 +10688,7 @@ test_read_ibft_dhcp (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "ibft-dhcp-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_DHCP, @@ -10613,7 +10720,7 @@ test_read_ibft_dhcp (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "ibft-dhcp-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_DHCP, @@ -10679,7 +10786,7 @@ test_read_ibft_static (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "ibft-static-verify-connection", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_STATIC, @@ -10726,7 +10833,7 @@ test_read_ibft_static (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "ibft-static-verify-wired", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_STATIC, @@ -10758,7 +10865,7 @@ test_read_ibft_static (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "ibft-static-verify-ip4", "failed to verify %s: missing %s setting", TEST_IFCFG_IBFT_STATIC, @@ -11754,6 +11861,8 @@ test_read_vlan_interface (void) char *route6file = NULL; gboolean ignore_error = FALSE; GError *error = NULL; + NMSettingVlan *s_vlan; + guint32 from = 0, to = 0; connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, NULL, @@ -11765,13 +11874,844 @@ test_read_vlan_interface (void) &route6file, &error, &ignore_error); - ASSERT (connection == NULL, - "vlan-interface-read", "unexpected success reading %s", TEST_IFCFG_VLAN_INTERFACE); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "vlan43"); + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); + g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, + NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING); + + /* Ingress map */ + g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP), ==, 2); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0, &from, &to)); + g_assert_cmpint (from, ==, 0); + g_assert_cmpint (to, ==, 1); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, &from, &to)); + g_assert_cmpint (from, ==, 2); + g_assert_cmpint (to, ==, 5); + + /* Egress map */ + g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP), ==, 3); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0, &from, &to)); + g_assert_cmpint (from, ==, 12); + g_assert_cmpint (to, ==, 3); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to)); + g_assert_cmpint (from, ==, 14); + g_assert_cmpint (to, ==, 7); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to)); + g_assert_cmpint (from, ==, 3); + g_assert_cmpint (to, ==, 1); + + g_object_unref (connection); +} + +#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-only-vlanid" + +static void +test_read_vlan_only_vlan_id (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + NMSettingVlan *s_vlan; + + connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert (nm_setting_vlan_get_interface_name (s_vlan) == NULL); + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); + + g_object_unref (connection); +} + +#define TEST_IFCFG_VLAN_ONLY_DEVICE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-only-device" + +static void +test_read_vlan_only_device (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + NMSettingVlan *s_vlan; + + connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_DEVICE, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "eth0.9"); + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 9); + + g_object_unref (connection); +} + +static void +test_write_vlan (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + char *written = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + gboolean success = FALSE; + + connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, + NULL, + TYPE_VLAN, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert (connection != NULL); + + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &written, + &error); + g_assert (success); + + unlink (written); + g_free (written); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); +} + +static void +test_write_vlan_only_vlanid (void) +{ + NMConnection *connection, *reread; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + char *written = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + gboolean success = FALSE; + + connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, + NULL, + TYPE_VLAN, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_free (unmanaged); + unmanaged = NULL; + g_free (keyfile); + keyfile = NULL; + g_free (routefile); + routefile = NULL; + g_free (route6file); + route6file = NULL; + + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &written, + &error); + g_assert (success); + + /* re-read the connection for comparison */ + reread = connection_from_file (written, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (written); + g_free (written); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + + g_assert_no_error (error); + g_assert (reread != NULL); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + g_object_unref (connection); + g_object_unref (reread); +} + +#define TEST_IFCFG_BOND_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-main" + +static void +test_read_bond_main (void) +{ + NMConnection *connection; + NMSettingBond *s_bond; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_BOND_MAIN, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "bond-main-read", "unexpected failure reading %s", TEST_IFCFG_BOND_MAIN); + + ASSERT (nm_connection_verify (connection, &error), + "bond-main-read", "failed to verify %s: %s", TEST_IFCFG_BOND_MAIN, error->message); + + /* ===== Bonding SETTING ===== */ + + s_bond = nm_connection_get_setting_bond (connection); + ASSERT (s_bond != NULL, + "bond-main", "failed to verify %s: missing %s setting", + TEST_IFCFG_BOND_MAIN, + NM_SETTING_BOND_SETTING_NAME); + + ASSERT (g_strcmp0 (nm_setting_bond_get_interface_name (s_bond), "bond0") == 0, + "bond-main", "failed to verify %s: DEVICE=%s does not match bond0", + TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_interface_name (s_bond)); + + ASSERT (g_strcmp0 (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), "100") == 0, + "bond-main", "failed to verify %s: miimon=%s does not match 100", + TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON)); g_free (unmanaged); g_free (keyfile); g_free (routefile); g_free (route6file); + g_object_unref (connection); +} + +static void +test_write_bond_main (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingBond *s_bond; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSettingWired *s_wired; + char *uuid; + const guint32 ip1 = htonl (0x01010103); + const guint32 gw = htonl (0x01010101); + const guint32 prefix = 24; + NMIP4Address *addr; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "bond-main-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Bond Main", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* bond setting */ + s_bond = (NMSettingBond *) nm_setting_bond_new (); + ASSERT (s_bond != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_BOND_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_bond)); + + g_object_set (s_bond, + NM_SETTING_BOND_INTERFACE_NAME, "bond0", + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NULL); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "bond-main-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "bond-main-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "bond-main-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_BOND, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "bond-main-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "bond-main-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "bond-main-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +#define TEST_IFCFG_BOND_SLAVE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-slave" + +static void +test_read_bond_slave (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_BOND_SLAVE, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "bond-slave-read", "unexpected failure reading %s", TEST_IFCFG_BOND_MAIN); + + ASSERT (nm_connection_verify (connection, &error), + "bond-slave-read", "failed to verify %s: %s", TEST_IFCFG_BOND_MAIN, error->message); + + s_con = nm_connection_get_setting_connection (connection); + ASSERT (s_con != NULL, + "bond-slave-read", "failed to verify %s: missing %s setting", + TEST_IFCFG_BOND_SLAVE, NM_SETTING_CONNECTION_SETTING_NAME); + + ASSERT (g_strcmp0 (nm_setting_connection_get_master (s_con), "bond0") == 0, + "bond-slave-read", "failed to verify %s: master is not bond0", + TEST_IFCFG_BOND_SLAVE); + + ASSERT (g_strcmp0 (nm_setting_connection_get_slave_type (s_con), NM_SETTING_BOND_SETTING_NAME) == 0, + "bond-slave-read", "failed to verify %s: slave-type is not bond", + TEST_IFCFG_BOND_SLAVE); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +static void +test_write_bond_slave (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; + GByteArray *mac; + guint32 mtu = 1492; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "bond-slave-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "bond-slave-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Bond Slave", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, "bond0", + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "bond-main-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, mac, + NM_SETTING_WIRED_MTU, mtu, + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "bond-slave-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "bond-slave-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "bond-slave-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "bond-slave-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "bond-slave-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "bond-slave-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "bond-slave-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "bond-slave-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +#define TEST_IFCFG_INFINIBAND TEST_IFCFG_DIR"/network-scripts/ifcfg-test-infiniband" + +static void +test_read_infiniband (void) +{ + NMConnection *connection; + NMSettingInfiniband *s_infiniband; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const GByteArray *array; + char expected_mac_address[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; + const char *transport_mode; + + connection = connection_from_file (TEST_IFCFG_INFINIBAND, + NULL, + TYPE_INFINIBAND, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "infiniband-read", "failed to read %s: %s", TEST_IFCFG_INFINIBAND, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "infiniband-verify", "failed to verify %s: %s", TEST_IFCFG_INFINIBAND, error->message); + + ASSERT (unmanaged == NULL, + "infiniband-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_INFINIBAND); + + /* ===== INFINIBAND SETTING ===== */ + + s_infiniband = nm_connection_get_setting_infiniband (connection); + ASSERT (s_infiniband != NULL, + "infiniband-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME); + + /* MAC address */ + array = nm_setting_infiniband_get_mac_address (s_infiniband); + ASSERT (array != NULL, + "infiniband-verify-infiniband", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS); + ASSERT (array->len == INFINIBAND_ALEN, + "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS); + + /* Transport mode */ + transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); + ASSERT (transport_mode != NULL, + "infiniband-verify-infiniband", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_TRANSPORT_MODE); + ASSERT (strcmp (transport_mode, "connected") == 0, + "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_INFINIBAND, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_TRANSPORT_MODE); + + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +static void +test_write_infiniband (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingInfiniband *s_infiniband; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + unsigned char tmpmac[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; + GByteArray *mac; + guint32 mtu = 65520; + char *uuid; + const guint32 ip1 = htonl (0x01010103); + const guint32 gw = htonl (0x01010101); + const guint32 prefix = 24; + NMIP4Address *addr; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "infiniband-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "infiniband-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write InfiniBand", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, + NULL); + g_free (uuid); + + /* InfiniBand setting */ + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); + ASSERT (s_infiniband != NULL, + "infiniband-write", "failed to allocate new %s setting", + NM_SETTING_INFINIBAND_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + + g_object_set (s_infiniband, + NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, + NM_SETTING_INFINIBAND_MTU, mtu, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "infiniband-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NULL); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-static-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "infiniband-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "infiniband-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "infiniband-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_INFINIBAND, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "infiniband-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "infiniband-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "infiniband-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); } #define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex" @@ -11843,6 +12783,7 @@ int main (int argc, char **argv) test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_ALWAYS, NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); test_read_wifi_wpa_psk (); + test_read_wifi_wpa_psk_2 (); test_read_wifi_wpa_psk_unquoted (); test_read_wifi_wpa_psk_unquoted2 (); test_read_wifi_wpa_psk_adhoc (); @@ -11856,6 +12797,10 @@ int main (int argc, char **argv) test_read_wifi_wep_no_keys (); test_read_permissions (); test_read_wifi_wep_agent_keys (); + test_read_infiniband (); + test_read_vlan_interface (); + test_read_vlan_only_vlan_id (); + test_read_vlan_only_device (); test_write_wired_static (); test_write_wired_static_ip6_only (); @@ -11908,6 +12853,12 @@ int main (int argc, char **argv) TRUE, TRUE, "really insecure passphrase04!"); + test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK Passphrase Special Chars", + "wifi-wpa-wpa2-psk-passphrase-write-spec-chars", + FALSE, + TRUE, + TRUE, + "blah`oops\"grr'$*@~!%"); test_write_wifi_wpa_psk_adhoc (); test_write_wifi_wpa_eap_tls (); test_write_wifi_wpa_eap_ttls_tls (); @@ -11919,6 +12870,9 @@ int main (int argc, char **argv) test_write_wired_ctc_dhcp (); test_write_permissions (); test_write_wifi_wep_agent_keys (); + test_write_infiniband (); + test_write_vlan (); + test_write_vlan_only_vlanid (); /* iSCSI / ibft */ test_read_ibft_dhcp (); @@ -11930,6 +12884,12 @@ int main (int argc, char **argv) test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1"); test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2"); + /* bonding */ + test_read_bond_main (); + test_read_bond_slave (); + test_write_bond_main (); + test_write_bond_slave (); + /* Stuff we expect to fail for now */ test_write_wired_pppoe (); test_write_vpn (); @@ -11937,7 +12897,6 @@ int main (int argc, char **argv) test_write_mobile_broadband (FALSE); test_read_bridge_main (); test_read_bridge_component (); - test_read_vlan_interface (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c index 92a0b802..0b7ddf36 100644 --- a/src/settings/plugins/ifcfg-rh/utils.c +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 - 2010 Red Hat, Inc. + * (C) Copyright 2008 - 2012 Red Hat, Inc. */ #include <glib.h> @@ -116,6 +116,89 @@ utils_hexstr2bin (const char *hex, size_t len) /* End from hostap */ /* + * utils_single_quote_string + * + * Put string inside single quotes and remove CR, LF characters. If single quote + * is present, escape it with a backslash and prepend the whole string with $ + * in order to have $'string'. That allows us to use single quote inside + * single quotes without breaking bash syntax. (man bash, section QUOTING). + * + * Caller is responsible for freeing the returned string. + */ +char * +utils_single_quote_string (const char *str) +{ + static const char const drop_chars[] = "\r\n"; /* drop CR and LF */ + static const char escape_char = '\\'; /* escape char is backslash */ + static const char quote_char = '\''; /* quote char is single quote */ + size_t i, slen, j = 0; + size_t drop = 0, extra = 0; + char *new_str; + + slen = strlen (str); + for (i = 0; i < slen; i++) { + if (str[i] == quote_char) + extra++; + if (strchr (drop_chars, str[i])) + drop++; + } + new_str = g_malloc0 (slen + extra - drop + 4); /* 4 is for $''\0*/ + if (!new_str) return NULL; + + if (extra > 0) + new_str[j++] = '$'; + new_str[j++] = quote_char; + for (i = 0; i < slen; i++) { + if (strchr (drop_chars, str[i])) + continue; + if (str[i] == quote_char) + new_str[j++] = escape_char; + new_str[j++] = str[i]; + } + new_str[j] = quote_char; + + return new_str; +} + +/* + * utils_single_unquote_string + * + * Remove string from single (or double) quotes, and remove escaping of '. + * Also remove first $ if the string is in the form of $'string'. + * + * Caller is responsible for freeing the returned string. + */ +char * +utils_single_unquote_string (const char *str) +{ + static const char escape_char = '\\'; /* escape char is backslash */ + static const char q_char = '\''; /* quote char is single quote */ + static const char dq_char = '"'; /* double quote char */ + size_t i, slen, j = 0, quote = 0, dollar = 0; + char *new_str; + + slen = strlen (str); + new_str = g_malloc0 (slen + 1); + if (!new_str) return NULL; + + if ( (slen >= 2 && (str[0] == dq_char || str[0] == q_char) && str[0] == str[slen-1]) + || (slen >= 3 && str[0] == '$' && str[1] == q_char && str[1] == str[slen-1])) { + quote = 1; + if (str[0] == '$') dollar = 1; + } + + i = quote + dollar; + while (i < slen - quote) { + if (str[i] == escape_char && str[i+1] == q_char) + i++; + new_str[j++] = str[i++]; + } + new_str[j] = '\0'; + + return new_str; +} + +/* * Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when * installing packages. * @@ -360,3 +443,17 @@ gone: return ret; } +gboolean +utils_disabling_ip4_config_allowed (NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + /* bonding slaves are allowed to have no ip configuration */ + if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME)) + return TRUE; + + return FALSE; +} diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h index d5e3a133..4fe7303b 100644 --- a/src/settings/plugins/ifcfg-rh/utils.h +++ b/src/settings/plugins/ifcfg-rh/utils.h @@ -15,13 +15,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 - 2009 Red Hat, Inc. + * (C) Copyright 2008 - 2012 Red Hat, Inc. */ #ifndef _UTILS_H_ #define _UTILS_H_ #include <glib.h> +#include <nm-connection.h> #include "shvar.h" #include "common.h" @@ -29,6 +30,10 @@ char *utils_bin2hexstr (const char *bytes, int len, int final_len); char *utils_hexstr2bin (const char *hex, size_t len); +char *utils_single_quote_string (const char *str); + +char *utils_single_unquote_string (const char *str); + char *utils_cert_path (const char *parent, const char *suffix); const char *utils_get_ifcfg_name (const char *file, gboolean only_ifcfg); @@ -47,5 +52,7 @@ shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create); gboolean utils_has_route_file_new_syntax (const char *filename); +gboolean utils_disabling_ip4_config_allowed (NMConnection *connection); + #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 068bcda2..e2aa57dd 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2011 Red Hat, Inc. + * Copyright (C) 2009 - 2012 Red Hat, Inc. */ #include <ctype.h> @@ -28,6 +28,7 @@ #include <sys/stat.h> #include <unistd.h> #include <stdio.h> +#include <netinet/ether.h> #include <nm-setting-connection.h> #include <nm-setting-wired.h> @@ -36,6 +37,7 @@ #include <nm-setting-ip4-config.h> #include <nm-setting-ip6-config.h> #include <nm-setting-pppoe.h> +#include <nm-setting-vlan.h> #include <nm-utils.h> #include "common.h" @@ -456,7 +458,7 @@ write_8021x_setting (NMConnection *connection, gboolean success = FALSE; GString *phase2_auth; - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); if (!s_8021x) { /* If wired, clear KEY_MGMT */ if (wired) @@ -504,6 +506,24 @@ write_8021x_setting (NMConnection *connection, if (value && !strcmp (value, "1")) svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", "yes", FALSE); + /* PAC file */ + value = nm_setting_802_1x_get_pac_file (s_8021x); + svSetValue (ifcfg, "IEEE_8021X_PAC_FILE", NULL, FALSE); + if (value) + svSetValue (ifcfg, "IEEE_8021X_PAC_FILE", value, FALSE); + + /* FAST PAC provisioning */ + value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x); + svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", NULL, FALSE); + if (value) { + if (strcmp (value, "1") == 0) + svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-unauth", FALSE); + else if (strcmp (value, "2") == 0) + svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-auth", FALSE); + else if (strcmp (value, "3") == 0) + svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-unauth allow-auth", FALSE); + } + /* Phase2 auth methods */ svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", NULL, FALSE); phase2_auth = g_string_new (NULL); @@ -554,7 +574,7 @@ write_wireless_security_setting (NMConnection *connection, guint32 i, num; GString *str; - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); if (!s_wsec) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); @@ -716,24 +736,20 @@ write_wireless_security_setting (NMConnection *connection, /* WPA Passphrase */ if (wpa) { - GString *quoted = NULL; + char *quoted = NULL; psk = nm_setting_wireless_security_get_psk (s_wsec); if (psk && (strlen (psk) != 64)) { /* Quote the PSK since it's a passphrase */ - quoted = g_string_sized_new (strlen (psk) + 2); /* 2 for quotes */ - g_string_append_c (quoted, '"'); - g_string_append (quoted, psk); - g_string_append_c (quoted, '"'); + quoted = utils_single_quote_string (psk); } set_secret (ifcfg, "WPA_PSK", - quoted ? quoted->str : psk, + quoted ? quoted : psk, "WPA_PSK_FLAGS", nm_setting_wireless_security_get_psk_flags (s_wsec), TRUE); - if (quoted) - g_string_free (quoted, TRUE); + g_free (quoted); } else { set_secret (ifcfg, "WPA_PSK", @@ -761,7 +777,7 @@ write_wireless_setting (NMConnection *connection, gboolean adhoc = FALSE, hex_ssid = FALSE; const GSList *macaddr_blacklist; - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); @@ -944,6 +960,48 @@ write_wireless_setting (NMConnection *connection, } static gboolean +write_infiniband_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingInfiniband *s_infiniband; + const GByteArray *mac; + char *tmp; + const char *transport_mode; + guint32 mtu; + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_INFINIBAND_SETTING_NAME); + return FALSE; + } + + svSetValue (ifcfg, "HWADDR", NULL, FALSE); + mac = nm_setting_infiniband_get_mac_address (s_infiniband); + if (mac) { + tmp = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND); + svSetValue (ifcfg, "HWADDR", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "MTU", NULL, FALSE); + mtu = nm_setting_infiniband_get_mtu (s_infiniband); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + svSetValue (ifcfg, "MTU", tmp, FALSE); + g_free (tmp); + } + + transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); + svSetValue (ifcfg, "CONNECTED_MODE", + strcmp (transport_mode, "connected") == 0 ? "yes" : "no", + FALSE); + + svSetValue (ifcfg, "TYPE", TYPE_INFINIBAND, FALSE); + + return TRUE; +} + +static gboolean write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; @@ -955,7 +1013,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) GString *str; const GSList *macaddr_blacklist; - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME); @@ -1064,11 +1122,143 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } +static GString *vlan_priority_maplist_to_stringlist (NMSettingVlan *s_vlan, NMVlanPriorityMap map) +{ + GSList *strlist = NULL, *iter; + GString *value = NULL; + + if (map == NM_VLAN_INGRESS_MAP) + g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, &strlist, NULL); + else if (map == NM_VLAN_EGRESS_MAP) + g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, &strlist, NULL); + else + return NULL; + + value = g_string_new (""); + for (iter = strlist; iter; iter = g_slist_next (iter)) + g_string_append_printf (value, "%s%s", value->len ? "," : "", (const char *) iter->data); + + nm_utils_slist_free (strlist, g_free); + + return value; +} + +static gboolean +write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingVlan *s_vlan; + NMSettingConnection *s_con; + char *tmp; + guint32 vlan_flags = 0; + GString *text = NULL; + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing connection setting"); + return FALSE; + } + + s_vlan = nm_connection_get_setting_vlan (connection); + if (!s_vlan) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing VLAN setting"); + return FALSE; + } + + svSetValue (ifcfg, "VLAN", "yes", FALSE); + svSetValue (ifcfg, "TYPE", TYPE_VLAN, FALSE); + svSetValue (ifcfg, "DEVICE", nm_setting_vlan_get_interface_name (s_vlan), FALSE); + svSetValue (ifcfg, "PHYSDEV", nm_setting_vlan_get_parent (s_vlan), FALSE); + svSetValue (ifcfg, "MASTER", nm_setting_connection_get_master (s_con), FALSE); + + tmp = g_strdup_printf ("%d", nm_setting_vlan_get_id (s_vlan)); + svSetValue (ifcfg, "VLAN_ID", tmp, FALSE); + g_free (tmp); + + vlan_flags = nm_setting_vlan_get_flags (s_vlan); + if (vlan_flags & NM_VLAN_FLAG_REORDER_HEADERS) + svSetValue (ifcfg, "REORDER_HDR", "1", FALSE); + else + svSetValue (ifcfg, "REORDER_HDR", "0", FALSE); + + svSetValue (ifcfg, "VLAN_FLAGS", NULL, FALSE); + if (vlan_flags & NM_VLAN_FLAG_GVRP) { + if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) + svSetValue (ifcfg, "VLAN_FLAGS", "GVRP,LOOSE_BINDING", FALSE); + else + svSetValue (ifcfg, "VLAN_FLAGS", "GVRP", FALSE); + } else if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) + svSetValue (ifcfg, "VLAN_FLAGS", "LOOSE_BINDING", FALSE); + + text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP); + svSetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE); + if (text) + g_string_free (text, TRUE); + + text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_EGRESS_MAP); + svSetValue (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE); + if (text) + g_string_free (text, TRUE); + + return TRUE; +} + +static gboolean +write_bonding_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingBond *s_bond; + const char *iface; + guint32 i, num_opts; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_BOND_SETTING_NAME); + return FALSE; + } + + iface = nm_setting_bond_get_interface_name (s_bond); + if (!iface) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing interface name"); + return FALSE; + } + + svSetValue (ifcfg, "DEVICE", iface, FALSE); + svSetValue (ifcfg, "BONDING_OPTS", NULL, FALSE); + + num_opts = nm_setting_bond_get_num_options (s_bond); + if (num_opts > 0) { + GString *str = g_string_sized_new (64); + + for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) { + const char *key, *value; + + if (!nm_setting_bond_get_option (s_bond, i, &key, &value)) + continue; + + if (str->len) + g_string_append_c (str, ' '); + + g_string_append_printf (str, "%s=%s", key, value); + } + + if (str->len) + svSetValue (ifcfg, "BONDING_OPTS", str->str, FALSE); + + g_string_free (str, TRUE); + } + + svSetValue (ifcfg, "TYPE", TYPE_BOND, FALSE); + svSetValue (ifcfg, "BONDING_MASTER", "yes", FALSE); + + return TRUE; +} + static void write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) { guint32 n, i; GString *str; + const char *master; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); @@ -1097,6 +1287,14 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) svSetValue (ifcfg, "USERS", str->str, FALSE); g_string_free (str, TRUE); } + + svSetValue (ifcfg, "ZONE", nm_setting_connection_get_zone(s_con), FALSE); + + master = nm_setting_connection_get_master (s_con); + if (master) { + if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME)) + svSetValue (ifcfg, "MASTER", master, FALSE); + } } static gboolean @@ -1172,7 +1370,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) gboolean fake_ip4 = FALSE; const char *method = NULL; - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); @@ -1509,7 +1707,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) GString *ip_str1, *ip_str2, *ip_ptr; char *route6_path; - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!s_ip6) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME); @@ -1587,7 +1785,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) } /* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */ num = nm_setting_ip6_config_get_num_dns (s_ip6); for (i = 0; i < 254; i++) { @@ -1644,6 +1842,24 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes", FALSE); + /* IPv6 Privacy Extensions */ + svSetValue (ifcfg, "IPV6_PRIVACY", NULL, FALSE); + svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", NULL, FALSE); + switch (nm_setting_ip6_config_get_ip6_privacy (s_ip6)){ + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + svSetValue (ifcfg, "IPV6_PRIVACY", "no", FALSE); + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + svSetValue (ifcfg, "IPV6_PRIVACY", "rfc3041", FALSE); + svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", "yes", FALSE); + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + svSetValue (ifcfg, "IPV6_PRIVACY", "rfc3041", FALSE); + break; + default: + break; + } + /* Static routes go to route6-<dev> file */ route6_path = utils_get_route6_path (ifcfg->fileName); if (!route6_path) { @@ -1665,6 +1881,7 @@ error: static char * escape_id (const char *id) { + static const char const as_dash[] = "\\][|/=()!"; char *escaped = g_strdup (id); char *p = escaped; @@ -1672,9 +1889,7 @@ escape_id (const char *id) while (*p) { if (*p == ' ') *p = '_'; - else if (*p == '/') - *p = '-'; - else if (*p == '\\') + else if (strchr (as_dash, *p)) *p = '-'; p++; } @@ -1691,6 +1906,7 @@ write_connection (NMConnection *connection, GError **error) { NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; NMSettingIP6Config *s_ip6; gboolean success = FALSE; shvarFile *ifcfg = NULL; @@ -1699,7 +1915,7 @@ write_connection (NMConnection *connection, gboolean no_8021x = FALSE; gboolean wired = FALSE; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); if (!s_con) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing '%s' setting", NM_SETTING_CONNECTION_SETTING_NAME); @@ -1759,7 +1975,7 @@ write_connection (NMConnection *connection, if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { // FIXME: can't write PPPoE at this time - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)) { + if (nm_connection_get_setting_pppoe (connection)) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Can't write connection type '%s'", NM_SETTING_PPPOE_SETTING_NAME); @@ -1769,9 +1985,18 @@ write_connection (NMConnection *connection, if (!write_wired_setting (connection, ifcfg, error)) goto out; wired = TRUE; + } else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) { + if (!write_vlan_setting (connection, ifcfg, error)) + goto out; } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { if (!write_wireless_setting (connection, ifcfg, &no_8021x, error)) goto out; + } else if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + if (!write_infiniband_setting (connection, ifcfg, error)) + goto out; + } else if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME)) { + if (!write_bonding_setting (connection, ifcfg, error)) + goto out; } else { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Can't write connection type '%s'", type); @@ -1783,10 +2008,13 @@ write_connection (NMConnection *connection, goto out; } - if (!write_ip4_setting (connection, ifcfg, error)) - goto out; + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4 || !utils_disabling_ip4_config_allowed (connection)) { + if (!write_ip4_setting (connection, ifcfg, error)) + goto out; + } - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) { if (!write_ip6_setting (connection, ifcfg, error)) goto out; diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in index dfa84086..ac528342 100644 --- a/src/settings/plugins/ifcfg-suse/Makefile.in +++ b/src/settings/plugins/ifcfg-suse/Makefile.in @@ -170,6 +170,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -224,11 +226,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -239,6 +245,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -278,6 +285,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/settings/plugins/ifcfg-suse/plugin.c b/src/settings/plugins/ifcfg-suse/plugin.c index 78db56e5..2ec90d81 100644 --- a/src/settings/plugins/ifcfg-suse/plugin.c +++ b/src/settings/plugins/ifcfg-suse/plugin.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -309,7 +309,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c } G_MODULE_EXPORT GObject * -nm_system_config_factory (void) +nm_system_config_factory (const char *config_file) { static SCPluginIfcfg *singleton = NULL; diff --git a/src/settings/plugins/ifnet/Makefile.am b/src/settings/plugins/ifnet/Makefile.am index 9bf8a79a..84deda5b 100644 --- a/src/settings/plugins/ifnet/Makefile.am +++ b/src/settings/plugins/ifnet/Makefile.am @@ -45,13 +45,13 @@ lib_ifnet_io_la_SOURCES = \ wpa_parser.c lib_ifnet_io_la_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - -DG_DISABLE_DEPRECATED \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DSBINDIR=\"$(sbindir)\" + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" lib_ifnet_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS)\ - $(GIO_LIBS) + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS)\ + $(GIO_LIBS) diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in index 8218b85a..322adbf8 100644 --- a/src/settings/plugins/ifnet/Makefile.in +++ b/src/settings/plugins/ifnet/Makefile.in @@ -218,6 +218,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -272,11 +274,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -287,6 +293,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -326,6 +333,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -433,16 +442,16 @@ lib_ifnet_io_la_SOURCES = \ wpa_parser.c lib_ifnet_io_la_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - -DG_DISABLE_DEPRECATED \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DSBINDIR=\"$(sbindir)\" + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" lib_ifnet_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS)\ - $(GIO_LIBS) + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS)\ + $(GIO_LIBS) all: all-recursive diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index b4aaa8d2..78812f97 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -45,12 +45,6 @@ #include "connection_parser.h" #include "nm-ifnet-connection.h" -static const char * -get_prefix (void) -{ - return _("System"); -} - static void update_connection_id (NMConnection *connection, const char *conn_name) { @@ -62,16 +56,12 @@ update_connection_id (NMConnection *connection, const char *conn_name) name_len = strlen (conn_name); if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { - gchar * conn_name_printable = utils_hexstr2bin (conn_name + 2, name_len - 2); - idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name_printable); - g_free (conn_name_printable); + idstr = utils_hexstr2bin (conn_name + 2, name_len - 2); } else - idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name); + idstr = g_strdup_printf ("%s", conn_name); uuid_base = idstr; uuid = nm_utils_uuid_generate_from_string (uuid_base); - setting = - (NMSettingConnection *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_CONNECTION); + setting = nm_connection_get_setting_connection (connection); g_object_set (setting, NM_SETTING_CONNECTION_ID, idstr, NM_SETTING_CONNECTION_UUID, uuid, NULL); PLUGIN_PRINT (IFNET_PLUGIN_NAME, @@ -509,20 +499,17 @@ static gboolean read_mac_address (const char *conn_name, GByteArray **array, GError **error) { const char *value = ifnet_get_data (conn_name, "mac"); - struct ether_addr *mac; if (!value || !strlen (value)) return TRUE; - mac = ether_aton (value); - if (!mac) { + *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!*array) { g_set_error (error, ifnet_plugin_error_quark (), 0, - "The MAC address '%s' was invalid.", value); + "The MAC address '%s' was invalid.", value); return FALSE; } - *array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); return TRUE; } @@ -567,7 +554,7 @@ make_wired_connection_setting (NMConnection *connection, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } -/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, +/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/ static void make_ip4_setting (NMConnection *connection, @@ -596,19 +583,19 @@ make_ip4_setting (NMConnection *connection, g_object_unref (ip4_setting); return; } - if (!strcmp (method, "dhcp")) + if (strstr (method, "dhcp")) g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); - else if (!strcmp (method, "autoip")){ + else if (strstr (method, "autoip")) { g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); return; - } else if (!strcmp (method, "shared")){ + } else if (strstr (method, "shared")) { g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, @@ -663,7 +650,7 @@ make_ip4_setting (NMConnection *connection, } /* add dhcp hostname and client id */ - if (!is_static_block && !strcmp (method, "dhcp")) { + if (!is_static_block && strstr (method, "dhcp")) { gchar *dhcp_hostname, *client_id; get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); @@ -868,7 +855,7 @@ make_ip6_setting (NMConnection *connection, nm_ip6_route_set_dest (route, iblock->ip); nm_ip6_route_set_next_hop (route, iblock->next_hop); nm_ip6_route_set_prefix (route, iblock->prefix); - /* metric is not per routes configuration right now + /* metric is not per routes configuration right now * global metric is also supported (metric="x") */ if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { metric = strtol (metric_str, NULL, 10); @@ -995,7 +982,7 @@ make_wireless_connection_setting (const char *conn_name, goto error; } - /* mode=0: infrastructure + /* mode=0: infrastructure * mode=1: adhoc */ value = wpa_get_value (conn_name, "mode"); if (value) @@ -1012,18 +999,15 @@ make_wireless_connection_setting (const char *conn_name, /* BSSID setting */ value = wpa_get_value (conn_name, "bssid"); if (value) { - struct ether_addr *eth; GByteArray *bssid; - eth = ether_aton (value); - if (!eth) { + bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!bssid) { g_set_error (error, ifnet_plugin_error_quark (), 0, - "Invalid BSSID '%s'", value); + "Invalid BSSID '%s'", value); goto error; } - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, bssid, NULL); g_byte_array_free (bssid, TRUE); @@ -1666,9 +1650,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, GError **error connection = nm_connection_new (); if (!connection) return NULL; - setting = - (NMSettingConnection *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_CONNECTION); + setting = nm_connection_get_setting_connection (connection); if (!setting) { setting = NM_SETTING_CONNECTION (nm_setting_connection_new ()); g_assert (setting); @@ -2021,10 +2003,7 @@ write_8021x_setting (NMConnection *connection, GString *phase2_auth; GString *phase1; - s_8021x = - (NMSetting8021x *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_802_1X); - + s_8021x = nm_connection_get_setting_802_1x (connection); if (!s_8021x) { return TRUE; } @@ -2119,9 +2098,7 @@ write_wireless_security_setting (NMConnection * connection, guint32 i, num; GString *str; - s_wsec = - (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); if (!s_wsec) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2171,7 +2148,6 @@ write_wireless_security_setting (NMConnection * connection, wpa_set_data (conn_name, "auth_alg", NULL); /* Default WEP TX key index */ - wpa_set_data (conn_name, "wep_tx_keyidx", NULL); if (wep) { tmp = g_strdup_printf ("%d", @@ -2179,7 +2155,8 @@ write_wireless_security_setting (NMConnection * connection, (s_wsec)); wpa_set_data (conn_name, "wep_tx_keyidx", tmp); g_free (tmp); - } + } else + wpa_set_data (conn_name, "wep_tx_keyidx", NULL); /* WEP keys */ for (i = 0; i < 4; i++) { @@ -2287,7 +2264,7 @@ write_wireless_setting (NMConnection *connection, gboolean adhoc = FALSE, hex_ssid = FALSE; gchar *ssid_str, *tmp; - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2406,9 +2383,7 @@ write_wired_setting (NMConnection *connection, char *tmp; guint32 mtu; - s_wired = - (NMSettingWired *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2462,9 +2437,7 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err gboolean has_def_route = FALSE; gboolean success = FALSE; - s_ip4 = - (NMSettingIP4Config *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2668,9 +2641,7 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err NMIP6Address *addr; const struct in6_addr *ip; - s_ip6 = - (NMSettingIP6Config *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!s_ip6) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2856,7 +2827,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, NMSettingPPPOE *s_pppoe; /* Writing pppoe setting */ - s_pppoe = NM_SETTING_PPPOE (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)); + s_pppoe = nm_connection_get_setting_pppoe (connection); if (!write_pppoe_setting (conn_name, s_pppoe)) goto out; pppoe = TRUE; @@ -2884,7 +2855,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, if (!write_ip4_setting (connection, conn_name, error)) goto out; - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) { /* IPv6 Setting */ if (!write_ip6_setting (connection, conn_name, error)) @@ -2972,9 +2943,7 @@ get_wireless_name (NMConnection * connection) char buf[33]; int i = 0; - s_wireless = - (NMSettingWireless *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) return NULL; @@ -3020,7 +2989,7 @@ ifnet_add_new_connection (NMConnection *connection, const char *type; gchar *new_type, *new_name = NULL; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); type = nm_setting_connection_get_connection_type (s_con); g_assert (type); diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index a48103db..38765f5f 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -22,6 +22,7 @@ #include <string.h> #include <nm-system-config-interface.h> #include <stdio.h> +#include "plugin.h" #include "net_parser.h" #include "net_utils.h" @@ -106,7 +107,6 @@ ignore_connection_name (const char *name) if (strlen (name) == 12 && is_hex (name)) result = TRUE; return result; - } static gboolean @@ -169,12 +169,10 @@ init_block_by_line (gchar * buf) conn = add_new_connection_config ("wireless", pos); } data = g_strdup (key_value[1]); - tmp = strip_string (data, '('); - tmp = strip_string (tmp, ')'); - strip_string (tmp, '"'); + tmp = strip_string (data, '"'); strip_string (tmp, '\''); if (conn) - g_hash_table_insert (conn, g_strdup (key_value[0]), + g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '), g_strdup (tmp)); g_free (data); g_strfreev (key_value); @@ -195,26 +193,31 @@ destroy_connection_config (GHashTable * conn) g_hash_table_destroy (conn); } -// read settings from /etc/NetworkManager/nm-system-settings.conf +/* Read settings from NetworkManager's config file */ const char * ifnet_get_global_setting (const char *group, const char *key) { GError *error = NULL; GKeyFile *keyfile = g_key_file_new (); gchar *result = NULL; + const char *conf_file; + + /* Get confing file name from plugin. */ + conf_file = ifnet_plugin_get_conf_file (); if (!g_key_file_load_from_file (keyfile, - IFNET_SYSTEM_SETTINGS_KEY_FILE, + conf_file, G_KEY_FILE_NONE, &error)) { PLUGIN_WARN (IFNET_PLUGIN_NAME, "loading system config file (%s) caused error: (%d) %s", - IFNET_SYSTEM_SETTINGS_KEY_FILE, + conf_file, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else { result = g_key_file_get_string (keyfile, group, key, &error); } g_key_file_free (keyfile); + return result; } @@ -283,6 +286,20 @@ is_function (gchar * line) return FALSE; } +static void +append_line (GString *buf, gchar* line) +{ + gchar *pos = NULL; + + if ((pos = strchr (line, '#')) != NULL) + *pos = '\0'; + g_strstrip (line); + + if (line[0] != '\0') + g_string_append_printf (buf, " %s", line); + g_free (line); +} + gboolean ifnet_init (gchar * config_file) { @@ -292,6 +309,8 @@ ifnet_init (gchar * config_file) /* Handle multiple lines with brackets */ gboolean complete = TRUE; + gboolean openrc_style = TRUE; + /* line buffer */ GString *buf; @@ -319,36 +338,60 @@ ifnet_init (gchar * config_file) strip_function (channel, line); continue; } - if (line[0] != '#' && line[0] != '\0') { - gchar *pos = NULL; + // New openrc style, bash arrays are not allowed. We only care about '"' + if (openrc_style && line[0] != '#' && line[0] != '\0' + && !strchr (line, '(') && !strchr (line, ')')) { + gchar *tmp = line; + + while ((tmp = strchr (tmp, '"')) != NULL) { + complete = !complete; + ++tmp; + } + + append_line (buf, line); + // Add "(separator) for routes. It will be easier for later parsing + if (strstr (buf->str, "via")) + g_string_append_printf (buf, "\""); + + if (!complete) + continue; + + strip_string (buf->str, '"'); + + init_block_by_line (buf->str); + g_string_free (buf, TRUE); + buf = g_string_new (NULL); + } + // Old bash arrays for baselayout-1, to be deleted + else if (line[0] != '#' && line[0] != '\0') { if (!complete) { complete = g_strrstr (line, ")") == NULL ? FALSE : TRUE; - if ((pos = strchr (line, '#')) != NULL) - *pos = '\0'; - g_strstrip (line); - if (line[0] != '\0') { - g_string_append_printf (buf, - " %s", line); - } - g_free (line); - if (!complete) + + append_line (buf, line); + if (!complete) { + openrc_style = FALSE; continue; + } + else { + openrc_style = TRUE; + } } else { complete = (g_strrstr (line, "(") != NULL && g_strrstr (line, ")") != NULL) || g_strrstr (line, "(") == NULL; - if ((pos = strchr (line, '#')) != NULL) - *pos = '\0'; - g_strstrip (line); - if (line[0] != '\0') - g_string_append (buf, line); - g_free (line); + + append_line (buf, line); if (!complete) + { + openrc_style = FALSE; continue; + } else { + openrc_style = TRUE; + } } init_block_by_line (buf->str); g_string_free (buf, TRUE); @@ -374,6 +417,34 @@ ifnet_get_data (const char *conn_name, const char *key) return NULL; } +/* format ip values for comparison */ +static gchar* +format_ip_for_comparison (const gchar * value) +{ + gchar **ipset; + guint length, i; + GString *formated_string = g_string_new (NULL); + gchar *formatted = NULL; + + ipset = g_strsplit (value, "\"", 0); + length = g_strv_length (ipset); + + for (i = 0; i < length; i++) + { + strip_string (ipset[i], ' '); + if (ipset[i][0] != '\0') + g_string_append_printf (formated_string, + "%s ", ipset[i]); + } + formatted = g_strdup (formated_string->str); + formatted[formated_string->len - 1] = '\0'; + + g_string_free (formated_string, TRUE); + g_strfreev (ipset); + + return formatted; +} + void ifnet_set_data (const char *conn_name, const char *key, const char *value) { @@ -391,7 +462,31 @@ ifnet_set_data (const char *conn_name, const char *key, const char *value) } /* Remove existing key value pair */ if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) { - if (stripped && !strcmp(old_value, stripped)){ + + /* This ugly hack is due to baselayout compatibility. We have to + * deal with different ip format. So sometimes we have the same ips + * but different strings. + */ + if (stripped && + (!strcmp (key, "config") + || !strcmp (key, "routes") + || !strcmp (key, "pppd") + || !strcmp (key, "chat"))) + { + gchar *old_ips = format_ip_for_comparison (old_value); + gchar *new_ips = format_ip_for_comparison (value); + if(!strcmp (old_ips, new_ips)) + { + g_free (stripped); + g_free (old_ips); + g_free (new_ips); + return; + } + g_free (old_ips); + g_free (new_ips); + } + + if (stripped && !strcmp (old_value, stripped)) { g_free (stripped); return; } @@ -436,22 +531,28 @@ format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name) guint length, i; GString *formated_string = g_string_new (NULL); + strip_string (value, '('); + strip_string (value, ')'); strip_string (value, '"'); - ipset = g_strsplit (value, "\" \"", 0); + ipset = g_strsplit (value, "\"", 0); length = g_strv_length (ipset); //only one line if (length < 2) { *out_line = - g_strdup_printf ("%s_%s=( \"%s\" )\n", key, name, value); + g_strdup_printf ("%s_%s=\"%s\"\n", key, name, value); goto done; } // Multiple lines - g_string_append_printf (formated_string, "%s_%s=(\n", key, name); + g_string_append_printf (formated_string, "%s_%s=\"\n", key, name); for (i = 0; i < length; i++) - g_string_append_printf (formated_string, - "\t\"%s\"\n", ipset[i]); - g_string_append (formated_string, ")\n"); + { + strip_string (ipset[i], ' '); + if (ipset[i][0] != '\0') + g_string_append_printf (formated_string, + "%s\n", ipset[i]); + } + g_string_append (formated_string, "\"\n"); *out_line = g_strdup (formated_string->str); done: g_string_free (formated_string, TRUE); @@ -466,7 +567,7 @@ ifnet_flush_to_file (const char *config_file) gpointer key, value, name, network; GHashTableIter iter, iter_network; GList *list_iter; - gchar *out_line; + gchar *out_line = NULL; gsize bytes_written; gboolean result = FALSE; @@ -475,6 +576,8 @@ ifnet_flush_to_file (const char *config_file) if (!conn_table || !global_settings_table) return FALSE; + backup_file (config_file); + channel = g_io_channel_new_file (config_file, "w", NULL); if (!channel) { PLUGIN_WARN (IFNET_PLUGIN_NAME, diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h index 0411e939..5dcc7e25 100644 --- a/src/settings/plugins/ifnet/net_parser.h +++ b/src/settings/plugins/ifnet/net_parser.h @@ -24,8 +24,8 @@ #include <glib.h> -#define CONF_NET_FILE "/etc/conf.d/net" -#define IFNET_SYSTEM_SETTINGS_KEY_FILE "/etc/NetworkManager/nm-system-settings.conf" +#define CONF_NET_FILE SYSCONFDIR "/conf.d/net" +#define IFNET_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf" #define IFNET_KEY_FILE_GROUP "ifnet" gboolean ifnet_init (gchar * config_file); diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index b533ae3f..f1687479 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -26,6 +26,7 @@ #include <errno.h> #include <nm-utils.h> #include <nm-system-config-interface.h> +#include <gio/gio.h> #include "net_utils.h" #include "wpa_parser.h" #include "net_parser.h" @@ -242,8 +243,7 @@ read_hostname (const char *path) if (g_str_has_prefix (all_lines[i], "hostname")) { tmp = strstr (all_lines[i], "="); tmp++; - tmp = strip_string (tmp, '"'); - result = g_strdup (tmp); + result = g_shell_unquote (tmp, NULL); break; } @@ -352,6 +352,49 @@ is_ip6_address (const char *in_address) } +// 'c' is only used for openrc style +static gchar ** +split_addresses_by_char (const gchar *addresses, const gchar *c) +{ + gchar **ipset; + + if (addresses == NULL) + return NULL; + + if (strchr (addresses, '(') != NULL) { // old baselayout style + gchar *tmp = g_strdup (addresses); + strip_string (tmp, '('); + strip_string (tmp, ')'); + strip_string (tmp, '"'); + strip_string (tmp, '\''); + ipset = g_strsplit (tmp, "\" \"", 0); + g_free(tmp); + } else { // openrc style + if (strstr (addresses, "netmask")) + // There is only one ip address if "netmask" is specified. + // '\n' is not used in config so there will be only one split. + ipset = g_strsplit (addresses, "\n", 0); + else + ipset = g_strsplit (addresses, c, 0); + } + + return ipset; +} + +static gchar ** +split_addresses (const gchar* addresses) +{ + // " " is only used by openrc style + return split_addresses_by_char (addresses, " "); +} + +static gchar ** +split_routes (const gchar* routes) +{ + // "\"" is only used by openrc style + return split_addresses_by_char (routes, "\""); +} + gboolean has_ip6_address (const char *conn_name) { @@ -360,7 +403,7 @@ has_ip6_address (const char *conn_name) guint i; g_return_val_if_fail (conn_name != NULL, FALSE); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { if (!is_ip6_address (ipset[i])) @@ -512,8 +555,11 @@ get_ip4_gateway (gchar * gateway) tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); + + // Only one gateway is selected if ((split = strstr (tmp, "\"")) != NULL) *split = '\0'; + if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) goto error; g_free (tmp); @@ -567,14 +613,11 @@ convert_ip4_config_block (const char *conn_name) gchar *ip; guint32 def_gateway = 0; const char *routes; - gchar *pos; ip_block *start = NULL, *current = NULL, *iblock = NULL; - const char *pattern = - "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))"; g_return_val_if_fail (conn_name != NULL, NULL); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); routes = ifnet_get_data (conn_name, "routes"); @@ -584,73 +627,16 @@ convert_ip4_config_block (const char *conn_name) for (i = 0; i < length; i++) { ip = ipset[i]; ip = strip_string (ip, '"'); - //Handle ip like 192.168.4.{1..3} - if ((pos = strchr (ip, '{')) != NULL) { - gchar *ip_start, *ip_prefix; - gchar *begin_str, *end_str; - int begin, end, j; - GRegex *regex; - GMatchInfo *match_info; - - regex = g_regex_new (pattern, 0, 0, NULL); - g_regex_match (regex, ip, 0, &match_info); - g_regex_unref (regex); - - if (!g_match_info_matches (match_info)) { - g_match_info_free (match_info); - continue; - } - begin_str = g_match_info_fetch (match_info, 3); - end_str = g_match_info_fetch (match_info, 4); - begin = atoi (begin_str); - end = atoi (end_str); - ip_start = g_match_info_fetch (match_info, 2); - ip_prefix = g_match_info_fetch (match_info, 5); - if (end < begin || begin < 1 || end > 254) { - g_match_info_free (match_info); - continue; - } - - for (j = begin; j <= end; j++) { - char suf[4]; - gchar *newip; - - sprintf (suf, "%d", j); - newip = - g_strconcat (ip_start, suf, ip_prefix, - NULL); - iblock = create_ip4_block (newip); - if (iblock == NULL) { - g_free (newip); - continue; - } - if (!iblock->gateway && def_gateway != 0) - iblock->gateway = def_gateway; - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - g_free (newip); - } - g_free (begin_str); - g_free (end_str); - g_free (ip_start); - g_free (ip_prefix); - g_match_info_free (match_info); - } else { - iblock = create_ip4_block (ip); - if (iblock == NULL) - continue; - if (!iblock->gateway && def_gateway != 0) - iblock->gateway = def_gateway; - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + if (!iblock->gateway && def_gateway != 0) + iblock->gateway = def_gateway; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; } } g_strfreev (ipset); @@ -667,7 +653,7 @@ convert_ip6_config_block (const char *conn_name) ip6_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; @@ -693,15 +679,11 @@ convert_ip4_routes_block (const char *conn_name) guint length; guint i; gchar *ip; - const char *routes; ip_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); - routes = ifnet_get_data (conn_name, "routes"); - if (!routes) - return NULL; - ipset = g_strsplit (routes, "\" \"", 0); + ipset = split_routes (ifnet_get_data (conn_name, "routes")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; @@ -731,15 +713,11 @@ convert_ip6_routes_block (const char *conn_name) guint length; guint i; gchar *ip, *tmp_addr; - const char *routes; ip6_block *start = NULL, *current = NULL, *iblock = NULL; struct in6_addr *tmp_ip6_addr; g_return_val_if_fail (conn_name != NULL, NULL); - routes = ifnet_get_data (conn_name, "routes"); - if (!routes) - return NULL; - ipset = g_strsplit (routes, "\" \"", 0); + ipset = split_routes (ifnet_get_data (conn_name, "routes")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; @@ -897,8 +875,8 @@ void get_dhcp_hostname_and_client_id (char **hostname, char **client_id) { const char *dhcp_client; - const gchar *dhcpcd_conf = "/etc/dhcpcd.conf"; - const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf"; + const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf"; + const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf"; gchar *line = NULL, *tmp = NULL, *contents = NULL; gchar **all_lines; guint line_num, i; @@ -972,3 +950,20 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) g_strfreev (all_lines); g_free (contents); } + +void backup_file (const gchar* target) +{ + GFile *source, *backup; + gchar* backup_path; + GError **error = NULL; + + source = g_file_new_for_path (target); + backup_path = g_strdup_printf ("%s.bak", target); + backup = g_file_new_for_path (backup_path); + + g_file_copy (source, backup, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error); + if (error && *error) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Backup failed: %s", (*error)->message); + + g_free (backup_path); +} diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h index 42f8d672..dee49143 100644 --- a/src/settings/plugins/ifnet/net_utils.h +++ b/src/settings/plugins/ifnet/net_utils.h @@ -77,4 +77,5 @@ gboolean is_true (const char *str); void get_dhcp_hostname_and_client_id (char **hostname, char **client_id); +void backup_file (const gchar* target); #endif diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index 59083688..fff83805 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -48,6 +48,7 @@ typedef struct { GHashTable *config_connections; gchar *hostname; + char *conf_file; gboolean unmanaged_well_known; GFileMonitor *hostname_monitor; @@ -180,7 +181,7 @@ monitor_file_changes (const char *filename, /* Callback for nm_settings_connection_replace_and_commit. Report any errors * encountered when commiting connection settings updates. */ static void -commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) +commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) { if (error) { PLUGIN_WARN (IFNET_PLUGIN_NAME, " error updating: %s", @@ -188,8 +189,7 @@ commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) } else { NMSettingConnection *s_con; - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), - NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_assert (s_con); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated", nm_setting_connection_get_id (s_con)); @@ -317,6 +317,26 @@ reload_connections (gpointer config) g_list_free (conn_names); } +static void +check_flagged_secrets (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + gboolean *is_system_secret = user_data; + + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) { + *is_system_secret = TRUE; + } + } +} + static NMSettingsConnection * add_connection (NMSystemConfigInterface *config, NMConnection *source, @@ -324,11 +344,28 @@ add_connection (NMSystemConfigInterface *config, { NMIfnetConnection *connection = NULL; char *conn_name; + gboolean has_flagged_secrets = FALSE; + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (source); + g_assert (s_con); + + /* If the connection is not available for all users, ignore + * it as this plugin only deals with System Connections */ + if (nm_setting_connection_get_num_permissions (s_con)) + return NULL; + + /* If the connection has flagged secrets, ignore + * it as this plugin does not deal with user agent service */ + nm_connection_for_each_setting_value (source, check_flagged_secrets, &has_flagged_secrets); + + if (!has_flagged_secrets) { + conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error); + if (conn_name) + connection = nm_ifnet_connection_new (conn_name, source); + reload_connections (config); + } - conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error); - if (conn_name) - connection = nm_ifnet_connection_new (conn_name, source); - reload_connections (config); return connection ? NM_SETTINGS_CONNECTION (connection) : NULL; } @@ -494,6 +531,7 @@ dispose (GObject * object) } g_free (priv->hostname); + g_free (priv->conf_file); ifnet_destroy (); wpa_parser_destroy (); G_OBJECT_CLASS (sc_plugin_ifnet_parent_class)->dispose (object); @@ -527,16 +565,37 @@ sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class) NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } +const char * +ifnet_plugin_get_conf_file (void) +{ + SCPluginIfnet *ifnet_plugin; + SCPluginIfnetPrivate *priv; + + /* Get config file name. Plugin's singleton has already been created + * with correct config file path, so the string passed here has no efect + * and we get the valid file name. + */ + ifnet_plugin = SC_PLUGIN_IFNET (nm_system_config_factory ("fake string")); + priv = SC_PLUGIN_IFNET_GET_PRIVATE (ifnet_plugin); + g_object_unref (ifnet_plugin); + + return priv->conf_file; +} + G_MODULE_EXPORT GObject * -nm_system_config_factory (void) +nm_system_config_factory (const char *config_file) { static SCPluginIfnet *singleton = NULL; + SCPluginIfnetPrivate *priv; - if (!singleton) - singleton - = - SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL)); - else + if (!singleton) { + singleton = SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL)); + if (singleton) { + priv = SC_PLUGIN_IFNET_GET_PRIVATE (singleton); + priv->conf_file = strdup (config_file); + } + } else g_object_ref (singleton); + return G_OBJECT (singleton); } diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h index 83099b63..eecab159 100644 --- a/src/settings/plugins/ifnet/plugin.h +++ b/src/settings/plugins/ifnet/plugin.h @@ -43,5 +43,7 @@ struct _SCPluginIfnetClass { GObjectClass parent; }; +const char * ifnet_plugin_get_conf_file (void); + GType sc_plugin_ifnet_get_type (void); #endif diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in index fe7f40e2..02ee121f 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.in +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -141,6 +141,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -195,11 +197,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -210,6 +216,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -249,6 +256,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net index 0eef399a..27d39f44 100644 --- a/src/settings/plugins/ifnet/tests/net +++ b/src/settings/plugins/ifnet/tests/net @@ -27,10 +27,9 @@ config_eth2=( routes_eth2=("default via 4321:0:1:2:3:4:567:89ab") enable_ipv6_eth2="true" config_eth3=("nufjlsjlll") -managed_eth4=("false") +managed_eth4="false" routes_eth4=("default via 4321:0:1:2:3:4:567:89ab") config_eth5=("dhcp") -config_eth6=("192.168.4.{1..101}/24") config_eth7=( "dhcp" ) auto_eth7="true" @@ -38,6 +37,14 @@ auto_eth7="true" # missing config_eth8 auto_eth8="true" +#new openrc style +config_eth9="202.117.16.10/24 202.117.17.10/24" +routes_eth9="default via 202.117.16.1 +10.0.0.0/8 via 192.168.0.1 +" +config_eth10="202.117.16.2 netmask 255.255.255.0" +routes_eth10="10.0.0.0/8 via 192.168.0.1" + config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") routes_myxjtu2=("default via 202.117.16.1") dns_servers_myxjtu2="202.117.0.20 202.117.0.21" diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index 52d9ce2a..50441d4e 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -33,11 +33,21 @@ #include "wpa_parser.h" #include "connection_parser.h" +/* Fake config file function to make the linker happy */ +const char *ifnet_plugin_get_conf_file (void); + +const char * +ifnet_plugin_get_conf_file (void) +{ + return "/etc/foo/barasdfasdfasdfasdf"; +} + + static void test_getdata () { ASSERT (ifnet_get_data ("eth1", "config") - && strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0, + && strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0, "get data", "config_eth1 is not correct"); ASSERT (ifnet_get_data ("ppp0", "username") && strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0, @@ -84,7 +94,7 @@ test_is_static () ASSERT (is_static_ip4 ("eth0") == TRUE, "is static", "a static interface is recognized as dhcp"); ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static", - "a static interface is recognized as dhcp"); + "a dhcp interface is recognized as static"); } static void @@ -182,10 +192,6 @@ test_convert_ipv4_config_block () ASSERT (iblock == NULL, "convert config_block", "convert error configuration"); destroy_ip_block (iblock); - iblock = convert_ip4_config_block ("eth6"); - ASSERT (iblock != NULL, "convert config_block", - "convert error configuration"); - destroy_ip_block (iblock); } static void @@ -200,6 +206,16 @@ test_convert_ipv4_routes_block () destroy_ip_block (tmp); ASSERT (iblock == NULL, "convert ip4 routes", "should only get one route"); + + iblock = convert_ip4_routes_block ("eth9"); + tmp = iblock; + + ASSERT (iblock != NULL, "convert ip4 routes", "should get one route"); + check_ip_block (iblock, "10.0.0.0", "255.0.0.0", "192.168.0.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + ASSERT (iblock == NULL, "convert ip4 routes", + "should only get one route"); } static void @@ -222,6 +238,9 @@ test_wpa_parser () "wep_key0 of static-wep-test should be abcde, find %s", value); ASSERT (exist_ssid ("leap-example"), "get wsec", "ssid leap-example is not found"); + + value = wpa_get_value ("test-with-hash-in-psk", "psk"); + g_assert_cmpstr (value, ==, "\"xjtudlc3731###asdfasdfasdf\""); } static void @@ -272,6 +291,18 @@ test_new_connection () "new connection failed: %s", error ? error->message : "NONE"); g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth9", &error); + ASSERT (connection != NULL, "new connection", + "new connection(eth9) failed: %s", + error ? error->message : "NONE"); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth10", &error); + ASSERT (connection != NULL, "new connection", + "new connection(eth10) failed: %s", + error ? error->message : "NONE"); + g_object_unref (connection); } #define NET_GEN_NAME "net.generate" diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf index 4f5f68cf..609ee0e1 100644 --- a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf +++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf @@ -863,3 +863,10 @@ network={ phase2="auth=CHAP" priority=20 } + +network={ + ssid="test-with-hash-in-psk" + key_mgmt=WPA-PSK + psk="xjtudlc3731###asdfasdfasdf" +} + diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c index da2bc3bb..0fd7d16b 100644 --- a/src/settings/plugins/ifnet/wpa_parser.c +++ b/src/settings/plugins/ifnet/wpa_parser.c @@ -124,7 +124,7 @@ add_key_value (GHashTable * network, gchar * line) g_strstrip (key_value[0]); g_strstrip (key_value[1]); - /* Reserve quotes for psk, wep_key, ssid + /* Reserve quotes for psk, wep_key, ssid * Quotes will determine whether they are hex format */ if (strcmp (key_value[0], "psk") != 0 && !g_str_has_prefix (key_value[0], "wep_key") @@ -162,7 +162,7 @@ add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key) } } -/* Reading wep security information from /etc/conf.d/net. +/* Reading wep security information from /etc/conf.d/net. * This should not be used in futre, use wpa_supplicant instead. */ static void add_keys_from_net () @@ -279,16 +279,21 @@ wpa_parser_init (const char *wpa_supplicant_conf) } else { GHashTable *network = g_hash_table_new (g_str_hash, g_str_equal); - gchar *tmp; do { + gchar *quote_start, *quote_end = NULL, *comment; + if (line[0] == '#' || line[0] == '\0') { g_free (line); continue; } - /* ignore inline comments */ - if ((tmp = strchr (line, '#')) != NULL) - *tmp = '\0'; + /* ignore inline comments unless inside + a double-quoted string */ + if ((quote_start = strchr (line, '"')) != NULL) + quote_end = strrchr (quote_start + 1, '"'); + if ((comment = strchr ((quote_end != NULL) ? + quote_end : line, '#')) != NULL) + *comment = '\0'; if (strstr (line, "}") != NULL) complete = TRUE; add_key_value (network, line); @@ -371,6 +376,8 @@ wpa_flush_to_file (const char *config_file) if (!wsec_table || !wsec_global_table) return FALSE; + backup_file (config_file); + channel = g_io_channel_new_file (config_file, "w", NULL); if (!channel) { PLUGIN_WARN (IFNET_PLUGIN_NAME, diff --git a/src/settings/plugins/ifnet/wpa_parser.h b/src/settings/plugins/ifnet/wpa_parser.h index 7fd77a05..3a0d377e 100644 --- a/src/settings/plugins/ifnet/wpa_parser.h +++ b/src/settings/plugins/ifnet/wpa_parser.h @@ -21,8 +21,11 @@ #ifndef _WPA_PARSER_H #define _WPA_PARSER_H -#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant/wpa_supplicant.conf" + #include <glib.h> + +#define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf" + void wpa_parser_init (const char *wpa_supplicant_conf); void wpa_parser_destroy (void); diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in index 98dded68..f5087648 100644 --- a/src/settings/plugins/ifupdown/Makefile.in +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -217,6 +217,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -271,11 +273,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -286,6 +292,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -325,6 +332,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c index b7c64242..38ed1479 100644 --- a/src/settings/plugins/ifupdown/interface_parser.c +++ b/src/settings/plugins/ifupdown/interface_parser.c @@ -294,6 +294,19 @@ const char *ifparser_getkey(if_block* iface, const char *key) return NULL; } +gboolean +ifparser_haskey(if_block* iface, const char *key) +{ + if_data *curr = iface->info; + + while (curr != NULL) { + if (strcmp (curr->key, key) == 0) + return TRUE; + curr = curr->next; + } + return FALSE; +} + int ifparser_get_num_info(if_block* iface) { int i = 0; diff --git a/src/settings/plugins/ifupdown/interface_parser.h b/src/settings/plugins/ifupdown/interface_parser.h index 0c1de23a..e68abcf6 100644 --- a/src/settings/plugins/ifupdown/interface_parser.h +++ b/src/settings/plugins/ifupdown/interface_parser.h @@ -24,6 +24,8 @@ #ifndef _INTERFACE_PARSER_H #define _INTERFACE_PARSER_H +#include <glib.h> + typedef struct _if_data { char *key; @@ -45,6 +47,7 @@ void ifparser_destroy(void); if_block *ifparser_getif(const char* iface); if_block *ifparser_getfirst(void); const char *ifparser_getkey(if_block* iface, const char *key); +gboolean ifparser_haskey(if_block* iface, const char *key); int ifparser_get_num_blocks(void); int ifparser_get_num_info(if_block* iface); diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c index dc2f8abf..6927f43f 100644 --- a/src/settings/plugins/ifupdown/parser.c +++ b/src/settings/plugins/ifupdown/parser.c @@ -25,6 +25,7 @@ #include <arpa/inet.h> #include <stdlib.h> #include <errno.h> +#include <ctype.h> #include <nm-connection.h> #include <NetworkManager.h> @@ -311,8 +312,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection, return; } - s_wireless = NM_SETTING_WIRELESS(nm_connection_get_setting(connection, - NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless(connection); g_return_if_fail(s_wireless); PLUGIN_PRINT ("SCPlugin-Ifupdown","update wireless security settings (%s).", block->name); @@ -433,96 +433,263 @@ eni_plugin_error_quark() { return error_quark; } - static void +ifupdown_ip4_add_dns (NMSettingIP4Config *s_ip4, const char *dns) +{ + struct in_addr addr; + char **list, **iter; + + if (dns == NULL) + return; + + list = g_strsplit_set (dns, " \t", -1); + for (iter = list; iter && *iter; iter++) { + g_strstrip (*iter); + if (isblank (*iter[0])) + continue; + if (!inet_pton (AF_INET, *iter, &addr)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: ignoring invalid nameserver '%s'", *iter); + continue; + } + + if (!nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: duplicate DNS domain '%s'", *iter); + } + } + g_strfreev (list); +} + +static gboolean update_ip4_setting_from_if_block(NMConnection *connection, - if_block *block) + if_block *block, + GError **error) { - NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new()); + NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new()); const char *type = ifparser_getkey(block, "inet"); gboolean is_static = type && !strcmp("static", type); - if(!is_static) { - g_object_set(ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + if (!is_static) { + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); } else { - struct in_addr tmp_ip4_addr; - NMIP4Address *ip4_addr = nm_ip4_address_new (); - - const char *address_v = ifparser_getkey(block, "address"); - const char *netmask_v = ifparser_getkey(block, "netmask"); - const char *gateway_v = ifparser_getkey(block, "gateway"); - const char *nameserver_v = ifparser_getkey(block, "dns-nameserver"); - const char *nameservers_v = ifparser_getkey(block, "dns-nameservers"); - GSList* nameservers_list = NULL; - GSList* nameservers_list_i = NULL; - GError *error = NULL; - - if(nameservers_v) - nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v); - if(nameserver_v) - nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v)); - - if (!address_v) - address_v = g_strdup ("0.0.0.0"); - - if (inet_pton (AF_INET, address_v, &tmp_ip4_addr)) - nm_ip4_address_set_address (ip4_addr, tmp_ip4_addr.s_addr); - else - g_set_error (&error, eni_plugin_error_quark (), 0, - "Invalid %s IP4 address '%s'", "address", address_v); - if (!netmask_v) - netmask_v = g_strdup( "255.255.255.255"); - - if (inet_pton (AF_INET, netmask_v, &tmp_ip4_addr)) - nm_ip4_address_set_prefix (ip4_addr, nm_utils_ip4_netmask_to_prefix(tmp_ip4_addr.s_addr)); - else - g_set_error (&error, eni_plugin_error_quark (), 0, - "Invalid %s IP4 address '%s'", "netmask", netmask_v); + struct in_addr tmp_addr, tmp_mask, tmp_gw; + NMIP4Address *addr; + const char *address_v; + const char *netmask_v; + const char *gateway_v; + const char *nameserver_v; + const char *nameservers_v; + const char *search_v; + char **list, **iter; + guint32 netmask_int = 32; + + /* Address */ + address_v = ifparser_getkey (block, "address"); + if (!address_v || !inet_pton (AF_INET, address_v, &tmp_addr)) { + g_set_error (error, eni_plugin_error_quark (), 0, + "Missing IPv4 address '%s'", + address_v ? address_v : "(none)"); + goto error; + } + /* mask/prefix */ + netmask_v = ifparser_getkey (block, "netmask"); + if (netmask_v) { + if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) { + g_set_error (error, eni_plugin_error_quark (), 0, + "Invalid IPv4 netmask '%s'", netmask_v); + goto error; + } + netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask.s_addr); + } + + /* gateway */ + gateway_v = ifparser_getkey (block, "gateway"); if (!gateway_v) - gateway_v = g_strdup (address_v); + gateway_v = address_v; /* dcbw: whaaa?? */ + if (!inet_pton (AF_INET, gateway_v, &tmp_gw)) { + g_set_error (error, eni_plugin_error_quark (), 0, + "Invalid IPv4 gateway '%s'", gateway_v); + goto error; + } - if (inet_pton (AF_INET, gateway_v, &tmp_ip4_addr)) - nm_ip4_address_set_gateway (ip4_addr, tmp_ip4_addr.s_addr); - else - g_set_error (&error, eni_plugin_error_quark (), 0, - "Invalid %s IP4 address '%s'", "gateway", gateway_v); + /* Add the new address to the setting */ + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, tmp_addr.s_addr); + nm_ip4_address_set_prefix (addr, netmask_int); + nm_ip4_address_set_gateway (addr, tmp_gw.s_addr); - if (nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) { + if (nm_setting_ip4_config_add_address (s_ip4, addr)) { PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d", - nm_setting_ip4_config_get_num_addresses (ip4_setting)); + nm_setting_ip4_config_get_num_addresses (s_ip4)); } else { PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP4 address"); } - while(nameservers_list_i) { - gchar *dns = nameservers_list_i->data; - nameservers_list_i = nameservers_list_i -> next; - if(!dns) - continue; - if (inet_pton (AF_INET, dns, &tmp_ip4_addr)) { - if (!nm_setting_ip4_config_add_dns (ip4_setting, tmp_ip4_addr.s_addr)) - PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns); - } else - g_set_error (&error, eni_plugin_error_quark (), 0, - "Invalid %s IP4 address nameserver '%s'", "nameserver", dns); + nameserver_v = ifparser_getkey (block, "dns-nameserver"); + ifupdown_ip4_add_dns (s_ip4, nameserver_v); + + nameservers_v = ifparser_getkey (block, "dns-nameservers"); + ifupdown_ip4_add_dns (s_ip4, nameservers_v); + + if (!nm_setting_ip4_config_get_num_dns (s_ip4)) + PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces"); + + /* DNS searches */ + search_v = ifparser_getkey (block, "dns-search"); + if (search_v) { + list = g_strsplit_set (search_v, " \t", -1); + for (iter = list; iter && *iter; iter++) { + g_strstrip (*iter); + if (isblank (*iter[0])) + continue; + if (!nm_setting_ip4_config_add_dns_search (s_ip4, *iter)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: duplicate DNS domain '%s'", *iter); + } + } + g_strfreev (list); } - if (!nm_setting_ip4_config_get_num_dns (ip4_setting)) + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + } + + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + return TRUE; + +error: + g_object_unref (s_ip4); + return FALSE; +} + +static void +ifupdown_ip6_add_dns (NMSettingIP6Config *s_ip6, const char *dns) +{ + struct in6_addr addr; + char **list, **iter; + + if (dns == NULL) + return; + + list = g_strsplit_set (dns, " \t", -1); + for (iter = list; iter && *iter; iter++) { + g_strstrip (*iter); + if (isblank (*iter[0])) + continue; + if (!inet_pton (AF_INET6, *iter, &addr)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: ignoring invalid nameserver '%s'", *iter); + continue; + } + + if (!nm_setting_ip6_config_add_dns (s_ip6, &addr)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: duplicate DNS domain '%s'", *iter); + } + } + g_strfreev (list); +} + +static gboolean +update_ip6_setting_from_if_block(NMConnection *connection, + if_block *block, + GError **error) +{ + NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new()); + const char *type = ifparser_getkey(block, "inet6"); + gboolean is_static = type && (!strcmp("static", type) || + !strcmp("v4tunnel", type)); + + if (!is_static) { + g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + } else { + struct in6_addr tmp_addr, tmp_gw; + NMIP6Address *addr; + const char *address_v; + const char *prefix_v; + const char *gateway_v; + const char *nameserver_v; + const char *nameservers_v; + const char *search_v; + int prefix_int = 128; + char **list, **iter; + + /* Address */ + address_v = ifparser_getkey(block, "address"); + if (!address_v || !inet_pton (AF_INET6, address_v, &tmp_addr)) { + g_set_error (error, eni_plugin_error_quark (), 0, + "Missing IPv6 address '%s'", + address_v ? address_v : "(none)"); + goto error; + } + + /* Prefix */ + prefix_v = ifparser_getkey(block, "netmask"); + if (prefix_v) + prefix_int = g_ascii_strtoll (prefix_v, NULL, 10); + + /* Gateway */ + gateway_v = ifparser_getkey (block, "gateway"); + if (!gateway_v) + gateway_v = address_v; /* dcbw: whaaa?? */ + if (!inet_pton (AF_INET6, gateway_v, &tmp_gw)) { + g_set_error (error, eni_plugin_error_quark (), 0, + "Invalid IPv6 gateway '%s'", gateway_v); + goto error; + } + + /* Add the new address to the setting */ + addr = nm_ip6_address_new (); + nm_ip6_address_set_address (addr, &tmp_addr); + nm_ip6_address_set_prefix (addr, prefix_int); + nm_ip6_address_set_gateway (addr, &tmp_gw); + + if (nm_setting_ip6_config_add_address (s_ip6, addr)) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d", + nm_setting_ip6_config_get_num_addresses (s_ip6)); + } else { + PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP6 address"); + } + + nameserver_v = ifparser_getkey(block, "dns-nameserver"); + ifupdown_ip6_add_dns (s_ip6, nameserver_v); + + nameservers_v = ifparser_getkey(block, "dns-nameservers"); + ifupdown_ip6_add_dns (s_ip6, nameservers_v); + + if (!nm_setting_ip6_config_get_num_dns (s_ip6)) PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces"); - g_object_set(ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NULL); + /* DNS searches */ + search_v = ifparser_getkey (block, "dns-search"); + if (search_v) { + list = g_strsplit_set (search_v, " \t", -1); + for (iter = list; iter && *iter; iter++) { + g_strstrip (*iter); + if (isblank (*iter[0])) + continue; + if (!nm_setting_ip6_config_add_dns_search (s_ip6, *iter)) { + PLUGIN_WARN ("SCPlugin-Ifupdown", + " warning: duplicate DNS domain '%s'", *iter); + } + } + g_strfreev (list); + } - g_slist_foreach (nameservers_list, (GFunc) g_free, NULL); - g_slist_free (nameservers_list); + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL); } - nm_connection_add_setting(connection, NM_SETTING(ip4_setting)); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + return TRUE; + +error: + g_object_unref (s_ip6); + return FALSE; } gboolean @@ -537,7 +704,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, NMSettingConnection *s_con; gboolean success = FALSE; - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if(!s_con) { s_con = NM_SETTING_CONNECTION (nm_setting_connection_new()); g_assert (s_con); @@ -562,15 +729,19 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, block->name, type, idstr, nm_setting_connection_get_uuid (s_con)); if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type)) - update_wired_setting_from_if_block (connection, block); + update_wired_setting_from_if_block (connection, block); else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { update_wireless_setting_from_if_block (connection, block); update_wireless_security_setting_from_if_block (connection, block); } - update_ip4_setting_from_if_block (connection, block); + if (ifparser_haskey(block, "inet6")) + success = update_ip6_setting_from_if_block (connection, block, error); + else + success = update_ip4_setting_from_if_block (connection, block, error); - success = nm_connection_verify (connection, error); + if (success == TRUE) + success = nm_connection_verify (connection, error); g_free (idstr); return success; diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c index 9679edea..4dbb0aa2 100644 --- a/src/settings/plugins/ifupdown/plugin.c +++ b/src/settings/plugins/ifupdown/plugin.c @@ -19,7 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007,2008 Canonical Ltd. - * (C) Copyright 2009 Red Hat, Inc. + * (C) Copyright 2009 - 2011 Red Hat, Inc. */ #include <string.h> @@ -42,6 +42,7 @@ #include "nm-setting-wireless.h" #include "nm-setting-wired.h" #include "nm-setting-ppp.h" +#include "nm-utils.h" #include "nm-ifupdown-connection.h" #include "plugin.h" @@ -60,9 +61,6 @@ #define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list." #define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname" -#define IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf" -#define IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf" - #define IFUPDOWN_KEY_FILE_GROUP "ifupdown" #define IFUPDOWN_KEY_FILE_KEY_MANAGED "managed" #define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE @@ -81,7 +79,7 @@ typedef struct { GHashTable *well_known_interfaces; GHashTable *well_known_ifaces; gboolean unmanage_well_known; - const char *conf_file; + char *conf_file; gulong inotify_event_id; int inotify_system_hostname_wd; @@ -190,10 +188,9 @@ bind_device_to_connection (SCPluginIfupdown *self, NMIfupdownConnection *exported) { GByteArray *mac_address; - NMSetting *s_wired = NULL; - NMSetting *s_wifi = NULL; + NMSettingWired *s_wired; + NMSettingWireless *s_wifi; const char *iface, *address; - struct ether_addr *tmp_mac; iface = g_udev_device_get_name (device); if (!iface) { @@ -207,18 +204,15 @@ bind_device_to_connection (SCPluginIfupdown *self, return; } - tmp_mac = ether_aton (address); - if (!tmp_mac) { + mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER); + if (!mac_address) { PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", address, iface); return; } - mac_address = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN); - - s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED); - s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS); + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (exported)); + s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (exported)); if (s_wired) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); @@ -432,13 +426,13 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) keys = g_hash_table_get_keys (priv->iface_connections); for (iter = keys; iter; iter = g_list_next (iter)) { NMIfupdownConnection *exported; - NMSetting *setting; + NMSettingConnection *setting; if (!g_hash_table_lookup (auto_ifaces, iter->data)) continue; exported = g_hash_table_lookup (priv->iface_connections, iter->data); - setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); + setting = nm_connection_get_setting_connection (NM_CONNECTION (exported)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); @@ -448,12 +442,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) g_list_free (keys); g_hash_table_destroy (auto_ifaces); - /* Find the config file */ - if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS)) - priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE; - else - priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE; - + /* Read the config file to find out whether to manage interfaces */ keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, priv->conf_file, @@ -706,20 +695,28 @@ GObject__dispose (GObject *object) if (priv->well_known_interfaces) g_hash_table_destroy(priv->well_known_interfaces); + g_free (priv->conf_file); + if (priv->client) g_object_unref (priv->client); + G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object); } G_MODULE_EXPORT GObject * -nm_system_config_factory (void) +nm_system_config_factory (const char *config_file) { static SCPluginIfupdown *singleton = NULL; + SCPluginIfupdownPrivate *priv; - if (!singleton) + if (!singleton) { singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL)); - else + if (singleton) { + priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (singleton); + priv->conf_file = strdup (config_file); + } + } else g_object_ref (singleton); return G_OBJECT (singleton); diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am index aed86197..ff219d5d 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.am +++ b/src/settings/plugins/ifupdown/tests/Makefile.am @@ -29,4 +29,4 @@ endif EXTRA_DIST = \ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ - test13 test14 test15 test16 + test13 test14 test15 test16 test17-wired-static-verify-ip4 diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in index aca48837..a03be1bd 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.in +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -141,6 +141,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -195,11 +197,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -210,6 +216,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -249,6 +256,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -334,7 +343,7 @@ test_ifupdown_LDADD = \ EXTRA_DIST = \ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ - test13 test14 test15 test16 + test13 test14 test15 test16 test17-wired-static-verify-ip4 all: all-am diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index 16465364..01020bdf 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -21,6 +21,9 @@ #include <glib.h> #include <string.h> +#include <nm-utils.h> + +#include "nm-test-helpers.h" #include "interface_parser.h" #include "parser.h" @@ -455,6 +458,386 @@ test16_missing_newline (const char *path) ifparser_destroy (); expected_free (e); } +static void +test17_read_static_ipv4 (const char *path) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingWired *s_wired; + char *unmanaged = NULL; + GError *error = NULL; + const char* tmp; + const char *expected_address = "10.0.0.3"; + const char *expected_id = "Ifupdown (eth0)"; + const char *expected_dns1 = "10.0.0.1"; + const char *expected_dns2 = "10.0.0.2"; + const char *expected_search1 = "example.com"; + const char *expected_search2 = "foo.example.com"; + guint32 expected_prefix = 8; + NMIP4Address *ip4_addr; + struct in_addr addr; +#define TEST17_NAME "wired-static-verify-ip4" + if_block *block = NULL; + + const char* file = "test17-" TEST17_NAME; + + init_ifparser_with_file (path, file); + block = ifparser_getfirst (); + connection = nm_connection_new(); + ifupdown_update_connection_from_if_block(connection, block, &error); + + ASSERT (connection != NULL, + TEST17_NAME, "failed to read %s: %s", file, error->message); + + ASSERT (nm_connection_verify (connection, &error), + TEST17_NAME, "failed to verify %s: %s", file, error->message); + + ASSERT (unmanaged == NULL, + TEST17_NAME, "failed to verify %s: unexpected unmanaged value", file); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection (connection); + ASSERT (s_con != NULL, + TEST17_NAME, "failed to verify %s: missing %s setting", + file, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + TEST17_NAME, "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value: %s", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID, tmp); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired (connection); + ASSERT (s_wired != NULL, + TEST17_NAME, "failed to verify %s: missing %s setting", + file, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0, + TEST17_NAME, "failed to verify %s: couldn't convert IP address #1", + file); + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + ASSERT (s_ip4 != NULL, + TEST17_NAME, "failed to verify %s: missing %s setting", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* IP addresses */ + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + TEST17_NAME, "failed to verify %s: missing IP4 address #1", + file); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, + TEST17_NAME, "failed to verify %s: unexpected IP4 address prefix", + file); + + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + TEST17_NAME, "failed to verify %s: unexpected IP4 address: %s", + file, addr.s_addr); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #2", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #2", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* DNS search domains */ + ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 2, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0); + ASSERT (tmp != NULL, + TEST17_NAME, "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + ASSERT (strcmp (tmp, expected_search1) == 0, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1); + ASSERT (tmp != NULL, + TEST17_NAME, "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + ASSERT (strcmp (tmp, expected_search2) == 0, + TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + g_object_unref (connection); +} + +static void +test18_read_static_ipv6 (const char *path) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP6Config *s_ip6; + NMSettingWired *s_wired; + char *unmanaged = NULL; + GError *error = NULL; + const char* tmp; + const char *expected_address = "fc00::1"; + const char *expected_id = "Ifupdown (myip6tunnel)"; + const char *expected_dns1 = "fc00::2"; + const char *expected_dns2 = "fc00::3"; + const char *expected_search1 = "example.com"; + const char *expected_search2 = "foo.example.com"; + guint32 expected_prefix = 64; + NMIP6Address *ip6_addr; + struct in6_addr addr; + if_block *block = NULL; +#define TEST18_NAME "wired-static-verify-ip6" + const char* file = "test18-" TEST18_NAME; + + init_ifparser_with_file (path, file); + block = ifparser_getfirst (); + connection = nm_connection_new(); + ifupdown_update_connection_from_if_block(connection, block, &error); + + ASSERT (connection != NULL, + TEST18_NAME + "failed to read %s: %s", file, error->message); + + ASSERT (nm_connection_verify (connection, &error), + TEST18_NAME, + "failed to verify %s: %s", file, error->message); + + ASSERT (unmanaged == NULL, + TEST18_NAME, + "failed to verify %s: unexpected unmanaged value", file); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection (connection); + ASSERT (s_con != NULL, + TEST18_NAME, "failed to verify %s: missing %s setting", + file, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + TEST18_NAME, + "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + ASSERT (strcmp (tmp, expected_id) == 0, + TEST18_NAME, + "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired (connection); + ASSERT (s_wired != NULL, + TEST18_NAME, "failed to verify %s: missing %s setting", + file, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv6 SETTING ===== */ + + ASSERT (inet_pton (AF_INET6, expected_address, &addr) > 0, + TEST18_NAME, + "failed to verify %s: couldn't convert IP address #1", + file); + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + ASSERT (s_ip6 != NULL, + TEST18_NAME, + "failed to verify %s: missing %s setting", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + TEST18_NAME, + "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + /* IP addresses */ + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1, + TEST18_NAME, + "failed to verify %s: unexpected number of %s / %s", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + TEST18_NAME, + "failed to verify %s: missing %s / %s #1", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix, + TEST18_NAME + "failed to verify %s: unexpected %s / %s prefix", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), + &addr), + TEST18_NAME, + "failed to verify %s: unexpected %s / %s", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* DNS Addresses */ + ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + TEST18_NAME, + "failed to verify %s: unexpected number of %s / %s values", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, + TEST18_NAME, + "failed to verify %s: couldn't convert DNS IP address #1", + file); + + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), + &addr), + TEST18_NAME, + "failed to verify %s: unexpected %s / %s #1", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0, + TEST18_NAME, + "failed to verify %s: couldn't convert DNS IP address #2", + file); + + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), + &addr), + TEST18_NAME, "failed to verify %s: unexpected %s / %s #2", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + /* DNS search domains */ + ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 2, + TEST18_NAME, + "failed to verify %s: unexpected number of %s / %s values", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 0); + ASSERT (tmp != NULL, + "wired-ipv6-manual-verify-ip6", + "failed to verify %s: missing %s / %s #1", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + ASSERT (strcmp (tmp, expected_search1) == 0, + "wired-ipv6-manual-verify-ip6", + "failed to verify %s: unexpected %s / %s #1", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 1); + ASSERT (tmp != NULL, + TEST18_NAME, + "failed to verify %s: missing %s / %s #2", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + ASSERT (strcmp (tmp, expected_search2) == 0, + TEST18_NAME, + "failed to verify %s: unexpected %s / %s #2", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + g_free (unmanaged); + g_object_unref (connection); +} + #if GLIB_CHECK_VERSION(2,25,12) typedef GTestFixtureFunc TCFunc; @@ -467,6 +850,12 @@ typedef void (*TCFunc)(void); int main (int argc, char **argv) { GTestSuite *suite; + GError *error = NULL; + + g_type_init (); + + if (!nm_utils_init (&error)) + FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); g_test_init (&argc, &argv, NULL); @@ -490,6 +879,8 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test14_mixed_whitespace_block_start, TEST_ENI_DIR)); g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR)); g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test17_read_static_ipv4, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test18_read_static_ipv6, TEST_ENI_DIR)); return g_test_run (); } diff --git a/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4 b/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4 new file mode 100644 index 00000000..9e5243a7 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4 @@ -0,0 +1,5 @@ +iface eth0 inet static + address 10.0.0.3 + netmask 255.0.0.0 + dns-search example.com foo.example.com + dns-nameservers 10.0.0.1 10.0.0.2 diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am index 3b242142..83031c24 100644 --- a/src/settings/plugins/keyfile/Makefile.am +++ b/src/settings/plugins/keyfile/Makefile.am @@ -3,7 +3,9 @@ SUBDIRS=. tests INCLUDES = \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-util + -I$(top_builddir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util noinst_LTLIBRARIES = \ libkeyfile-io.la \ diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index ae0c9f8e..c766e794 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -193,6 +193,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -247,11 +249,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -262,6 +268,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -301,6 +308,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -368,7 +377,9 @@ SUBDIRS = . tests INCLUDES = \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-util + -I$(top_builddir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util noinst_LTLIBRARIES = \ libkeyfile-io.la \ diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index af69c200..d53907a9 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -42,9 +42,6 @@ #include "common.h" #include "utils.h" -#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf" -#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf" - static char *plugin_get_hostname (SCPluginKeyfile *plugin); static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); @@ -60,7 +57,7 @@ typedef struct { GFileMonitor *monitor; guint monitor_id; - const char *conf_file; + char *conf_file; GFileMonitor *conf_file_monitor; guint conf_file_monitor_id; @@ -354,13 +351,15 @@ setup_monitoring (NMSystemConfigInterface *config) priv->monitor = monitor; } - file = g_file_new_for_path (priv->conf_file); - monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); - g_object_unref (file); + if (priv->conf_file) { + file = g_file_new_for_path (priv->conf_file); + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); - if (monitor) { - priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config); - priv->conf_file_monitor = monitor; + if (monitor) { + priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config); + priv->conf_file_monitor = monitor; + } } } @@ -410,6 +409,9 @@ get_unmanaged_specs (NMSystemConfigInterface *config) GSList *specs = NULL; GError *error = NULL; + if (!priv->conf_file) + return NULL; + key_file = g_key_file_new (); if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { char *str; @@ -460,6 +462,9 @@ plugin_get_hostname (SCPluginKeyfile *plugin) char *hostname = NULL; GError *error = NULL; + if (!priv->conf_file) + return NULL; + key_file = g_key_file_new (); if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL); @@ -481,6 +486,11 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) GError *error = NULL; gboolean result = FALSE; + if (!priv->conf_file) { + g_warning ("Error saving hostname: no config file"); + return FALSE; + } + key_file = g_key_file_new (); if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { char *data; @@ -517,14 +527,6 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) static void sc_plugin_keyfile_init (SCPluginKeyfile *plugin) { - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); - - if (g_file_test (CONF_FILE, G_FILE_TEST_EXISTS)) - priv->conf_file = CONF_FILE; - else - priv->conf_file = OLD_CONF_FILE; - - priv->hostname = plugin_get_hostname (plugin); } static void @@ -597,6 +599,7 @@ dispose (GObject *object) } g_free (priv->hostname); + g_free (priv->conf_file); if (priv->hash) g_hash_table_destroy (priv->hash); @@ -642,13 +645,22 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c } GObject * -nm_settings_keyfile_plugin_new (void) +nm_settings_keyfile_plugin_new (const char *config_file) { static SCPluginKeyfile *singleton = NULL; + SCPluginKeyfilePrivate *priv; - if (!singleton) + if (!singleton) { singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL)); - else + if (singleton) { + priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton); + + priv->conf_file = g_strdup (config_file); + + /* plugin_set_hostname() has to be called *after* priv->conf_file is set */ + priv->hostname = plugin_get_hostname (singleton); + } + } else g_object_ref (singleton); return G_OBJECT (singleton); diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h index af5147ef..05d4e2b0 100644 --- a/src/settings/plugins/keyfile/plugin.h +++ b/src/settings/plugins/keyfile/plugin.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #ifndef _PLUGIN_H_ @@ -43,6 +43,6 @@ GType sc_plugin_keyfile_get_type (void); GQuark keyfile_plugin_error_quark (void); -GObject *nm_settings_keyfile_plugin_new (void); +GObject *nm_settings_keyfile_plugin_new (const char *config_file); #endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 4128b9f2..c7889cfc 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -34,8 +34,10 @@ #include <nm-setting-wireless.h> #include <nm-setting-bluetooth.h> #include <nm-setting-8021x.h> +#include <nm-utils.h> #include <arpa/inet.h> #include <netinet/ether.h> +#include <linux/if_infiniband.h> #include <string.h> #include <ctype.h> @@ -650,12 +652,11 @@ static void mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - struct ether_addr *eth; char *tmp_string = NULL, *p; gint *tmp_list; GByteArray *array = NULL; gsize length; - int i; + int i, type; p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); if (tmp_string) { @@ -666,43 +667,45 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons i++; p++; } - if (i == 5) { - /* parse as a MAC address */ - eth = ether_aton (tmp_string); - if (eth) { - g_free (tmp_string); - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN); - goto done; - } - } + + /* If we found enough it's probably a string-format MAC address */ + type = nm_utils_hwaddr_type (i + 1); + if (type > 0) + array = nm_utils_hwaddr_atoba (tmp_string, type); } g_free (tmp_string); - /* Old format; list of ints */ - tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); - array = g_byte_array_sized_new (length); - for (i = 0; i < length; i++) { - int val = tmp_list[i]; - unsigned char v = (unsigned char) (val & 0xFF); - - if (val < 0 || val > 255) { - g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); - } else - g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); + if (array == NULL) { + /* Old format; list of ints */ + tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); + type = nm_utils_hwaddr_type (length); + if (type < 0) { + array = g_byte_array_sized_new (length); + for (i = 0; i < length; i++) { + int val = tmp_list[i]; + const guint8 v = (guint8) (val & 0xFF); + + if (val < 0 || val > 255) { + g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); + g_byte_array_free (array, TRUE); + array = NULL; + break; + } + g_byte_array_append (array, &v, 1); + } + } + g_free (tmp_list); } - g_free (tmp_list); -done: - if (array->len == ETH_ALEN) { + if (array) { g_object_set (setting, key, array, NULL); + g_byte_array_free (array, TRUE); } else { g_warning ("%s: ignoring invalid MAC address for %s / %s", __func__, setting_name, key); } - g_byte_array_free (array, TRUE); } static void @@ -825,6 +828,22 @@ ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char } } +static void +password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + GByteArray *array; + + array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE); + if (array) { + g_object_set (setting, key, array, NULL); + g_byte_array_free (array, TRUE); + } else { + g_warning ("%s: ignoring invalid raw password for %s / %s", + __func__, setting_name, key); + } +} + static char * get_cert_path (const char *keyfile_path, GByteArray *cert_path) { @@ -1019,11 +1038,19 @@ static KeyParser key_parsers[] = { NM_SETTING_BLUETOOTH_BDADDR, TRUE, mac_address_parser }, + { NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS, + TRUE, + mac_address_parser }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, TRUE, ssid_parser }, { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD_RAW, + TRUE, + password_raw_parser }, + { NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CA_CERT, TRUE, cert_parser }, @@ -1300,7 +1327,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) * the keyfile didn't include it, which can happen when the base * device type setting is all default values (like ethernet). */ - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); if (s_con) { ctype = nm_setting_connection_get_connection_type (s_con); setting = nm_connection_get_setting_by_name (connection, ctype); @@ -1314,7 +1341,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (vpn_secrets) { NMSettingVPN *s_vpn; - s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + s_vpn = nm_connection_get_setting_vpn (connection); if (s_vpn) read_vpn_secrets (key_file, s_vpn); } diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am index affe8dca..2adbf873 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.am +++ b/src/settings/plugins/keyfile/tests/Makefile.am @@ -2,7 +2,9 @@ SUBDIRS=keyfiles INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ -I$(srcdir)/../ diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index c1fc662d..ff08e529 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -179,6 +179,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -233,11 +235,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -248,6 +254,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -287,6 +294,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -353,7 +362,9 @@ top_srcdir = @top_srcdir@ SUBDIRS = keyfiles INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ -I$(srcdir)/../ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am index 55dda7ee..f163312e 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am @@ -13,7 +13,8 @@ KEYFILES = \ Test_Wired_TLS_Old \ Test_Wired_TLS_New \ Test_Wired_TLS_Blob \ - Test_Wired_TLS_Path_Missing + Test_Wired_TLS_Path_Missing \ + Test_InfiniBand_Connection CERTS = \ test-ca-cert.pem \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index 0ea23ebc..cf5b868f 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -107,6 +107,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -161,11 +163,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -176,6 +182,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -215,6 +222,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -293,7 +302,8 @@ KEYFILES = \ Test_Wired_TLS_Old \ Test_Wired_TLS_New \ Test_Wired_TLS_Blob \ - Test_Wired_TLS_Path_Missing + Test_Wired_TLS_Path_Missing \ + Test_InfiniBand_Connection CERTS = \ test-ca-cert.pem \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection new file mode 100644 index 00000000..3a984b77 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection @@ -0,0 +1,13 @@ +[connection] +id=Test InfiniBand Connection +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=infiniband + +[infiniband] +mac-address=00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90 +transport-mode=datagram +mtu=1400 + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index 2859cb3e..79fa2f9c 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -26,6 +26,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> +#include <linux/if_infiniband.h> #include <nm-utils.h> #include <nm-setting-connection.h> @@ -38,6 +39,7 @@ #include <nm-setting-ppp.h> #include <nm-setting-gsm.h> #include <nm-setting-8021x.h> +#include <nm-setting-infiniband.h> #include "nm-test-helpers.h" @@ -93,7 +95,7 @@ test_read_valid_wired_connection (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_WIRED_FILE, @@ -142,7 +144,7 @@ test_read_valid_wired_connection (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "connection-verify-wired", "failed to verify %s: missing %s setting", TEST_WIRED_FILE, @@ -174,7 +176,7 @@ test_read_valid_wired_connection (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "connection-verify-ip4", "failed to verify %s: missing %s setting", TEST_WIRED_FILE, @@ -297,7 +299,7 @@ test_read_valid_wired_connection (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "connection-verify-ip6", "failed to verify %s: missing %s setting", TEST_WIRED_FILE, @@ -745,7 +747,7 @@ test_read_ip6_wired_connection (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_WIRED_IP6_FILE, @@ -779,7 +781,7 @@ test_read_ip6_wired_connection (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "connection-verify-wired", "failed to verify %s: missing %s setting", TEST_WIRED_IP6_FILE, @@ -787,7 +789,7 @@ test_read_ip6_wired_connection (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "connection-verify-ip4", "failed to verify %s: missing %s setting", TEST_WIRED_IP6_FILE, @@ -809,7 +811,7 @@ test_read_ip6_wired_connection (void) /* ===== IPv6 SETTING ===== */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, "connection-verify-ip6", "failed to verify %s: missing %s setting", TEST_WIRED_IP6_FILE, @@ -1001,7 +1003,7 @@ test_read_wired_mac_case (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_WIRED_MAC_CASE_FILE, @@ -1035,7 +1037,7 @@ test_read_wired_mac_case (void) /* ===== WIRED SETTING ===== */ - s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + s_wired = nm_connection_get_setting_wired (connection); ASSERT (s_wired != NULL, "connection-verify-wired", "failed to verify %s: missing %s setting", TEST_WIRED_MAC_CASE_FILE, @@ -1087,7 +1089,7 @@ test_read_valid_wireless_connection (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_WIRELESS_FILE, @@ -1136,7 +1138,7 @@ test_read_valid_wireless_connection (void) /* ===== WIRED SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "connection-verify-wireless", "failed to verify %s: missing %s setting", TEST_WIRELESS_FILE, @@ -1162,7 +1164,7 @@ test_read_valid_wireless_connection (void) /* ===== IPv4 SETTING ===== */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "connection-verify-ip4", "failed to verify %s: missing %s setting", TEST_WIRELESS_FILE, @@ -1315,7 +1317,7 @@ test_read_string_ssid (void) /* ===== WIRELESS SETTING ===== */ - s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + s_wireless = nm_connection_get_setting_wireless (connection); ASSERT (s_wireless != NULL, "connection-verify-wireless", "failed to verify %s: missing %s setting", TEST_STRING_SSID_FILE, @@ -1832,7 +1834,7 @@ test_read_bt_dun_connection (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_BT_DUN_FILE, @@ -1866,7 +1868,7 @@ test_read_bt_dun_connection (void) /* ===== BLUETOOTH SETTING ===== */ - s_bluetooth = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH)); + s_bluetooth = nm_connection_get_setting_bluetooth (connection); ASSERT (s_bluetooth != NULL, "connection-verify-bt", "failed to verify %s: missing %s setting", TEST_WIRELESS_FILE, @@ -1905,7 +1907,7 @@ test_read_bt_dun_connection (void) /* ===== GSM SETTING ===== */ - s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + s_gsm = nm_connection_get_setting_gsm (connection); ASSERT (s_gsm != NULL, "connection-verify-gsm", "failed to verify %s: missing %s setting", TEST_BT_DUN_FILE, @@ -1952,7 +1954,7 @@ test_read_bt_dun_connection (void) /* ===== SERIAL SETTING ===== */ - s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL)); + s_serial = nm_connection_get_setting_serial (connection); ASSERT (s_serial != NULL, "connection-verify-serial", "failed to verify %s: missing %s setting", TEST_BT_DUN_FILE, @@ -2081,7 +2083,7 @@ test_read_gsm_connection (void) NMSettingConnection *s_con; NMSettingSerial *s_serial; NMSettingGsm *s_gsm; - NMSetting *s_bluetooth; + NMSettingBluetooth *s_bluetooth; GError *error = NULL; const char *tmp; const char *expected_id = "AT&T Data Connect"; @@ -2100,7 +2102,7 @@ test_read_gsm_connection (void) /* ===== CONNECTION SETTING ===== */ - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "connection-verify-connection", "failed to verify %s: missing %s setting", TEST_GSM_FILE, @@ -2134,7 +2136,7 @@ test_read_gsm_connection (void) /* ===== BLUETOOTH SETTING ===== */ /* Plain GSM, so no BT setting expected */ - s_bluetooth = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + s_bluetooth = nm_connection_get_setting_bluetooth (connection); ASSERT (s_bluetooth == NULL, "connection-verify-bt", "unexpected %s setting", TEST_GSM_FILE, @@ -2142,7 +2144,7 @@ test_read_gsm_connection (void) /* ===== GSM SETTING ===== */ - s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + s_gsm = nm_connection_get_setting_gsm (connection); ASSERT (s_gsm != NULL, "connection-verify-gsm", "failed to verify %s: missing %s setting", TEST_GSM_FILE, @@ -2215,7 +2217,7 @@ test_read_gsm_connection (void) /* ===== SERIAL SETTING ===== */ - s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL)); + s_serial = nm_connection_get_setting_serial (connection); ASSERT (s_serial != NULL, "connection-verify-serial", "failed to verify %s: missing %s setting", TEST_GSM_FILE, @@ -2324,7 +2326,7 @@ static void test_read_wired_8021x_tls_blob_connection (void) { NMConnection *connection; - NMSetting *s_wired; + NMSettingWired *s_wired; NMSetting8021x *s_8021x; GError *error = NULL; const char *tmp; @@ -2346,11 +2348,11 @@ test_read_wired_8021x_tls_blob_connection (void) } /* ===== Wired Setting ===== */ - s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired != NULL); /* ===== 802.1x Setting ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x != NULL); g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); @@ -2389,7 +2391,7 @@ static void test_read_wired_8021x_tls_bad_path_connection (void) { NMConnection *connection; - NMSetting *s_wired; + NMSettingWired *s_wired; NMSetting8021x *s_8021x; GError *error = NULL; const char *tmp; @@ -2411,11 +2413,11 @@ test_read_wired_8021x_tls_bad_path_connection (void) } /* ===== Wired Setting ===== */ - s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired != NULL); /* ===== 802.1x Setting ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x != NULL); g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); @@ -2451,7 +2453,7 @@ static void test_read_wired_8021x_tls_old_connection (void) { NMConnection *connection; - NMSetting *s_wired; + NMSettingWired *s_wired; NMSetting8021x *s_8021x; GError *error = NULL; const char *tmp; @@ -2472,11 +2474,11 @@ test_read_wired_8021x_tls_old_connection (void) } /* ===== Wired Setting ===== */ - s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired != NULL); /* ===== 802.1x Setting ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x != NULL); g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); @@ -2507,7 +2509,7 @@ static void test_read_wired_8021x_tls_new_connection (void) { NMConnection *connection; - NMSetting *s_wired; + NMSettingWired *s_wired; NMSetting8021x *s_8021x; GError *error = NULL; const char *tmp; @@ -2529,11 +2531,11 @@ test_read_wired_8021x_tls_new_connection (void) } /* ===== Wired Setting ===== */ - s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired != NULL); /* ===== 802.1x Setting ===== */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x != NULL); g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); @@ -2779,7 +2781,7 @@ test_write_wired_8021x_tls_connection_blob (void) g_assert (testfile); /* Check that the new certs got written out */ - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); uuid = nm_setting_connection_get_uuid (s_con); g_assert (uuid); @@ -2805,7 +2807,7 @@ test_write_wired_8021x_tls_connection_blob (void) } /* Ensure the re-read connection's certificates use the path scheme */ - s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (reread); g_assert (s_8021x); g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); @@ -2828,6 +2830,134 @@ test_write_wired_8021x_tls_connection_blob (void) g_object_unref (connection); } +#define TEST_INFINIBAND_FILE TEST_KEYFILES_DIR"/Test_InfiniBand_Connection" + +static void +test_read_infiniband_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingInfiniband *s_ib; + GError *error = NULL; + const GByteArray *array; + guint8 expected_mac[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, + 0x90 }; + const char *expected_id = "Test InfiniBand Connection"; + const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_INFINIBAND_FILE, &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Connection setting */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, expected_uuid); + + /* InfiniBand setting */ + s_ib = nm_connection_get_setting_infiniband (connection); + g_assert (s_ib); + + array = nm_setting_infiniband_get_mac_address (s_ib); + g_assert (array); + g_assert_cmpint (array->len, ==, INFINIBAND_ALEN); + g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + + g_object_unref (connection); +} + +static void +test_write_infiniband_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingInfiniband *s_ib; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + GByteArray *mac; + guint8 tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0xab, 0xbc, + 0xcd, 0xde, 0xef, 0xf0, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f, 0x6f, 0xba + }; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Work InfiniBand", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, + NULL); + g_free (uuid); + + /* InfiniBand setting */ + s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new (); + g_assert (s_ib); + nm_connection_add_setting (connection, NM_SETTING (s_ib)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + g_object_set (s_ib, + NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, + NM_SETTING_INFINIBAND_MTU, 900, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -2876,6 +3006,9 @@ int main (int argc, char **argv) test_write_wired_8021x_tls_connection_path (); test_write_wired_8021x_tls_connection_blob (); + test_read_infiniband_connection (); + test_write_infiniband_connection (); + base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); g_free (base); diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 2babe267..bbd6a7c3 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -416,7 +416,7 @@ mac_address_writer (GKeyFile *file, GByteArray *array; const char *setting_name = nm_setting_get_name (setting); char *mac; - struct ether_addr tmp; + int type; g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); @@ -424,15 +424,16 @@ mac_address_writer (GKeyFile *file, if (!array) return; - if (array->len != ETH_ALEN) { + type = nm_utils_hwaddr_type (array->len); + if (type < 0) { g_warning ("%s: invalid %s / %s MAC address length %d", __func__, setting_name, key, array->len); return; } - memcpy (tmp.ether_addr_octet, array->data, ETH_ALEN); - mac = ether_ntoa (&tmp); + mac = nm_utils_hwaddr_ntoa (array->data, type); g_key_file_set_string (file, setting_name, key, mac); + g_free (mac); } static void @@ -532,6 +533,31 @@ ssid_writer (GKeyFile *file, } } +static void +password_raw_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + const char *setting_name = nm_setting_get_name (setting); + GByteArray *array; + int i, *tmp_array; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); + + array = (GByteArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + tmp_array = g_new (gint, array->len); + for (i = 0; i < array->len; i++) + tmp_array[i] = (int) array->data[i]; + g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len); + g_free (tmp_array); +} + typedef struct ObjectType { const char *key; const char *suffix; @@ -787,10 +813,16 @@ static KeyWriter key_writers[] = { { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR, mac_address_writer }, + { NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS, + mac_address_writer }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, ssid_writer }, { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD_RAW, + password_raw_writer }, + { NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CA_CERT, cert_writer }, { NM_SETTING_802_1X_SETTING_NAME, diff --git a/src/settings/tests/Makefile.am b/src/settings/tests/Makefile.am index 4a451398..57d56fc4 100644 --- a/src/settings/tests/Makefile.am +++ b/src/settings/tests/Makefile.am @@ -1,5 +1,6 @@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/src/settings diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in index 7c966ba2..de5474d4 100644 --- a/src/settings/tests/Makefile.in +++ b/src/settings/tests/Makefile.in @@ -143,6 +143,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -197,11 +199,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -212,6 +218,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -251,6 +258,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -316,6 +325,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/src/settings diff --git a/src/supplicant-manager/Makefile.am b/src/supplicant-manager/Makefile.am index 359fc70a..e8a2ce74 100644 --- a/src/supplicant-manager/Makefile.am +++ b/src/supplicant-manager/Makefile.am @@ -2,10 +2,13 @@ SUBDIRS=. tests INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_builddir}/libnm-util noinst_LTLIBRARIES = libsupplicant-manager.la @@ -27,7 +30,6 @@ libsupplicant_manager_la_CPPFLAGS = \ -DNM_LOCALSTATEDIR=\"$(localstatedir)\" libsupplicant_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in index 5a7a2f2f..fbb43bde 100644 --- a/src/supplicant-manager/Makefile.in +++ b/src/supplicant-manager/Makefile.in @@ -57,7 +57,6 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libsupplicant_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libsupplicant_manager_la_OBJECTS = \ @@ -184,6 +183,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -238,11 +239,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -253,6 +258,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -292,6 +298,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -358,10 +366,13 @@ top_srcdir = @top_srcdir@ SUBDIRS = . tests INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_builddir}/libnm-util noinst_LTLIBRARIES = libsupplicant-manager.la libsupplicant_manager_la_SOURCES = \ @@ -382,7 +393,6 @@ libsupplicant_manager_la_CPPFLAGS = \ -DNM_LOCALSTATEDIR=\"$(localstatedir)\" libsupplicant_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c index 4860314b..a8e4ab9d 100644 --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2006 - 2010 Red Hat, Inc. + * Copyright (C) 2006 - 2012 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -54,6 +54,7 @@ typedef struct GHashTable *config; GHashTable *blobs; guint32 ap_scan; + gboolean fast_required; gboolean dispose_has_run; } NMSupplicantConfigPrivate; @@ -278,6 +279,14 @@ nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan; } +gboolean +nm_supplicant_config_fast_required (NMSupplicantConfig *self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->fast_required; +} + static void get_hash_cb (gpointer key, gpointer value, gpointer user_data) { @@ -293,6 +302,7 @@ get_hash_cb (gpointer key, gpointer value, gpointer user_data) g_value_set_int (variant, atoi (opt->value)); break; case TYPE_BYTES: + case TYPE_UTF8: array = g_byte_array_sized_new (opt->len); g_byte_array_append (array, (const guint8 *) opt->value, opt->len); g_value_init (variant, DBUS_TYPE_G_UCHAR_ARRAY); @@ -583,7 +593,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, NMSettingWirelessSecurity *setting, NMSetting8021x *setting_8021x, - const char *connection_uid) + const char *con_uuid) { char *value; gboolean success; @@ -592,7 +602,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); - g_return_val_if_fail (connection_uid != NULL, FALSE); + g_return_val_if_fail (con_uuid != NULL, FALSE); key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting); if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE)) @@ -692,7 +702,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) { if (!setting_8021x) return FALSE; - if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, connection_uid, FALSE)) + if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, con_uuid, FALSE)) return FALSE; } @@ -711,24 +721,43 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, NMSetting8021x *setting, - const char *connection_uid, + const char *con_uuid, gboolean wired) { + NMSupplicantConfigPrivate *priv; char *tmp; const char *peapver, *value, *path; gboolean success, added; GString *phase1, *phase2; const GByteArray *array; - gboolean peap = FALSE; + gboolean peap = FALSE, fast = FALSE; guint32 i, num_eap; + gboolean fast_provisoning_allowed = FALSE; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); - g_return_val_if_fail (connection_uid != NULL, FALSE); + g_return_val_if_fail (con_uuid != NULL, FALSE); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); value = nm_setting_802_1x_get_password (setting); - if (!add_string_val (self, value, "password", FALSE, TRUE)) - return FALSE; + if (value) { + if (!add_string_val (self, value, "password", FALSE, TRUE)) + return FALSE; + } else { + array = nm_setting_802_1x_get_password_raw (setting); + if (array) { + success = nm_supplicant_config_add_option (self, + "password", + (const char *)array->data, + array->len, + TRUE); + if (!success) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding password-raw to supplicant config."); + return FALSE; + } + } + } value = nm_setting_802_1x_get_pin (setting); if (!add_string_val (self, value, "pin", FALSE, TRUE)) return FALSE; @@ -744,14 +773,16 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE); - /* Check for PEAP + GTC */ + /* Check EAP method for special handling: PEAP + GTC, FAST */ num_eap = nm_setting_802_1x_get_num_eap_methods (setting); for (i = 0; i < num_eap; i++) { const char *method = nm_setting_802_1x_get_eap_method (setting, i); - if (method && (strcasecmp (method, "peap") == 0)) { + if (method && (strcasecmp (method, "peap") == 0)) peap = TRUE; - break; + if (method && (strcasecmp (method, "fast") == 0)) { + fast = TRUE; + priv->fast_required = TRUE; } } @@ -785,6 +816,16 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting)); } + value = nm_setting_802_1x_get_phase1_fast_provisioning (setting); + if (value) { + if (phase1->len) + g_string_append_c (phase1, ' '); + g_string_append_printf (phase1, "fast_provisioning=%s", value); + + if (strcmp (value, "0") != 0) + fast_provisoning_allowed = TRUE; + } + if (phase1->len) { if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE)) { g_string_free (phase1, TRUE); @@ -794,7 +835,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, g_string_free (phase1, TRUE); phase2 = g_string_new (NULL); - if (nm_setting_802_1x_get_phase2_auth (setting)) { + if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) { tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1); g_string_append_printf (phase2, "auth=%s", tmp); g_free (tmp); @@ -816,6 +857,32 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, } g_string_free (phase2, TRUE); + /* PAC file */ + path = nm_setting_802_1x_get_pac_file (setting); + if (path) { + if (!add_string_val (self, path, "pac_file", FALSE, FALSE)) + return FALSE; + } else { + /* PAC file is not specified. + * If provisioning is allowed, use an blob format. + */ + if (fast_provisoning_allowed) { + char *blob_name = g_strdup_printf ("blob://pac-blob-%s", con_uuid); + if (!add_string_val (self, blob_name, "pac_file", FALSE, FALSE)) { + g_free (blob_name); + return FALSE; + } + g_free (blob_name); + } else { + /* This is only error for EAP-FAST; don't disturb other methods. */ + if (fast) { + nm_log_err (LOGD_SUPPLICANT, "EAP-FAST error: no PAC file provided and " + "automatic PAC provisioning is disabled."); + return FALSE; + } + } + } + /* CA path */ path = nm_setting_802_1x_get_ca_path (setting); if (nm_setting_802_1x_get_system_ca_certs (setting)) @@ -838,7 +905,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_ca_cert_blob (setting); - ADD_BLOB_VAL (array, "ca_cert", connection_uid); + ADD_BLOB_VAL (array, "ca_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_ca_cert_path (setting); @@ -853,7 +920,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); - ADD_BLOB_VAL (array, "ca_cert2", connection_uid); + ADD_BLOB_VAL (array, "ca_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_ca_cert_path (setting); @@ -881,7 +948,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_private_key_blob (setting); - ADD_BLOB_VAL (array, "private_key", connection_uid); + ADD_BLOB_VAL (array, "private_key", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: @@ -919,7 +986,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_client_cert_blob (setting); - ADD_BLOB_VAL (array, "client_cert", connection_uid); + ADD_BLOB_VAL (array, "client_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_client_cert_path (setting); @@ -937,7 +1004,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_phase2_private_key_blob (setting); - ADD_BLOB_VAL (array, "private_key2", connection_uid); + ADD_BLOB_VAL (array, "private_key2", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: @@ -975,7 +1042,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: array = nm_setting_802_1x_get_phase2_client_cert_blob (setting); - ADD_BLOB_VAL (array, "client_cert2", connection_uid); + ADD_BLOB_VAL (array, "client_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_client_cert_path (setting); diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h index dad23e29..a8d30470 100644 --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2006 - 2012 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -57,6 +57,8 @@ guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self); void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self, guint32 ap_scan); +gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self); + GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig *self); GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self); @@ -70,13 +72,13 @@ gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self, gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, NMSettingWirelessSecurity *setting, NMSetting8021x *setting_8021x, - const char *connection_uid); + const char *con_uuid); gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self); gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, NMSetting8021x *setting, - const char *connection_uid, + const char *con_uuid, gboolean wired); G_END_DECLS diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 857cde51..f8ad8f18 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -15,10 +15,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2006 - 2010 Red Hat, Inc. + * Copyright (C) 2006 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include <config.h> #include <stdio.h> #include <string.h> #include <glib.h> @@ -55,11 +56,14 @@ static void wpas_iface_scan_done (DBusGProxy *proxy, /* Signals */ enum { - STATE, /* change in the interface's state */ - REMOVED, /* interface was removed by the supplicant */ - NEW_BSS, /* interface saw a new access point from a scan */ - SCAN_DONE, /* wifi scan is complete */ - CONNECTION_ERROR, /* an error occurred during a connection request */ + STATE, /* change in the interface's state */ + REMOVED, /* interface was removed by the supplicant */ + NEW_BSS, /* interface saw a new access point from a scan */ + BSS_UPDATED, /* a BSS property changed */ + BSS_REMOVED, /* supplicant removed BSS from its scan list */ + SCAN_DONE, /* wifi scan is complete */ + CONNECTION_ERROR, /* an error occurred during a connection request */ + CREDENTIALS_REQUEST, /* 802.1x identity or password requested */ LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -79,6 +83,8 @@ typedef struct { NMDBusManager * dbus_mgr; char * dev; gboolean is_wireless; + gboolean has_credreq; /* Whether querying 802.1x credentials is supported */ + gboolean fast_supported; char * object_path; guint32 state; @@ -92,6 +98,7 @@ typedef struct { DBusGProxy * props_proxy; char * net_path; guint32 blobs_left; + GHashTable * bss_proxies; guint32 last_scan; @@ -100,6 +107,28 @@ typedef struct { gboolean disposed; } NMSupplicantInterfacePrivate; +/* FIXME: remove this and just store the standard D-Bus properties + * proxy object in bss_proxies when we drop support for wpa_supplicant + * 0.7.x. + */ +typedef struct { + /* Proxy for standard D-Bus Properties interface */ + DBusGProxy *props; + /* Proxy for old wpa_supplicant-specific PropertiesChanged signal */ + DBusGProxy *old_props; +} BssProxies; + +static void +bss_proxies_free (gpointer data) +{ + BssProxies *proxies = data; + + g_object_unref (proxies->props); + g_object_unref (proxies->old_props); + memset (proxies, 0, sizeof (*proxies)); + g_free (proxies); +} + static gboolean cancel_all_cb (GObject *object, gpointer call_id, gpointer user_data) { @@ -192,6 +221,14 @@ emit_error_helper (NMSupplicantInterface *self, } static void +signal_new_bss (NMSupplicantInterface *self, + const char *object_path, + GHashTable *props) +{ + g_signal_emit (self, signals[NEW_BSS], 0, object_path, props); +} + +static void bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; @@ -201,7 +238,7 @@ bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_ if (dbus_g_proxy_end_call (proxy, call_id, &error, DBUS_TYPE_G_MAP_OF_VARIANT, &props, G_TYPE_INVALID)) { - g_signal_emit (info->interface, signals[NEW_BSS], 0, props); + signal_new_bss (info->interface, dbus_g_proxy_get_path (proxy), props); g_hash_table_destroy (props); } else { if (!strstr (error->message, "The BSSID requested was invalid")) { @@ -213,31 +250,93 @@ bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_ } static void -request_bss_properties (NMSupplicantInterface *self, - GPtrArray *paths) +bss_properties_changed (DBusGProxy *proxy, + const char *interface, + GHashTable *props, + const char **unused, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + + if (g_strcmp0 (interface, WPAS_DBUS_IFACE_BSS) == 0) + g_signal_emit (self, signals[BSS_UPDATED], 0, dbus_g_proxy_get_path (proxy), props); +} + +static void +old_bss_properties_changed (DBusGProxy *proxy, + GHashTable *props, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + + g_signal_emit (self, signals[BSS_UPDATED], 0, dbus_g_proxy_get_path (proxy), props); +} + +static void +handle_new_bss (NMSupplicantInterface *self, + const char *object_path, + GHashTable *props) { NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - int i; - - /* Fire off a "properties" call for each returned BSSID */ - for (i = 0; i < paths->len; i++) { - NMSupplicantInfo *info; - DBusGProxy *proxy; - DBusGProxyCall *call; - - proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), - WPAS_DBUS_SERVICE, - g_ptr_array_index (paths, i), - DBUS_INTERFACE_PROPERTIES); - info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (proxy, "GetAll", - bssid_properties_cb, - info, - nm_supplicant_info_destroy, - G_TYPE_STRING, WPAS_DBUS_IFACE_BSS, - G_TYPE_INVALID); + NMSupplicantInfo *info; + DBusGProxyCall *call; + BssProxies *proxies; + + g_return_if_fail (object_path != NULL); + + if (g_hash_table_lookup (priv->bss_proxies, object_path)) + return; + + proxies = g_malloc0 (sizeof (*proxies)); + proxies->props = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + object_path, + DBUS_INTERFACE_PROPERTIES); + proxies->old_props = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + object_path, + WPAS_DBUS_IFACE_BSS); + g_hash_table_insert (priv->bss_proxies, + (gpointer) dbus_g_proxy_get_path (proxies->props), + proxies); + + /* Standard D-Bus PropertiesChanged signal */ + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED_BOXED, + G_TYPE_NONE, + G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_STRV, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (proxies->props, "PropertiesChanged", + G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_STRV, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxies->props, "PropertiesChanged", + G_CALLBACK (bss_properties_changed), + self, NULL); + + /* Old wpa_supplicant-specific PropertiesChanged signal; since it's using + * a different interface, we have to use a different DBusGProxy + */ + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (proxies->old_props, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxies->old_props, "PropertiesChanged", + G_CALLBACK (old_bss_properties_changed), + self, NULL); + + if (props) { + signal_new_bss (self, object_path, props); + } else { + info = nm_supplicant_info_new (self, proxies->props, priv->other_pcalls); + call = dbus_g_proxy_begin_call (proxies->props, "GetAll", + bssid_properties_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, WPAS_DBUS_IFACE_BSS, + G_TYPE_INVALID); nm_supplicant_info_set_call (info, call); - g_object_unref (proxy); } } @@ -247,7 +346,20 @@ wpas_iface_bss_added (DBusGProxy *proxy, GHashTable *props, gpointer user_data) { - g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[NEW_BSS], 0, props); + handle_new_bss (NM_SUPPLICANT_INTERFACE (user_data), object_path, props); +} + +static void +wpas_iface_bss_removed (DBusGProxy *proxy, + const char *object_path, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + g_signal_emit (self, signals[BSS_REMOVED], 0, object_path); + + g_hash_table_remove (priv->bss_proxies, object_path); } static int @@ -318,6 +430,10 @@ set_state (NMSupplicantInterface *self, guint32 new_state) "BSSAdded", G_CALLBACK (wpas_iface_bss_added), self); + dbus_g_proxy_disconnect_signal (priv->iface_proxy, + "BSSRemoved", + G_CALLBACK (wpas_iface_bss_removed), + self); } } @@ -403,8 +519,13 @@ wpas_iface_properties_changed (DBusGProxy *proxy, set_state_from_string (self, g_value_get_string (value)); value = g_hash_table_lookup (props, "BSSs"); - if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) - request_bss_properties (self, g_value_get_boxed (value)); + if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) { + GPtrArray *paths = g_value_get_boxed (value); + int i; + + for (i = 0; paths && (i < paths->len); i++) + handle_new_bss (self, g_ptr_array_index (paths, i), NULL); + } } static void @@ -443,6 +564,92 @@ wpas_iface_get_props (NMSupplicantInterface *self) nm_supplicant_info_set_call (info, call); } +gboolean +nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, + const char *field, + const char *value, + GError **error) +{ + NMSupplicantInterfacePrivate *priv; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); + g_return_val_if_fail (field != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + g_return_val_if_fail (priv->has_credreq == TRUE, FALSE); + + /* Need a network block object path */ + g_return_val_if_fail (priv->net_path, FALSE); + return dbus_g_proxy_call_with_timeout (priv->iface_proxy, "NetworkReply", + 5000, + error, + DBUS_TYPE_G_OBJECT_PATH, priv->net_path, + G_TYPE_STRING, field, + G_TYPE_STRING, value, + G_TYPE_INVALID); +} + +static void +wpas_iface_network_request (DBusGProxy *proxy, + const char *object_path, + const char *field, + const char *message, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + g_return_if_fail (priv->has_credreq == TRUE); + g_return_if_fail (priv->net_path != NULL); + g_return_if_fail (g_strcmp0 (object_path, priv->net_path) == 0); + + g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message); +} + +static void +iface_check_netreply_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GError *error = NULL; + + if ( dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) + || dbus_g_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs")) { + /* We know NetworkReply is supported if the NetworkReply method returned + * successfully (which is unexpected since we sent a bogus network + * object path) or if we got an "InvalidArgs" (which indicates NetworkReply + * is supported). We know it's not supported if we get an + * "UnknownMethod" error. + */ + priv->has_credreq = TRUE; + + nm_log_dbg (LOGD_SUPPLICANT, "Supplicant %s network credentials requests", + priv->has_credreq ? "supports" : "does not support"); + } + g_clear_error (&error); +} + +static void +wpas_iface_check_network_reply (NMSupplicantInterface *self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + + info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "NetworkReply", + iface_check_netreply_cb, + info, + nm_supplicant_info_destroy, + DBUS_TYPE_G_OBJECT_PATH, "/foobaraasdfasdf", + G_TYPE_STRING, "foobar", + G_TYPE_STRING, "foobar", + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); +} + static void interface_add_done (NMSupplicantInterface *self, char *path) { @@ -486,6 +693,30 @@ interface_add_done (NMSupplicantInterface *self, char *path) self, NULL); + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->iface_proxy, "BSSRemoved", + DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSRemoved", + G_CALLBACK (wpas_iface_bss_removed), + self, + NULL); + + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->iface_proxy, "NetworkRequest", + DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->iface_proxy, "NetworkRequest", + G_CALLBACK (wpas_iface_network_request), + self, + NULL); + priv->props_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), WPAS_DBUS_SERVICE, path, @@ -493,6 +724,9 @@ interface_add_done (NMSupplicantInterface *self, char *path) /* Get initial properties */ wpas_iface_get_props (self); + /* Check whether NetworkReply is supported */ + wpas_iface_check_network_reply (self); + set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY); } @@ -574,6 +808,12 @@ interface_add_cb (DBusGProxy *proxy, } } +#if HAVE_WEXT +#define DEFAULT_WIFI_DRIVER "nl80211,wext" +#else +#define DEFAULT_WIFI_DRIVER "nl80211" +#endif + static void interface_add (NMSupplicantInterface *self, gboolean is_wireless) { @@ -602,7 +842,7 @@ interface_add (NMSupplicantInterface *self, gboolean is_wireless) driver = g_new0 (GValue, 1); g_value_init (driver, G_TYPE_STRING); - g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired"); + g_value_set_string (driver, is_wireless ? DEFAULT_WIFI_DRIVER : "wired"); g_hash_table_insert (hash, "Driver", driver); ifname = g_new0 (GValue, 1); @@ -851,7 +1091,15 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self, priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); nm_supplicant_interface_disconnect (self); - + + /* Make sure the supplicant supports EAP-FAST before trying to send + * it an EAP-FAST configuration. + */ + if (nm_supplicant_config_fast_required (cfg) && !priv->fast_supported) { + nm_log_warn (LOGD_SUPPLICANT, "EAP-FAST is not supported by the supplicant"); + return FALSE; + } + if (priv->cfg) g_object_unref (priv->cfg); priv->cfg = cfg; @@ -1017,6 +1265,7 @@ NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager *smgr, const char *ifname, gboolean is_wireless, + gboolean fast_supported, gboolean start_now) { NMSupplicantInterface *self; @@ -1039,6 +1288,7 @@ nm_supplicant_interface_new (NMSupplicantManager *smgr, priv->dev = g_strdup (ifname); priv->is_wireless = is_wireless; + priv->fast_supported = fast_supported; if (start_now) interface_add (self, priv->is_wireless); @@ -1063,6 +1313,8 @@ nm_supplicant_interface_init (NMSupplicantInterface * self) WPAS_DBUS_SERVICE, WPAS_DBUS_PATH, WPAS_DBUS_INTERFACE); + + priv->bss_proxies = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, bss_proxies_free); } static void @@ -1123,6 +1375,8 @@ dispose (GObject *object) if (priv->wpas_proxy) g_object_unref (priv->wpas_proxy); + g_hash_table_destroy (priv->bss_proxies); + if (priv->smgr) { if (priv->smgr_avail_id) g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id); @@ -1187,8 +1441,26 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMSupplicantInterfaceClass, new_bss), NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); + _nm_marshal_VOID__STRING_POINTER, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER); + + signals[BSS_UPDATED] = + g_signal_new (NM_SUPPLICANT_INTERFACE_BSS_UPDATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, bss_updated), + NULL, NULL, + _nm_marshal_VOID__STRING_POINTER, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER); + + signals[BSS_REMOVED] = + g_signal_new (NM_SUPPLICANT_INTERFACE_BSS_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, bss_removed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); signals[SCAN_DONE] = g_signal_new (NM_SUPPLICANT_INTERFACE_SCAN_DONE, @@ -1207,5 +1479,14 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, _nm_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + + signals[CREDENTIALS_REQUEST] = + g_signal_new (NM_SUPPLICANT_INTERFACE_CREDENTIALS_REQUEST, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, credentials_request), + NULL, NULL, + _nm_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); } diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index e32411d7..608ee059 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -57,8 +57,11 @@ enum { #define NM_SUPPLICANT_INTERFACE_STATE "state" #define NM_SUPPLICANT_INTERFACE_REMOVED "removed" #define NM_SUPPLICANT_INTERFACE_NEW_BSS "new-bss" +#define NM_SUPPLICANT_INTERFACE_BSS_UPDATED "bss-updated" +#define NM_SUPPLICANT_INTERFACE_BSS_REMOVED "bss-removed" #define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done" #define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error" +#define NM_SUPPLICANT_INTERFACE_CREDENTIALS_REQUEST "credentials-request" struct _NMSupplicantInterface { GObject parent; @@ -79,8 +82,18 @@ typedef struct { /* interface saw a new BSS */ void (*new_bss) (NMSupplicantInterface *iface, + const char *object_path, GHashTable *props); + /* a BSS property changed */ + void (*bss_updated) (NMSupplicantInterface *iface, + const char *object_path, + GHashTable *props); + + /* supplicant removed a BSS from its scan list */ + void (*bss_removed) (NMSupplicantInterface *iface, + const char *object_path); + /* wireless scan is done */ void (*scan_done) (NMSupplicantInterface *iface, gboolean success); @@ -89,6 +102,11 @@ typedef struct { void (*connection_error) (NMSupplicantInterface * iface, const char * name, const char * message); + + /* 802.1x credentials requested */ + void (*credentials_request) (NMSupplicantInterface *iface, + const char *field, + const char *message); } NMSupplicantInterfaceClass; @@ -97,6 +115,7 @@ GType nm_supplicant_interface_get_type (void); NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless, + gboolean fast_supported, gboolean start_now); gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, @@ -118,4 +137,11 @@ gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self); const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self); +gboolean nm_supplicant_interface_get_has_credentials_request (NMSupplicantInterface *self); + +gboolean nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, + const char *field, + const char *value, + GError **error); + #endif /* NM_SUPPLICANT_INTERFACE_H */ diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 349f722a..ae150865 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -86,7 +86,7 @@ nm_supplicant_manager_iface_get (NMSupplicantManager * self, start_now = !die_count_exceeded (priv->die_count); nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname); - iface = nm_supplicant_interface_new (self, ifname, is_wireless, start_now); + iface = nm_supplicant_interface_new (self, ifname, is_wireless, priv->fast_supported, start_now); if (iface) g_hash_table_insert (priv->ifaces, g_strdup (ifname), iface); } else { diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.c b/src/supplicant-manager/nm-supplicant-settings-verify.c index aea5bfec..76de84d8 100644 --- a/src/supplicant-manager/nm-supplicant-settings-verify.c +++ b/src/supplicant-manager/nm-supplicant-settings-verify.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2006 - 2012 Red Hat, Inc. */ #include <glib.h> @@ -44,6 +44,10 @@ static gboolean validate_type_bytes (const struct Opt * opt, const char * value, const guint32 len); +static gboolean validate_type_utf8 (const struct Opt *opt, + const char * value, + const guint32 len); + static gboolean validate_type_keyword (const struct Opt * opt, const char * value, const guint32 len); @@ -58,6 +62,7 @@ struct validate_entry { static const struct validate_entry validate_table[] = { { TYPE_INT, validate_type_int }, { TYPE_BYTES, validate_type_bytes }, + { TYPE_UTF8, validate_type_utf8 }, { TYPE_KEYWORD, validate_type_keyword }, }; @@ -73,7 +78,9 @@ const char * eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM", const char * phase1_allowed[] = {"peapver=0", "peapver=1", "peaplabel=1", "peap_outer_success=0", "include_tls_length=1", - "sim_min_num_chal=3", NULL }; + "sim_min_num_chal=3", "fast_provisioning=0", + "fast_provisioning=1", "fast_provisioning=2", + "fast_provisioning=3", NULL }; const char * phase2_allowed[] = {"auth=PAP", "auth=CHAP", "auth=MSCHAP", "auth=MSCHAPV2", "auth=GTC", "auth=OTP", "auth=MD5", "auth=TLS", "autheap=MD5", @@ -100,7 +107,7 @@ static const struct Opt opt_table[] = { { "eapol_flags", TYPE_INT, 0, 3, FALSE, NULL }, { "eap", TYPE_KEYWORD, 0, 0, FALSE, eap_allowed }, { "identity", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "password", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "password", TYPE_UTF8, 0, 0, FALSE, NULL }, { "ca_path", TYPE_BYTES, 0, 0, FALSE, NULL }, { "subject_match", TYPE_BYTES, 0, 0, FALSE, NULL }, { "altsubject_match", TYPE_BYTES, 0, 0, FALSE, NULL }, @@ -129,6 +136,7 @@ static const struct Opt opt_table[] = { { "fragment_size", TYPE_INT, 1, 2000, FALSE, NULL }, { "proactive_key_caching", TYPE_INT, 0, 1, FALSE, NULL }, { "bgscan", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "pac_file", TYPE_BYTES, 0, 1024, FALSE, NULL }, }; @@ -174,6 +182,26 @@ validate_type_bytes (const struct Opt * opt, } static gboolean +validate_type_utf8 (const struct Opt *opt, + const char * value, + const guint32 len) +{ + guint32 check_len; + + g_return_val_if_fail (opt != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + check_len = opt->int_high ? opt->int_high : 255; + /* Note that we deliberately don't validate the UTF-8, because + some "UTF-8" fields, such as 8021x.password, do not actually + have to be valid UTF-8 */ + if (g_utf8_strlen (value, len) > check_len) + return FALSE; + + return TRUE; +} + +static gboolean validate_type_keyword (const struct Opt * opt, const char * value, const guint32 len) diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.h b/src/supplicant-manager/nm-supplicant-settings-verify.h index 0939ebdb..eb213e0e 100644 --- a/src/supplicant-manager/nm-supplicant-settings-verify.h +++ b/src/supplicant-manager/nm-supplicant-settings-verify.h @@ -21,10 +21,11 @@ #ifndef NM_SUPPLICANT_SETTINGS_VERIFY_H #define NM_SUPPLICANT_SETTINGS_VERIFY_H -typedef enum OptType { +typedef enum { TYPE_INVALID = 0, TYPE_INT, TYPE_BYTES, + TYPE_UTF8, TYPE_KEYWORD, TYPE_STRING } OptType; diff --git a/src/supplicant-manager/tests/Makefile.am b/src/supplicant-manager/tests/Makefile.am index b5e4db61..47ae66c5 100644 --- a/src/supplicant-manager/tests/Makefile.am +++ b/src/supplicant-manager/tests/Makefile.am @@ -1,6 +1,8 @@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/supplicant-manager diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in index 25e60e86..65be2b39 100644 --- a/src/supplicant-manager/tests/Makefile.in +++ b/src/supplicant-manager/tests/Makefile.in @@ -143,6 +143,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -197,11 +199,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -212,6 +218,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -251,6 +258,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -316,7 +325,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/supplicant-manager diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 296668aa..90487042 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -1,6 +1,8 @@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/dhcp-manager \ -I$(top_builddir)/marshallers \ -I$(top_srcdir)/src \ diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index 39390e4b..7d367415 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -160,6 +160,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -214,11 +216,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -229,6 +235,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -268,6 +275,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -333,7 +342,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/dhcp-manager \ -I$(top_builddir)/marshallers \ -I$(top_srcdir)/src \ diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index 93bd325a..faa023fc 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -162,7 +162,7 @@ fill_wifi_empty (NMConnection *connection) { NMSettingWireless *s_wifi; - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); if (!s_wifi) { s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); @@ -175,7 +175,7 @@ fill_wifi (NMConnection *connection, const KeyData items[]) { NMSettingWireless *s_wifi; - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wifi = nm_connection_get_setting_wireless (connection); if (!s_wifi) { s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); @@ -190,7 +190,7 @@ fill_wsec (NMConnection *connection, const KeyData items[]) { NMSettingWirelessSecurity *s_wsec; - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_wsec = nm_connection_get_setting_wireless_security (connection); if (!s_wsec) { s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); nm_connection_add_setting (connection, NM_SETTING (s_wsec)); @@ -205,7 +205,7 @@ fill_8021x (NMConnection *connection, const KeyData items[]) { NMSetting8021x *s_8021x; - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting_802_1x (connection); if (!s_8021x) { s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); nm_connection_add_setting (connection, NM_SETTING (s_8021x)); diff --git a/src/vpn-manager/Makefile.am b/src/vpn-manager/Makefile.am index ce99728e..c3c5b525 100644 --- a/src/vpn-manager/Makefile.am +++ b/src/vpn-manager/Makefile.am @@ -1,10 +1,13 @@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src \ - -I${top_builddir}/marshallers \ -I${top_srcdir}/src/dns-manager \ -DVPN_NAME_FILES_DIR=\""$(sysconfdir)/NetworkManager/VPN"\" @@ -16,8 +19,6 @@ libvpn_manager_la_SOURCES = \ nm-vpn-manager.h \ nm-vpn-service.c \ nm-vpn-service.h \ - nm-vpn-connection-base.c \ - nm-vpn-connection-base.h \ nm-vpn-connection.c \ nm-vpn-connection.h @@ -28,16 +29,13 @@ libvpn_manager_la_CPPFLAGS = \ -DG_DISABLE_DEPRECATED libvpn_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) -nm-vpn-connection-base-glue.h: $(top_srcdir)/introspection/nm-active-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection_base --mode=glib-server --output=$@ $< - nm-vpn-connection-glue.h: $(top_srcdir)/introspection/nm-vpn-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-server --output=$@ $< @@ -46,7 +44,6 @@ nm-vpn-plugin-bindings.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml BUILT_SOURCES = \ - nm-vpn-connection-base-glue.h \ nm-vpn-connection-glue.h \ nm-vpn-plugin-bindings.h diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in index 51a12507..9a7e5e42 100644 --- a/src/vpn-manager/Makefile.in +++ b/src/vpn-manager/Makefile.in @@ -57,13 +57,12 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libvpn_manager_la_DEPENDENCIES = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libvpn_manager_la_OBJECTS = libvpn_manager_la-nm-vpn-manager.lo \ libvpn_manager_la-nm-vpn-service.lo \ - libvpn_manager_la-nm-vpn-connection-base.lo \ libvpn_manager_la-nm-vpn-connection.lo libvpn_manager_la_OBJECTS = $(am_libvpn_manager_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) @@ -145,6 +144,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -199,11 +200,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -214,6 +219,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -253,6 +259,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -319,10 +327,13 @@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src/generated \ + -I${top_builddir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src \ - -I${top_builddir}/marshallers \ -I${top_srcdir}/src/dns-manager \ -DVPN_NAME_FILES_DIR=\""$(sysconfdir)/NetworkManager/VPN"\" @@ -332,8 +343,6 @@ libvpn_manager_la_SOURCES = \ nm-vpn-manager.h \ nm-vpn-service.c \ nm-vpn-service.h \ - nm-vpn-connection-base.c \ - nm-vpn-connection-base.h \ nm-vpn-connection.c \ nm-vpn-connection.h @@ -344,7 +353,7 @@ libvpn_manager_la_CPPFLAGS = \ -DG_DISABLE_DEPRECATED libvpn_manager_la_LIBADD = \ - $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(LIBNL_LIBS) \ @@ -352,7 +361,6 @@ libvpn_manager_la_LIBADD = \ $(GLIB_LIBS) BUILT_SOURCES = \ - nm-vpn-connection-base-glue.h \ nm-vpn-connection-glue.h \ nm-vpn-plugin-bindings.h @@ -410,7 +418,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvpn_manager_la-nm-vpn-connection-base.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvpn_manager_la-nm-vpn-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvpn_manager_la-nm-vpn-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvpn_manager_la-nm-vpn-service.Plo@am__quote@ @@ -458,14 +465,6 @@ libvpn_manager_la-nm-vpn-service.lo: nm-vpn-service.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvpn_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvpn_manager_la-nm-vpn-service.lo `test -f 'nm-vpn-service.c' || echo '$(srcdir)/'`nm-vpn-service.c -libvpn_manager_la-nm-vpn-connection-base.lo: nm-vpn-connection-base.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvpn_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvpn_manager_la-nm-vpn-connection-base.lo -MD -MP -MF $(DEPDIR)/libvpn_manager_la-nm-vpn-connection-base.Tpo -c -o libvpn_manager_la-nm-vpn-connection-base.lo `test -f 'nm-vpn-connection-base.c' || echo '$(srcdir)/'`nm-vpn-connection-base.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvpn_manager_la-nm-vpn-connection-base.Tpo $(DEPDIR)/libvpn_manager_la-nm-vpn-connection-base.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-vpn-connection-base.c' object='libvpn_manager_la-nm-vpn-connection-base.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvpn_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libvpn_manager_la-nm-vpn-connection-base.lo `test -f 'nm-vpn-connection-base.c' || echo '$(srcdir)/'`nm-vpn-connection-base.c - libvpn_manager_la-nm-vpn-connection.lo: nm-vpn-connection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libvpn_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libvpn_manager_la-nm-vpn-connection.lo -MD -MP -MF $(DEPDIR)/libvpn_manager_la-nm-vpn-connection.Tpo -c -o libvpn_manager_la-nm-vpn-connection.lo `test -f 'nm-vpn-connection.c' || echo '$(srcdir)/'`nm-vpn-connection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvpn_manager_la-nm-vpn-connection.Tpo $(DEPDIR)/libvpn_manager_la-nm-vpn-connection.Plo @@ -682,9 +681,6 @@ uninstall-am: pdf pdf-am ps ps-am tags uninstall uninstall-am -nm-vpn-connection-base-glue.h: $(top_srcdir)/introspection/nm-active-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection_base --mode=glib-server --output=$@ $< - nm-vpn-connection-glue.h: $(top_srcdir)/introspection/nm-vpn-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-server --output=$@ $< diff --git a/src/vpn-manager/nm-vpn-connection-base.c b/src/vpn-manager/nm-vpn-connection-base.c deleted file mode 100644 index bc2cffb2..00000000 --- a/src/vpn-manager/nm-vpn-connection-base.c +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2011 Red Hat, Inc. - * Copyright (C) 2007 - 2008 Novell, Inc. - */ - -#include "NetworkManager.h" -#include "nm-vpn-connection-base.h" -#include "nm-active-connection.h" -#include "nm-vpn-connection-base-glue.h" -#include "nm-dbus-manager.h" - -G_DEFINE_ABSTRACT_TYPE (NMVpnConnectionBase, nm_vpn_connection_base, G_TYPE_OBJECT) - -#define NM_VPN_CONNECTION_BASE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_VPN_CONNECTION_BASE, \ - NMVpnConnectionBasePrivate)) - -typedef struct { - gboolean disposed; - - NMConnection *connection; - char *ac_path; - char *specific_object; - gboolean is_default; - gboolean is_default6; - NMActiveConnectionState state; -} NMVpnConnectionBasePrivate; - -enum { - PROP_0, - PROP_CONNECTION, - PROP_UUID, - PROP_SPECIFIC_OBJECT, - PROP_DEVICES, - PROP_STATE, - PROP_DEFAULT, - PROP_DEFAULT6, - PROP_VPN, - - LAST_PROP -}; - -/****************************************************************/ - -void -nm_vpn_connection_base_set_state (NMVpnConnectionBase *self, - NMVPNConnectionState vpn_state) -{ - NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (self); - NMActiveConnectionState new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - - /* Set the NMActiveConnection state based on VPN state */ - switch (vpn_state) { - case NM_VPN_CONNECTION_STATE_PREPARE: - case NM_VPN_CONNECTION_STATE_NEED_AUTH: - case NM_VPN_CONNECTION_STATE_CONNECT: - case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: - new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING; - break; - case NM_VPN_CONNECTION_STATE_ACTIVATED: - new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED; - break; - default: - break; - } - - if (new_ac_state != priv->state) { - priv->state = new_ac_state; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); - } -} - -const char * -nm_vpn_connection_base_get_ac_path (NMVpnConnectionBase *self) -{ - return NM_VPN_CONNECTION_BASE_GET_PRIVATE (self)->ac_path; -} - -const char * -nm_vpn_connection_base_get_specific_object (NMVpnConnectionBase *self) -{ - return NM_VPN_CONNECTION_BASE_GET_PRIVATE (self)->specific_object; -} - -void -nm_vpn_connection_base_export (NMVpnConnectionBase *self, - NMConnection *connection, - const char *specific_object) -{ - NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (self); - NMDBusManager *dbus_mgr; - - g_return_if_fail (priv->connection == NULL); - - priv->connection = g_object_ref (connection); - priv->specific_object = g_strdup (specific_object); - - dbus_mgr = nm_dbus_manager_get (); - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), - priv->ac_path, G_OBJECT (self)); - g_object_unref (dbus_mgr); -} - -/****************************************************************/ - -static void -nm_vpn_connection_base_init (NMVpnConnectionBase *self) -{ - NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (self); - - priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - priv->ac_path = nm_active_connection_get_next_object_path (); -} - -static void -dispose (GObject *object) -{ - NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (object); - - if (!priv->disposed) { - priv->disposed = TRUE; - - g_free (priv->ac_path); - g_free (priv->specific_object); - g_object_unref (priv->connection); - } - - G_OBJECT_CLASS (nm_vpn_connection_base_parent_class)->dispose (object); -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_CONNECTION: - g_value_set_boxed (value, nm_connection_get_path (priv->connection)); - break; - case PROP_UUID: - g_value_set_string (value, nm_connection_get_uuid (priv->connection)); - break; - case PROP_SPECIFIC_OBJECT: - g_value_set_boxed (value, priv->specific_object); - break; - case PROP_DEVICES: - g_value_take_boxed (value, g_ptr_array_new ()); - break; - case PROP_STATE: - g_value_set_uint (value, priv->state); - break; - case PROP_DEFAULT: - g_value_set_boolean (value, priv->is_default); - break; - case PROP_DEFAULT6: - g_value_set_boolean (value, priv->is_default6); - break; - case PROP_VPN: - g_value_set_boolean (value, TRUE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_vpn_connection_base_class_init (NMVpnConnectionBaseClass *vpn_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (vpn_class); - - g_type_class_add_private (vpn_class, sizeof (NMVpnConnectionBasePrivate)); - - /* virtual methods */ - object_class->get_property = get_property; - object_class->dispose = dispose; - - /* properties */ - nm_active_connection_install_properties (object_class, - PROP_CONNECTION, - PROP_UUID, - PROP_SPECIFIC_OBJECT, - PROP_DEVICES, - PROP_STATE, - PROP_DEFAULT, - PROP_DEFAULT6, - PROP_VPN); - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (vpn_class), - &dbus_glib_nm_vpn_connection_base_object_info); -} - diff --git a/src/vpn-manager/nm-vpn-connection-base.h b/src/vpn-manager/nm-vpn-connection-base.h deleted file mode 100644 index 6f19e7c5..00000000 --- a/src/vpn-manager/nm-vpn-connection-base.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2005 - 2011 Red Hat, Inc. - */ - -#ifndef NM_VPN_CONNECTION_BASE_H -#define NM_VPN_CONNECTION_BASE_H - -#include <glib-object.h> -#include "NetworkManagerVPN.h" -#include "nm-connection.h" - -#define NM_TYPE_VPN_CONNECTION_BASE (nm_vpn_connection_base_get_type ()) -#define NM_VPN_CONNECTION_BASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION_BASE, NMVpnConnectionBase)) -#define NM_VPN_CONNECTION_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION_BASE, NMVpnConnectionBaseClass)) -#define NM_IS_VPN_CONNECTION_BASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION_BASE)) -#define NM_IS_VPN_CONNECTION_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_CONNECTION_BASE)) -#define NM_VPN_CONNECTION_BASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION_BASE, NMVpnConnectionBaseClass)) - -typedef struct { - GObject parent; -} NMVpnConnectionBase; - -typedef struct { - GObjectClass parent; -} NMVpnConnectionBaseClass; - -GType nm_vpn_connection_base_get_type (void); - -const char *nm_vpn_connection_base_get_ac_path (NMVpnConnectionBase *self); - -const char *nm_vpn_connection_base_get_specific_object (NMVpnConnectionBase *self); - -void nm_vpn_connection_base_export (NMVpnConnectionBase *self, - NMConnection *connection, - const char *specific_object); - -void nm_vpn_connection_base_set_state (NMVpnConnectionBase *self, - NMVPNConnectionState vpn_state); - -#endif /* NM_VPN_CONNECTION_BASE_H */ - diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 73f2b553..b391f1ec 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -30,7 +30,6 @@ #include "NetworkManager.h" #include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" -#include "nm-device-interface.h" #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-ip4-config.h" @@ -52,7 +51,7 @@ #include "nm-vpn-connection-glue.h" -G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_VPN_CONNECTION_BASE) +G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) typedef enum { /* Only system secrets */ @@ -108,12 +107,31 @@ enum { PROP_0, PROP_VPN_STATE, PROP_BANNER, + PROP_MASTER = 2000, LAST_PROP }; static void get_secrets (NMVPNConnection *self, SecretsReq secrets_idx); +static NMActiveConnectionState +ac_state_from_vpn_state (NMVPNConnectionState vpn_state) +{ + /* Set the NMActiveConnection state based on VPN state */ + switch (vpn_state) { + case NM_VPN_CONNECTION_STATE_PREPARE: + case NM_VPN_CONNECTION_STATE_NEED_AUTH: + case NM_VPN_CONNECTION_STATE_CONNECT: + case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: + return NM_ACTIVE_CONNECTION_STATE_ACTIVATING; + case NM_VPN_CONNECTION_STATE_ACTIVATED: + return NM_ACTIVE_CONNECTION_STATE_ACTIVATED; + default: + break; + } + return NM_ACTIVE_CONNECTION_STATE_UNKNOWN; +} + static void nm_vpn_connection_set_vpn_state (NMVPNConnection *connection, NMVPNConnectionState vpn_state, @@ -134,7 +152,8 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection, priv->vpn_state = vpn_state; /* Update active connection base class state */ - nm_vpn_connection_base_set_state (NM_VPN_CONNECTION_BASE (connection), vpn_state); + nm_active_connection_set_state (NM_ACTIVE_CONNECTION (connection), + ac_state_from_vpn_state (vpn_state)); /* Save ip_iface since when the VPN goes down it may get freed * before we're done with it. @@ -231,7 +250,10 @@ nm_vpn_connection_new (NMConnection *connection, g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); - self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); + self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, + NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, + NM_ACTIVE_CONNECTION_VPN, TRUE, + NULL); if (!self) return NULL; @@ -246,11 +268,16 @@ nm_vpn_connection_new (NMConnection *connection, G_CALLBACK (device_state_changed), self); - priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, + priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_IP4_CONFIG, G_CALLBACK (device_ip4_config_changed), self); - nm_vpn_connection_base_export (NM_VPN_CONNECTION_BASE (self), connection, specific_object); + if (!nm_active_connection_export (NM_ACTIVE_CONNECTION (self), + connection, + nm_device_get_path (parent_device))) { + g_object_unref (self); + self = NULL; + } return self; } @@ -259,10 +286,10 @@ static const char * nm_vpn_connection_get_service (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - NMSettingVPN *setting; + NMSettingVPN *s_vpn; - setting = (NMSettingVPN *) nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_VPN); - return nm_setting_vpn_get_service_type (setting); + s_vpn = nm_connection_get_setting_vpn (priv->connection); + return nm_setting_vpn_get_service_type (s_vpn); } static void @@ -452,7 +479,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, /* Grab the interface index for address/routing operations */ priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface); - if (!priv->ip_ifindex) { + if (priv->ip_ifindex < 0) { nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface); goto error; } @@ -520,6 +547,15 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, if (val) nm_ip4_config_add_domain (config, g_value_get_string (val)); + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS); + if (val) { + const char **domains = g_value_get_boxed (val); + const char **domain; + + for (domain = domains; domain && *domain; domain++) + nm_ip4_config_add_domain (config, *domain); + } + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_BANNER); if (val) { g_free (priv->banner); @@ -559,7 +595,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, print_vpn_config (config, priv->ip4_internal_gw, priv->ip_iface, priv->banner); /* Merge in user overrides from the NMConnection's IPv4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG)); + s_ip4 = nm_connection_get_setting_ip4_config (priv->connection); nm_utils_merge_ip4_config (config, s_ip4); nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL); @@ -646,22 +682,22 @@ static GHashTable * _hash_with_username (NMConnection *connection, const char *username) { NMConnection *dup; - NMSetting *s_vpn; + NMSettingVPN *s_vpn; GHashTable *hash; const char *existing; /* Shortcut if we weren't given a username or if there already was one in * the VPN setting; don't bother duplicating the connection and everything. */ - s_vpn = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + s_vpn = nm_connection_get_setting_vpn (connection); g_assert (s_vpn); - existing = nm_setting_vpn_get_user_name (NM_SETTING_VPN (s_vpn)); + existing = nm_setting_vpn_get_user_name (s_vpn); if (username == NULL || existing) return nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); dup = nm_connection_duplicate (connection); g_assert (dup); - s_vpn = nm_connection_get_setting (dup, NM_TYPE_SETTING_VPN); + s_vpn = nm_connection_get_setting_vpn (dup); g_assert (s_vpn); g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL); hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ALL); @@ -737,25 +773,17 @@ nm_vpn_connection_activate (NMVPNConnection *connection) } const char * -nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection) -{ - g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); - - return nm_vpn_connection_base_get_ac_path (NM_VPN_CONNECTION_BASE (connection)); -} - -const char * nm_vpn_connection_get_name (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv; - NMSettingConnection *setting; + NMSettingConnection *s_con; g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - setting = (NMSettingConnection *) nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_CONNECTION); + s_con = nm_connection_get_setting_connection (priv->connection); - return nm_setting_connection_get_id (setting); + return nm_setting_connection_get_id (s_con); } NMConnection * @@ -1152,6 +1180,9 @@ get_property (GObject *object, guint prop_id, case PROP_BANNER: g_value_set_string (value, priv->banner ? priv->banner : ""); break; + case PROP_MASTER: + g_value_set_boxed (value, nm_device_get_path (priv->parent_dev)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1171,6 +1202,8 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) object_class->dispose = dispose; object_class->finalize = finalize; + g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); + /* properties */ g_object_class_install_property (object_class, PROP_VPN_STATE, g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, @@ -1199,10 +1232,6 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - signals[PROPERTIES_CHANGED] = - nm_properties_changed_signal_new (object_class, - G_STRUCT_OFFSET (NMVPNConnectionClass, properties_changed)); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (object_class), &dbus_glib_nm_vpn_connection_object_info); } diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index c0d15f8a..93cc06d1 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -26,7 +26,6 @@ #include <glib-object.h> #include "NetworkManagerVPN.h" #include "nm-device.h" -#include "nm-vpn-connection-base.h" #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) @@ -39,18 +38,16 @@ #define NM_VPN_CONNECTION_BANNER "banner" typedef struct { - NMVpnConnectionBase parent; + NMActiveConnection parent; } NMVPNConnection; typedef struct { - NMVpnConnectionBaseClass parent; + NMActiveConnectionClass parent; /* Signals */ void (*vpn_state_changed) (NMVPNConnection *connection, NMVPNConnectionState state, NMVPNConnectionStateReason reason); - - void (*properties_changed) (NMVPNConnection *connection, GHashTable *properties); } NMVPNConnectionClass; GType nm_vpn_connection_get_type (void); @@ -63,8 +60,6 @@ NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, void nm_vpn_connection_activate (NMVPNConnection *connection); NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection); -const char * nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection); -const char * nm_vpn_connection_get_specific_object_path (NMVPNConnection *connection); const char * nm_vpn_connection_get_name (NMVPNConnection *connection); NMVPNConnectionState nm_vpn_connection_get_vpn_state (NMVPNConnection *connection); const char * nm_vpn_connection_get_banner (NMVPNConnection *connection); diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 41e96c0b..34131964 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -29,6 +29,7 @@ #include "nm-dbus-manager.h" #include "NetworkManagerVPN.h" #include "nm-marshal.h" +#include "nm-enum-types.h" #include "nm-logging.h" G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT) @@ -61,31 +62,6 @@ nm_vpn_manager_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_vpn_manager_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* The base device for the VPN connection is not active. */ - ENUM_ENTRY (NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "BaseDeviceNotActive"), - /* The requested VPN connection was invalid. */ - ENUM_ENTRY (NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* The VPN service required by this VPN connection did not exist or was invalid. */ - ENUM_ENTRY (NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "ServiceInvalid"), - /* The VPN service required by this VPN connection could not be started. */ - ENUM_ENTRY (NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, "ServiceStartFailed"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMVPNManagerError", values); - } - return etype; -} - static NMVPNService * get_service_by_namefile (NMVPNManager *self, const char *namefile) @@ -158,7 +134,7 @@ connection_vpn_state_changed (NMVPNConnection *connection, } } -NMVPNConnection * +NMActiveConnection * nm_vpn_manager_activate_connection (NMVPNManager *manager, NMConnection *connection, NMDevice *device, @@ -185,7 +161,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, return NULL; } - vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + vpn_setting = nm_connection_get_setting_vpn (connection); if (!vpn_setting) { g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, @@ -217,7 +193,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, manager); } - return vpn; + return (NMActiveConnection *) vpn; } gboolean @@ -243,7 +219,7 @@ nm_vpn_manager_deactivate_connection (NMVPNManager *self, NMVPNConnection *vpn = NM_VPN_CONNECTION (aiter->data); const char *vpn_path; - vpn_path = nm_vpn_connection_get_active_connection_path (vpn); + vpn_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (vpn)); if (!strcmp (path, vpn_path)) { nm_vpn_connection_disconnect (vpn, reason); success = TRUE; @@ -279,7 +255,7 @@ nm_vpn_manager_add_active_connections (NMVPNManager *self, const char *path; if (!filter || (nm_vpn_connection_get_connection (vpn) == filter)) { - path = nm_vpn_connection_get_active_connection_path (vpn); + path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (vpn)); g_ptr_array_add (array, g_strdup (path)); } } @@ -326,7 +302,7 @@ nm_vpn_manager_get_vpn_connection_for_active (NMVPNManager *manager, NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data); const char *ac_path; - ac_path = nm_vpn_connection_get_active_connection_path (vpn); + ac_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (vpn)); if (ac_path && !strcmp (ac_path, active_path)) return vpn; } diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index 78a5220b..cec370c8 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -35,14 +35,13 @@ typedef enum { - NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0, - NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, - NM_VPN_MANAGER_ERROR_SERVICE_INVALID, - NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, + NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0, /*< nick=BaseDeviceNotActive >*/ + NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_VPN_MANAGER_ERROR_SERVICE_INVALID, /*< nick=ServiceInvalid >*/ + NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, /*< nick=ServiceStartFailed >*/ } NMVPNManagerError; #define NM_VPN_MANAGER_ERROR (nm_vpn_manager_error_quark ()) -#define NM_TYPE_VPN_MANAGER_ERROR (nm_vpn_manager_error_get_type ()) GQuark nm_vpn_manager_error_quark (void); GType nm_vpn_manager_error_get_type (void); @@ -66,13 +65,13 @@ GType nm_vpn_manager_get_type (void); NMVPNManager *nm_vpn_manager_get (void); -NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager, - NMConnection *connection, - NMDevice *device, - const char *specific_object, - gboolean user_requested, - gulong user_uid, - GError **error); +NMActiveConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + gboolean user_requested, + gulong user_uid, + GError **error); gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, const char *path, diff --git a/src/wifi/Makefile.am b/src/wifi/Makefile.am new file mode 100644 index 00000000..c9a1b474 --- /dev/null +++ b/src/wifi/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = \ + -I${top_srcdir}/include \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src + +noinst_LTLIBRARIES = libwifi-utils.la + +libwifi_utils_la_SOURCES = \ + wifi-utils.c \ + wifi-utils.h \ + wifi-utils-private.h \ + wifi-utils-nl80211.c \ + wifi-utils-nl80211.h + +if WITH_WEXT +libwifi_utils_la_SOURCES += wifi-utils-wext.c wifi-utils-wext.h +endif + +libwifi_utils_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(LIBNL_CFLAGS) + +libwifi_utils_la_LIBADD = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(LIBNL_LIBS) + diff --git a/src/wifi/Makefile.in b/src/wifi/Makefile.in new file mode 100644 index 00000000..028469bf --- /dev/null +++ b/src/wifi/Makefile.in @@ -0,0 +1,665 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WITH_WEXT_TRUE@am__append_1 = wifi-utils-wext.c wifi-utils-wext.h +subdir = src/wifi +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libwifi_utils_la_DEPENDENCIES = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__libwifi_utils_la_SOURCES_DIST = wifi-utils.c wifi-utils.h \ + wifi-utils-private.h wifi-utils-nl80211.c wifi-utils-nl80211.h \ + wifi-utils-wext.c wifi-utils-wext.h +@WITH_WEXT_TRUE@am__objects_1 = libwifi_utils_la-wifi-utils-wext.lo +am_libwifi_utils_la_OBJECTS = libwifi_utils_la-wifi-utils.lo \ + libwifi_utils_la-wifi-utils-nl80211.lo $(am__objects_1) +libwifi_utils_la_OBJECTS = $(am_libwifi_utils_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libwifi_utils_la_SOURCES) +DIST_SOURCES = $(am__libwifi_utils_la_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +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@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ +LIBNL1_LIBS = @LIBNL1_LIBS@ +LIBNL2_CFLAGS = @LIBNL2_CFLAGS@ +LIBNL2_LIBS = @LIBNL2_LIBS@ +LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ +LIBNL3_LIBS = @LIBNL3_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ +LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I${top_srcdir}/include \ + -I${top_builddir}/include \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src + +noinst_LTLIBRARIES = libwifi-utils.la +libwifi_utils_la_SOURCES = wifi-utils.c wifi-utils.h \ + wifi-utils-private.h wifi-utils-nl80211.c wifi-utils-nl80211.h \ + $(am__append_1) +libwifi_utils_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(LIBNL_CFLAGS) + +libwifi_utils_la_LIBADD = \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(LIBNL_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/wifi/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/wifi/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libwifi-utils.la: $(libwifi_utils_la_OBJECTS) $(libwifi_utils_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libwifi_utils_la_OBJECTS) $(libwifi_utils_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwifi_utils_la-wifi-utils-nl80211.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwifi_utils_la-wifi-utils-wext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwifi_utils_la-wifi-utils.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libwifi_utils_la-wifi-utils.lo: wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwifi_utils_la-wifi-utils.lo -MD -MP -MF $(DEPDIR)/libwifi_utils_la-wifi-utils.Tpo -c -o libwifi_utils_la-wifi-utils.lo `test -f 'wifi-utils.c' || echo '$(srcdir)/'`wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwifi_utils_la-wifi-utils.Tpo $(DEPDIR)/libwifi_utils_la-wifi-utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wifi-utils.c' object='libwifi_utils_la-wifi-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwifi_utils_la-wifi-utils.lo `test -f 'wifi-utils.c' || echo '$(srcdir)/'`wifi-utils.c + +libwifi_utils_la-wifi-utils-nl80211.lo: wifi-utils-nl80211.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwifi_utils_la-wifi-utils-nl80211.lo -MD -MP -MF $(DEPDIR)/libwifi_utils_la-wifi-utils-nl80211.Tpo -c -o libwifi_utils_la-wifi-utils-nl80211.lo `test -f 'wifi-utils-nl80211.c' || echo '$(srcdir)/'`wifi-utils-nl80211.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwifi_utils_la-wifi-utils-nl80211.Tpo $(DEPDIR)/libwifi_utils_la-wifi-utils-nl80211.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wifi-utils-nl80211.c' object='libwifi_utils_la-wifi-utils-nl80211.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwifi_utils_la-wifi-utils-nl80211.lo `test -f 'wifi-utils-nl80211.c' || echo '$(srcdir)/'`wifi-utils-nl80211.c + +libwifi_utils_la-wifi-utils-wext.lo: wifi-utils-wext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwifi_utils_la-wifi-utils-wext.lo -MD -MP -MF $(DEPDIR)/libwifi_utils_la-wifi-utils-wext.Tpo -c -o libwifi_utils_la-wifi-utils-wext.lo `test -f 'wifi-utils-wext.c' || echo '$(srcdir)/'`wifi-utils-wext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwifi_utils_la-wifi-utils-wext.Tpo $(DEPDIR)/libwifi_utils_la-wifi-utils-wext.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wifi-utils-wext.c' object='libwifi_utils_la-wifi-utils-wext.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwifi_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwifi_utils_la-wifi-utils-wext.lo `test -f 'wifi-utils-wext.c' || echo '$(srcdir)/'`wifi-utils-wext.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/wifi/wifi-utils-nl80211.c b/src/wifi/wifi-utils-nl80211.c new file mode 100644 index 00000000..4a4e661e --- /dev/null +++ b/src/wifi/wifi-utils-nl80211.c @@ -0,0 +1,819 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + * Copyright (C) 2011 Intel Corporation. All rights reserved. + */ + +#include <config.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> +#include <net/ethernet.h> +#include <unistd.h> +#include <math.h> + +#include <glib.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> + +#include <linux/nl80211.h> + +#include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" +#include "nm-logging.h" +#include "nm-utils.h" +#include "nm-netlink-compat.h" + +typedef struct { + WifiData parent; + struct nl_sock *nl_sock; + int id; + struct nl_cb *nl_cb; + guint32 *freqs; + int num_freqs; +} WifiDataNl80211; + +static int ack_handler (struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_STOP; +} + +static int finish_handler (struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_SKIP; +} + +static int error_handler (struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *done = arg; + *done = err->error; + return NL_SKIP; +} + +static struct nl_msg * +_nl80211_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags) +{ + struct nl_msg *msg; + + msg = nlmsg_alloc (); + if (msg) { + genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0); + NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, ifindex); + } + return msg; + + nla_put_failure: + nlmsg_free (msg); + return NULL; +} + +static struct nl_msg * +nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags) +{ + return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, cmd, flags); +} + +/* NOTE: this function consumes 'msg' */ +static int +_nl80211_send_and_recv (struct nl_sock *nl_sock, + struct nl_cb *nl_cb, + struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + struct nl_cb *cb; + int err, done; + + g_return_val_if_fail (msg != NULL, -ENOMEM); + g_return_val_if_fail (valid_handler != NULL, -EINVAL); + + cb = nl_cb_clone (nl_cb); + if (!cb) { + err = -ENOMEM; + goto out; + } + + err = nl_send_auto_complete (nl_sock, msg); + if (err < 0) + goto out; + + done = 0; + nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done); + nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done); + nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); + nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data); + + /* Loop until one of our NL callbacks says we're done; on success + * done will be 1, on error it will be < 0. + */ + while (!done) { + err = nl_recvmsgs (nl_sock, cb); + if (err && err != -NLE_AGAIN) { + nm_log_warn (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s", + err, nl_geterror (err)); + break; + } + } + if (err == 0 && done < 0) + err = done; + + out: + nl_cb_put (cb); + nlmsg_free (msg); + return err; +} + +static int +nl80211_send_and_recv (WifiDataNl80211 *nl80211, + struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + return _nl80211_send_and_recv (nl80211->nl_sock, nl80211->nl_cb, msg, valid_handler, valid_data); +} + +static void +wifi_nl80211_deinit (WifiData *parent) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) parent; + + if (nl80211->nl_sock) + nl_socket_free (nl80211->nl_sock); + if (nl80211->nl_cb) + nl_cb_put (nl80211->nl_cb); +} + +struct nl80211_iface_info { + NM80211Mode mode; +}; + +static int nl80211_iface_info_handler (struct nl_msg *msg, void *arg) +{ + struct nl80211_iface_info *info = arg; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (!tb[NL80211_ATTR_IFTYPE]) + return NL_SKIP; + + switch (nla_get_u32 (tb[NL80211_ATTR_IFTYPE])) { + case NL80211_IFTYPE_ADHOC: + info->mode = NM_802_11_MODE_ADHOC; + break; + case NL80211_IFTYPE_STATION: + info->mode = NM_802_11_MODE_INFRA; + break; + } + + return NL_SKIP; +} + +static NM80211Mode +wifi_nl80211_get_mode (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + struct nl80211_iface_info iface_info = { + .mode = NM_802_11_MODE_UNKNOWN, + }; + struct nl_msg *msg; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_INTERFACE, 0); + + if (nl80211_send_and_recv (nl80211, msg, nl80211_iface_info_handler, + &iface_info) < 0) + return NM_802_11_MODE_UNKNOWN; + + return iface_info.mode; +} + +static gboolean +wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) +{ + /* + * Used only to set mode for scanning as some old cards + * don't properly scan in IBSS mode, nl80211 cards are + * expected to scan properly so ignore this. + */ + return TRUE; +} + +/* @divisor: pass what value @xbm should be divided by to get dBm */ +static guint32 nl80211_xbm_to_percent (gint32 xbm, guint32 divisor) +{ +#define NOISE_FLOOR_DBM -90 +#define SIGNAL_MAX_DBM -20 + + xbm /= divisor; + xbm = CLAMP(xbm, NOISE_FLOOR_DBM, SIGNAL_MAX_DBM); + + return 100 - 70 * (((float) SIGNAL_MAX_DBM - (float) xbm) / + ((float) SIGNAL_MAX_DBM - (float) NOISE_FLOOR_DBM)); +} + +struct nl80211_bss_info { + guint32 freq; + guint8 bssid[ETH_ALEN]; + guint8 ssid[32]; + guint32 ssid_len; + guint32 beacon_signal; + gboolean valid; +}; + +#define WLAN_EID_SSID 0 + +static void find_ssid (guint8 *ies, guint32 ies_len, + guint8 **ssid, guint32 *ssid_len) +{ + *ssid = NULL; + *ssid_len = 0; + + while (ies_len > 2 && ies[0] != WLAN_EID_SSID) { + ies_len -= ies[1] + 2; + ies += ies[1] + 2; + } + if (ies_len < 2) + return; + if (ies_len < 2 + ies[1]) + return; + + *ssid_len = ies[1]; + *ssid = ies + 2; +} + +static int nl80211_bss_dump_handler (struct nl_msg *msg, void *arg) +{ + struct nl80211_bss_info *info = arg; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct nlattr *bss[NL80211_BSS_MAX + 1]; + static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { + [NL80211_BSS_TSF] = { .type = NLA_U64 }, + [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_BSS_BSSID] = { }, + [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, + [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, + [NL80211_BSS_INFORMATION_ELEMENTS] = { }, + [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, + [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, + [NL80211_BSS_STATUS] = { .type = NLA_U32 }, + }; + guint32 status; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_BSS] == NULL) + return NL_SKIP; + + if (nla_parse_nested (bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) + return NL_SKIP; + + if (bss[NL80211_BSS_STATUS] == NULL) + return NL_SKIP; + + status = nla_get_u32 (bss[NL80211_BSS_STATUS]); + + if (status != NL80211_BSS_STATUS_ASSOCIATED && + status != NL80211_BSS_STATUS_IBSS_JOINED) + return NL_SKIP; + + if (bss[NL80211_BSS_BSSID] == NULL) + return NL_SKIP; + memcpy(info->bssid, nla_data (bss[NL80211_BSS_BSSID]), ETH_ALEN); + + if (bss[NL80211_BSS_FREQUENCY]) + info->freq = nla_get_u32 (bss[NL80211_BSS_FREQUENCY]); + + if (bss[NL80211_BSS_SIGNAL_UNSPEC]) + info->beacon_signal = + nla_get_u8 (bss[NL80211_BSS_SIGNAL_UNSPEC]); + + if (bss[NL80211_BSS_SIGNAL_MBM]) + info->beacon_signal = + nl80211_xbm_to_percent (nla_get_u32 (bss[NL80211_BSS_SIGNAL_MBM]), 100); + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) { + guint8 *ssid; + guint32 ssid_len; + + find_ssid(nla_data (bss[NL80211_BSS_INFORMATION_ELEMENTS]), + nla_len (bss[NL80211_BSS_INFORMATION_ELEMENTS]), + &ssid, &ssid_len); + if (ssid && ssid_len && ssid_len <= sizeof(info->ssid)) { + memcpy (info->ssid, ssid, ssid_len); + info->ssid_len = ssid_len; + } + } + + info->valid = TRUE; + + return NL_SKIP; +} + +static void nl80211_get_bss_info (WifiDataNl80211 *nl80211, + struct nl80211_bss_info *bss_info) +{ + struct nl_msg *msg; + + memset(bss_info, 0, sizeof(*bss_info)); + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_SCAN, NLM_F_DUMP); + + nl80211_send_and_recv (nl80211, msg, nl80211_bss_dump_handler, bss_info); +} + +static guint32 +wifi_nl80211_get_freq (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + struct nl80211_bss_info bss_info; + + nl80211_get_bss_info (nl80211, &bss_info); + + return bss_info.freq; +} + +static guint32 +wifi_nl80211_find_freq (WifiData *data, const guint32 *freqs) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + int i; + + for (i = 0; i < nl80211->num_freqs; i++) { + while (*freqs) { + if (nl80211->freqs[i] == *freqs) + return *freqs; + freqs++; + } + } + return 0; +} + +static GByteArray * +wifi_nl80211_get_ssid (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + GByteArray *array = NULL; + struct nl80211_bss_info bss_info; + + nl80211_get_bss_info (nl80211, &bss_info); + + if (bss_info.valid) { + array = g_byte_array_sized_new (bss_info.ssid_len); + g_byte_array_append (array, (const guint8 *) bss_info.ssid, + bss_info.ssid_len); + } + + return array; +} + +static gboolean +wifi_nl80211_get_bssid (WifiData *data, struct ether_addr *out_bssid) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + struct nl80211_bss_info bss_info; + + nl80211_get_bss_info (nl80211, &bss_info); + + if (bss_info.valid) + memcpy(out_bssid, bss_info.bssid, ETH_ALEN); + + return bss_info.valid; +} + +struct nl80211_station_info { + guint32 txrate; + gboolean txrate_valid; + guint8 signal; + gboolean signal_valid; +}; + +static int nl80211_station_handler (struct nl_msg *msg, void *arg) +{ + struct nl80211_station_info *info = arg; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; + struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 }, + [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 }, + [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 }, + [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 }, + [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 }, + [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 }, + [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_LLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 }, + }; + + static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { + [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, + [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, + }; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_STA_INFO] == NULL) + return NL_SKIP; + + if (nla_parse_nested (sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) + return NL_SKIP; + + if (sinfo[NL80211_STA_INFO_TX_BITRATE] == NULL) + return NL_SKIP; + + if (nla_parse_nested (rinfo, NL80211_RATE_INFO_MAX, + sinfo[NL80211_STA_INFO_TX_BITRATE], + rate_policy)) + return NL_SKIP; + + if (rinfo[NL80211_RATE_INFO_BITRATE] == NULL) + return NL_SKIP; + + /* convert from nl80211's units of 100kbps to NM's kbps */ + info->txrate = nla_get_u16 (rinfo[NL80211_RATE_INFO_BITRATE]) * 100; + info->txrate_valid = TRUE; + + if (sinfo[NL80211_STA_INFO_SIGNAL] != NULL) { + info->signal = nl80211_xbm_to_percent ((gint8) nla_get_u8 (sinfo[NL80211_STA_INFO_SIGNAL]), 1); + info->signal_valid = TRUE; + } + + return NL_SKIP; +} + +static void nl80211_get_ap_info (WifiDataNl80211 *nl80211, + struct nl80211_station_info *sta_info) +{ + struct nl_msg *msg; + struct nl80211_bss_info bss_info; + + memset(sta_info, 0, sizeof(*sta_info)); + + nl80211_get_bss_info (nl80211, &bss_info); + if (!bss_info.valid) + return; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_STATION, 0); + if (msg) { + NLA_PUT (msg, NL80211_ATTR_MAC, ETH_ALEN, bss_info.bssid); + + nl80211_send_and_recv (nl80211, msg, nl80211_station_handler, sta_info); + if (!sta_info->signal_valid) { + /* Fall back to bss_info signal quality (both are in percent) */ + sta_info->signal = bss_info.beacon_signal; + } + } + + return; + + nla_put_failure: + nlmsg_free (msg); + return; +} + +static guint32 +wifi_nl80211_get_rate (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + struct nl80211_station_info sta_info; + + nl80211_get_ap_info (nl80211, &sta_info); + + return sta_info.txrate; +} + +static int +wifi_nl80211_get_qual (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + struct nl80211_station_info sta_info; + + nl80211_get_ap_info (nl80211, &sta_info); + return sta_info.signal; +} + +struct nl80211_device_info { + guint32 *freqs; + int num_freqs; + guint32 caps; + gboolean can_scan, can_scan_ssid; + gboolean success; +}; + +static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nl80211_device_info *info = arg; + struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + struct nlattr *nl_band; + struct nlattr *nl_freq; + int rem_freq; + int rem_band; + int freq_idx; + static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 }, + }; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_WIPHY_BANDS] == NULL) + return NL_SKIP; + + if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) { + info->can_scan_ssid = + nla_get_u8 (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0; + } else { + /* old kernel that only had mac80211, so assume it can */ + info->can_scan_ssid = TRUE; + } + + if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) { + struct nlattr *nl_cmd; + int i; + + nla_for_each_nested (nl_cmd, + tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) { + guint32 cmd = nla_get_u32 (nl_cmd); + if (cmd == NL80211_CMD_TRIGGER_SCAN) + info->can_scan = TRUE; + } + } + + info->num_freqs = 0; + + nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (nla_parse_nested (tb_band, NL80211_BAND_ATTR_MAX, nl_band, + NULL) < 0) + return NL_SKIP; + + nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], + rem_freq) { + nla_parse_nested (tb_freq, NL80211_FREQUENCY_ATTR_MAX, + nl_freq, freq_policy); + + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + + info->num_freqs++; + } + } + + info->freqs = g_malloc0 (sizeof(guint32) * info->num_freqs); + + freq_idx = 0; + nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (nla_parse_nested (tb_band, NL80211_BAND_ATTR_MAX, nl_band, + NULL) < 0) + return NL_SKIP; + + nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], + rem_freq) { + nla_parse_nested (tb_freq, NL80211_FREQUENCY_ATTR_MAX, + nl_freq, freq_policy); + + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + + info->freqs[freq_idx] = + nla_get_u32 (tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + freq_idx++; + } + } + + if (tb[NL80211_ATTR_CIPHER_SUITES]) { + int num; + int i; + __u32 *ciphers = nla_data (tb[NL80211_ATTR_CIPHER_SUITES]); + + num = nla_len (tb[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32); + for (i = 0; i < num; i++) { + switch (ciphers[i]) { + case 0x000fac01: + info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40; + break; + case 0x000fac05: + info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP104; + break; + case 0x000fac02: + info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP | + NM_WIFI_DEVICE_CAP_WPA; + break; + case 0x000fac04: + info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP | + NM_WIFI_DEVICE_CAP_RSN; + break; + } + } + } + + if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) { + struct nlattr *nl_mode; + int i; + + nla_for_each_nested (nl_mode, tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) { + if (nla_type (nl_mode) == NL80211_IFTYPE_AP) { + info->caps |= NM_WIFI_DEVICE_CAP_AP; + break; + } + } + } + + info->success = TRUE; + + return NL_SKIP; +} + +WifiData * +wifi_nl80211_init (const char *iface, int ifindex) +{ + WifiDataNl80211 *nl80211; + struct nl_msg *msg; + struct nl80211_device_info device_info = {}; + + nl80211 = wifi_data_new (iface, ifindex, sizeof (*nl80211)); + nl80211->parent.get_mode = wifi_nl80211_get_mode; + nl80211->parent.set_mode = wifi_nl80211_set_mode; + nl80211->parent.get_freq = wifi_nl80211_get_freq; + nl80211->parent.find_freq = wifi_nl80211_find_freq; + nl80211->parent.get_ssid = wifi_nl80211_get_ssid; + nl80211->parent.get_bssid = wifi_nl80211_get_bssid; + nl80211->parent.get_rate = wifi_nl80211_get_rate; + nl80211->parent.get_qual = wifi_nl80211_get_qual; + nl80211->parent.deinit = wifi_nl80211_deinit; + + nl80211->nl_sock = nl_socket_alloc (); + if (nl80211->nl_sock == NULL) + goto error; + + if (genl_connect (nl80211->nl_sock)) + goto error; + + nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); + if (nl80211->id < 0) + goto error; + + nl80211->nl_cb = nl_cb_alloc (NL_CB_DEFAULT); + if (nl80211->nl_cb == NULL) + goto error; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WIPHY, 0); + + if (nl80211_send_and_recv (nl80211, msg, nl80211_wiphy_info_handler, + &device_info) < 0) { + nm_log_dbg (LOGD_HW | LOGD_WIFI, + "(%s): NL80211_CMD_GET_WIPHY request failed", + nl80211->parent.iface); + goto error; + } + + if (!device_info.success) { + nm_log_dbg (LOGD_HW | LOGD_WIFI, + "(%s): NL80211_CMD_GET_WIPHY request indicated failure", + nl80211->parent.iface); + goto error; + } + + if (!device_info.can_scan_ssid) { + nm_log_err (LOGD_HW | LOGD_WIFI, + "(%s): driver does not support SSID scans", + nl80211->parent.iface); + goto error; + } + + if (device_info.num_freqs == 0 || device_info.freqs == NULL) { + nm_log_err (LOGD_HW | LOGD_WIFI, + "(%s): driver reports no supported frequencies", + nl80211->parent.iface); + goto error; + } + + nl80211->freqs = device_info.freqs; + nl80211->num_freqs = device_info.num_freqs; + nl80211->parent.can_scan_ssid = device_info.can_scan_ssid; + nl80211->parent.caps = device_info.caps; + + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): using nl80211 for WiFi device control", + nl80211->parent.iface); + + return (WifiData *) nl80211; + +error: + wifi_utils_deinit ((WifiData *) nl80211); + return NULL; +} + +static int +iface_to_index (struct nl_sock *nl_sock, const char *iface) +{ + struct nl_cache *link_cache = NULL; + int err, ifindex; + + /* name to index */ + err = rtnl_link_alloc_cache (nl_sock, &link_cache); + if (err < 0) { + nm_log_warn (LOGD_HW, "failed to allocate link cache: (%d) %s", + err, nl_geterror (err)); + return -1; + } + nl_cache_mngt_provide (link_cache); + nl_cache_refill (nl_sock, link_cache); + ifindex = rtnl_link_name2i (link_cache, iface); + nl_cache_free (link_cache); + + return ifindex; +} + +gboolean +wifi_nl80211_is_wifi (const char *iface) +{ + struct nl_sock *nl_sock; + struct nl_cb *nl_cb = NULL; + struct nl_msg *msg = NULL; + int id, ifindex; + struct nl80211_iface_info iface_info = { + .mode = NM_802_11_MODE_UNKNOWN, + }; + gboolean is_wifi = FALSE; + + nl_sock = nl_socket_alloc (); + if (nl_sock == NULL) + return FALSE; + + if (genl_connect (nl_sock)) + goto error; + + ifindex = iface_to_index (nl_sock, iface); + if (ifindex < 0) + goto error; + + id = genl_ctrl_resolve (nl_sock, "nl80211"); + if (id < 0) + goto error; + + nl_cb = nl_cb_alloc (NL_CB_DEFAULT); + if (nl_cb) { + msg = _nl80211_alloc_msg (id, ifindex, NL80211_CMD_GET_INTERFACE, 0); + if (_nl80211_send_and_recv (nl_sock, + nl_cb, + msg, + nl80211_iface_info_handler, + &iface_info) >= 0) + is_wifi = (iface_info.mode != NM_802_11_MODE_UNKNOWN); + } + + error: + if (nl_cb) + nl_cb_put (nl_cb); + nl_socket_free (nl_sock); + return is_wifi; +} + diff --git a/src/wifi/wifi-utils-nl80211.h b/src/wifi/wifi-utils-nl80211.h new file mode 100644 index 00000000..2a7fe874 --- /dev/null +++ b/src/wifi/wifi-utils-nl80211.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Intel Corporation. All rights reserved. + */ + +#ifndef WIFI_UTILS_NL80211_H +#define WIFI_UTILS_NL80211_H + +#include "wifi-utils.h" + +WifiData *wifi_nl80211_init (const char *iface, int ifindex); + +gboolean wifi_nl80211_is_wifi (const char *iface); + +#endif /* WIFI_UTILS_NL80211_H */ diff --git a/src/wifi/wifi-utils-private.h b/src/wifi/wifi-utils-private.h new file mode 100644 index 00000000..83075090 --- /dev/null +++ b/src/wifi/wifi-utils-private.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef WIFI_UTILS_PRIVATE_H +#define WIFI_UTILS_PRIVATE_H + +#include <glib.h> + +#include "NetworkManager.h" +#include "wifi-utils.h" + +struct WifiData { + char *iface; + int ifindex; + NMDeviceWifiCapabilities caps; + gboolean can_scan_ssid; + + NM80211Mode (*get_mode) (WifiData *data); + + gboolean (*set_mode) (WifiData *data, const NM80211Mode mode); + + /* Return current frequency in MHz (really associated BSS frequency) */ + guint32 (*get_freq) (WifiData *data); + + /* Return first supported frequency in the zero-terminated list */ + guint32 (*find_freq) (WifiData *data, const guint32 *freqs); + + /* If SSID is empty/blank (zero-length or all \0s) return NULL */ + GByteArray * (*get_ssid) (WifiData *data); + + /* Return current bitrate in Kbps */ + guint32 (*get_rate) (WifiData *data); + + gboolean (*get_bssid) (WifiData *data, struct ether_addr *out_bssid); + + /* Return a signal strength percentage 0 - 100% for the current BSSID; + * return -1 on errors or if not associated. + */ + int (*get_qual) (WifiData *data); + + void (*deinit) (WifiData *data); + + /* OLPC Mesh-only functions */ + + guint32 (*get_mesh_channel) (WifiData *data); + + /* channel == 0 means "auto channel" */ + gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); + + /* ssid == NULL means "auto SSID" */ + gboolean (*set_mesh_ssid) (WifiData *data, const GByteArray *ssid); +}; + +gpointer wifi_data_new (const char *iface, int ifindex, gsize len); +void wifi_data_free (WifiData *data); + +#endif /* WIFI_UTILS_PRIVATE_H */ diff --git a/src/wifi/wifi-utils-wext.c b/src/wifi/wifi-utils-wext.c new file mode 100644 index 00000000..75d00f41 --- /dev/null +++ b/src/wifi/wifi-utils-wext.c @@ -0,0 +1,663 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include <config.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> +#include <net/ethernet.h> +#include <unistd.h> +#include <math.h> + +#include <glib.h> + +#include "wifi-utils-private.h" +#include "wifi-utils-wext.h" +#include "nm-logging.h" +#include "nm-utils.h" + +/* Hacks necessary to #include wireless.h; yay for WEXT */ +#ifndef __user +#define __user +#endif +#include <sys/types.h> +#include <linux/types.h> +#include <sys/socket.h> +#include <linux/if.h> +#include <linux/wireless.h> + + +typedef struct { + WifiData parent; + int fd; + struct iw_quality max_qual; + gint8 num_freqs; + guint32 freqs[IW_MAX_FREQUENCIES]; +} WifiDataWext; + +/* Until a new wireless-tools comes out that has the defs and the structure, + * need to copy them here. + */ +/* Scan capability flags - in (struct iw_range *)->scan_capa */ +#define NM_IW_SCAN_CAPA_NONE 0x00 +#define NM_IW_SCAN_CAPA_ESSID 0x01 + +struct iw_range_with_scan_capa +{ + guint32 throughput; + guint32 min_nwid; + guint32 max_nwid; + guint16 old_num_channels; + guint8 old_num_frequency; + + guint8 scan_capa; +/* don't need the rest... */ +}; + +static guint32 +iw_freq_to_uint32 (struct iw_freq *freq) +{ + if (freq->e == 0) { + /* Some drivers report channel not frequency. Convert to a + * frequency; but this assumes that the device is in b/g mode. + */ + if ((freq->m >= 1) && (freq->m <= 13)) + return 2407 + (5 * freq->m); + else if (freq->m == 14) + return 2484; + } + + return (guint32) (((double) freq->m) * pow (10, freq->e) / 1000000); +} + +static void +wifi_wext_deinit (WifiData *parent) +{ + WifiDataWext *wext = (WifiDataWext *) parent; + + if (wext->fd >= 0) + close (wext->fd); +} + +static NM80211Mode +wifi_wext_get_mode (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + + if (ioctl (wext->fd, SIOCGIWMODE, &wrq) < 0) { + if (errno != ENODEV) { + nm_log_warn (LOGD_HW | LOGD_WIFI, + "(%s): error %d getting card mode", + wext->parent.iface, errno); + } + return NM_802_11_MODE_UNKNOWN; + } + + switch (wrq.u.mode) { + case IW_MODE_ADHOC: + return NM_802_11_MODE_ADHOC; + case IW_MODE_INFRA: + return NM_802_11_MODE_INFRA; + default: + break; + } + return NM_802_11_MODE_UNKNOWN; +} + +static gboolean +wifi_wext_set_mode (WifiData *data, const NM80211Mode mode) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + if (wifi_wext_get_mode (data) == mode) + return TRUE; + + memset (&wrq, 0, sizeof (struct iwreq)); + switch (mode) { + case NM_802_11_MODE_ADHOC: + wrq.u.mode = IW_MODE_ADHOC; + break; + case NM_802_11_MODE_INFRA: + wrq.u.mode = IW_MODE_INFRA; + break; + default: + g_warn_if_reached (); + return FALSE; + } + + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCSIWMODE, &wrq) < 0) { + if (errno != ENODEV) { + nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting mode %d", + wext->parent.iface, mode); + } + return FALSE; + } + + return TRUE; +} + +static guint32 +wifi_wext_get_freq (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCGIWFREQ, &wrq) < 0) { + nm_log_warn (LOGD_HW | LOGD_WIFI, + "(%s): error getting frequency: %s", + wext->parent.iface, strerror (errno)); + return 0; + } + + return iw_freq_to_uint32 (&wrq.u.freq); +} + +static guint32 +wifi_wext_find_freq (WifiData *data, const guint32 *freqs) +{ + WifiDataWext *wext = (WifiDataWext *) data; + int i; + + for (i = 0; i < wext->num_freqs; i++) { + while (*freqs) { + if (wext->freqs[i] == *freqs) + return *freqs; + freqs++; + } + } + return 0; +} + +static GByteArray * +wifi_wext_get_ssid (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + char ssid[IW_ESSID_MAX_SIZE + 2]; + guint32 len; + GByteArray *array = NULL; + + memset (ssid, 0, sizeof (ssid)); + wrq.u.essid.pointer = (caddr_t) &ssid; + wrq.u.essid.length = sizeof (ssid); + wrq.u.essid.flags = 0; + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + + if (ioctl (wext->fd, SIOCGIWESSID, &wrq) < 0) { + nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): couldn't get SSID: %d", + wext->parent.iface, errno); + return NULL; + } + + len = wrq.u.essid.length; + if (nm_utils_is_empty_ssid ((guint8 *) ssid, len) == FALSE) { + array = g_byte_array_sized_new (len); + g_byte_array_append (array, (const guint8 *) ssid, len); + } + + return array; +} + +static gboolean +wifi_wext_get_bssid (WifiData *data, struct ether_addr *out_bssid) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (wrq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCGIWAP, &wrq) < 0) { + nm_log_warn (LOGD_HW | LOGD_WIFI, + "(%s): error getting associated BSSID: %s", + wext->parent.iface, strerror (errno)); + return FALSE; + } + memcpy (out_bssid->ether_addr_octet, &(wrq.u.ap_addr.sa_data), ETH_ALEN); + return TRUE; +} + +static guint32 +wifi_wext_get_rate (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + int err; + + memset (&wrq, 0, sizeof (wrq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + err = ioctl (wext->fd, SIOCGIWRATE, &wrq); + return ((err == 0) ? wrq.u.bitrate.value / 1000 : 0); +} + +static int +wext_qual_to_percent (const struct iw_quality *qual, + const struct iw_quality *max_qual) +{ + int percent = -1; + int level_percent = -1; + + g_return_val_if_fail (qual != NULL, -1); + g_return_val_if_fail (max_qual != NULL, -1); + + /* Magically convert the many different WEXT quality representations to a percentage */ + + nm_log_dbg (LOGD_WIFI, + "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X", + (__s8) qual->qual, qual->qual, qual->qual, + (__s8) qual->level, qual->level, qual->level, + (__s8) qual->noise, qual->noise, qual->noise, + qual->updated, + (__s8) max_qual->qual, max_qual->qual, max_qual->qual, + (__s8) max_qual->level, max_qual->level, max_qual->level, + (__s8) max_qual->noise, max_qual->noise, max_qual->noise, + max_qual->updated); + + /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is. + * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be + * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers + * are free to use whatever they want to calculate "Link Quality". + */ + if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID)) + percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual)); + + /* If the driver doesn't specify a complete and valid quality, we have two options: + * + * 1) dBm: driver must specify max_qual->level = 0, and have valid values for + * qual->level and (qual->noise OR max_qual->noise) + * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for + * qual->level and max_qual->level + * + * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise, + * If drivers don't conform to it, they are wrong and need to be fixed. + */ + + if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */ + && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */ + || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */ + ) { + /* Absolute power values (dBm) */ + + /* Reasonable fallbacks for dumb drivers that don't specify either level. */ + #define FALLBACK_NOISE_FLOOR_DBM -90 + #define FALLBACK_SIGNAL_MAX_DBM -20 + int max_level = FALLBACK_SIGNAL_MAX_DBM; + int noise = FALLBACK_NOISE_FLOOR_DBM; + int level = qual->level - 0x100; + + level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + + if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID)) + noise = qual->noise - 0x100; + else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) + noise = max_qual->noise - 0x100; + noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + + /* A sort of signal-to-noise ratio calculation */ + level_percent = (int)(100 - 70 *( + ((double)max_level - (double)level) / + ((double)max_level - (double)noise))); + nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", + level_percent, max_level, level, noise); + } else if ( (max_qual->level != 0) + && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID)) { + /* Relative power values (RSSI) */ + + int level = qual->level; + + /* Signal level is relavtive (0 -> max_qual->level) */ + level = CLAMP (level, 0, max_qual->level); + level_percent = (int)(100 * ((double)level / (double)max_qual->level)); + nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.", + level_percent, max_qual->level, level); + } else if (percent == -1) { + nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy."); + } + + /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */ + if ((percent < 1) && (level_percent >= 0)) + percent = level_percent; + + nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).", + percent, CLAMP (percent, 0, 100)); + return (CLAMP (percent, 0, 100)); +} + +static int +wifi_wext_get_qual (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + struct iw_statistics stats; + + memset (&stats, 0, sizeof (stats)); + wrq.u.data.pointer = &stats; + wrq.u.data.length = sizeof (stats); + wrq.u.data.flags = 1; /* Clear updated flag */ + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + + if (ioctl (wext->fd, SIOCGIWSTATS, &wrq) < 0) { + nm_log_warn (LOGD_HW | LOGD_WIFI, + "(%s): error getting signal strength: %s", + wext->parent.iface, strerror (errno)); + return -1; + } + + return wext_qual_to_percent (&stats.qual, &wext->max_qual); +} + +/*********************/ +/* OLPC Mesh-only functions */ + +static guint32 +wifi_wext_get_mesh_channel (WifiData *data) +{ + WifiDataWext *wext = (WifiDataWext *) data; + guint32 freq; + int i; + + freq = wifi_utils_get_freq (data); + for (i = 0; i < wext->num_freqs; i++) { + if (freq == wext->freqs[i]) + return i + 1; + } + return 0; +} + +static gboolean +wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + + if (channel > 0) { + wrq.u.freq.flags = IW_FREQ_FIXED; + wrq.u.freq.e = 0; + wrq.u.freq.m = channel; + } + + if (ioctl (wext->fd, SIOCSIWFREQ, &wrq) < 0) { + nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC_MESH, + "(%s): error setting channel to %d: %s", + wext->parent.iface, channel, strerror (errno)); + return FALSE; + } + + return TRUE; +} + +static gboolean +wifi_wext_set_mesh_ssid (WifiData *data, const GByteArray *ssid) +{ + WifiDataWext *wext = (WifiDataWext *) data; + struct iwreq wrq; + guint32 len = 0; + char buf[IW_ESSID_MAX_SIZE + 1]; + + memset (buf, 0, sizeof (buf)); + if (ssid) { + len = ssid->len; + memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len)); + } + wrq.u.essid.pointer = (caddr_t) buf; + wrq.u.essid.length = len; + wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */ + + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCSIWESSID, &wrq) == 0) + return TRUE; + + if (errno != ENODEV) { + nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC_MESH, + "(%s): error setting SSID to '%s': %s", + wext->parent.iface, + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(null)", + strerror (errno)); + } + + return FALSE; +} + +/*********************/ + +static gboolean +wext_can_scan (WifiDataWext *wext) +{ + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + if (ioctl (wext->fd, SIOCSIWSCAN, &wrq) < 0) { + if (errno == EOPNOTSUPP) + return FALSE; + } + return TRUE; +} + +static gboolean +wext_get_range (WifiDataWext *wext, + struct iw_range *range, + guint32 *response_len) +{ + int i = 26; + gboolean success = FALSE; + struct iwreq wrq; + + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, wext->parent.iface, IFNAMSIZ); + wrq.u.data.pointer = (caddr_t) range; + wrq.u.data.length = sizeof (struct iw_range); + + /* Need to give some drivers time to recover after suspend/resume + * (ex ipw3945 takes a few seconds to talk to its regulatory daemon; + * see rh bz#362421) + */ + while (i-- > 0) { + if (ioctl (wext->fd, SIOCGIWRANGE, &wrq) == 0) { + if (response_len) + *response_len = wrq.u.data.length; + success = TRUE; + break; + } else if (errno != EAGAIN) { + nm_log_err (LOGD_HW | LOGD_WIFI, + "(%s): couldn't get driver range information (%d).", + wext->parent.iface, errno); + break; + } + + g_usleep (G_USEC_PER_SEC / 4); + } + + if (i <= 0) { + nm_log_warn (LOGD_HW | LOGD_WIFI, + "(%s): driver took too long to respond to IWRANGE query.", + wext->parent.iface); + } + + return success; +} + +#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \ + NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \ + NM_WIFI_DEVICE_CAP_WPA | \ + NM_WIFI_DEVICE_CAP_RSN) + +static guint32 +wext_get_caps (WifiDataWext *wext, struct iw_range *range) +{ + guint32 caps = NM_WIFI_DEVICE_CAP_NONE; + + g_return_val_if_fail (wext != NULL, NM_WIFI_DEVICE_CAP_NONE); + g_return_val_if_fail (range != NULL, NM_WIFI_DEVICE_CAP_NONE); + + /* All drivers should support WEP by default */ + caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104; + + if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) + caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP; + + if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) + caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP; + + if (range->enc_capa & IW_ENC_CAPA_WPA) + caps |= NM_WIFI_DEVICE_CAP_WPA; + + if (range->enc_capa & IW_ENC_CAPA_WPA2) + caps |= NM_WIFI_DEVICE_CAP_RSN; + + /* Check for cipher support but not WPA support */ + if ( (caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + && !(caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))) { + nm_log_warn (LOGD_WIFI, "%s: device supports WPA ciphers but not WPA protocol; " + "WPA unavailable.", wext->parent.iface); + caps &= ~WPA_CAPS; + } + + /* Check for WPA support but not cipher support */ + if ( (caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN)) + && !(caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))) { + nm_log_warn (LOGD_WIFI, "%s: device supports WPA protocol but not WPA ciphers; " + "WPA unavailable.", wext->parent.iface); + caps &= ~WPA_CAPS; + } + + return caps; +} + +WifiData * +wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) +{ + WifiDataWext *wext; + struct iw_range range; + guint32 response_len = 0; + struct iw_range_with_scan_capa *scan_capa_range; + int i; + + wext = wifi_data_new (iface, ifindex, sizeof (*wext)); + wext->parent.get_mode = wifi_wext_get_mode; + wext->parent.set_mode = wifi_wext_set_mode; + wext->parent.get_freq = wifi_wext_get_freq; + wext->parent.find_freq = wifi_wext_find_freq; + wext->parent.get_ssid = wifi_wext_get_ssid; + wext->parent.get_bssid = wifi_wext_get_bssid; + wext->parent.get_rate = wifi_wext_get_rate; + wext->parent.get_qual = wifi_wext_get_qual; + wext->parent.deinit = wifi_wext_deinit; + wext->parent.get_mesh_channel = wifi_wext_get_mesh_channel; + wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel; + wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid; + + wext->fd = socket (PF_INET, SOCK_DGRAM, 0); + if (wext->fd < 0) + goto error; + + memset (&range, 0, sizeof (struct iw_range)); + if (wext_get_range (wext, &range, &response_len) == FALSE) { + nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed", + wext->parent.iface); + goto error; + } + + if ((response_len < 300) || (range.we_version_compiled < 21)) { + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): driver WEXT version too old (got %d, expected >= 21)", + wext->parent.iface, + range.we_version_compiled); + goto error; + } + + wext->max_qual.qual = range.max_qual.qual; + wext->max_qual.level = range.max_qual.level; + wext->max_qual.noise = range.max_qual.noise; + wext->max_qual.updated = range.max_qual.updated; + + wext->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); + for (i = 0; i < wext->num_freqs; i++) + wext->freqs[i] = iw_freq_to_uint32 (&range.freq[i]); + + /* Check for scanning capability; cards that can't scan are not supported */ + if (check_scan && (wext_can_scan (wext) == FALSE)) { + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): drivers that cannot scan are unsupported", + wext->parent.iface); + goto error; + } + + /* Check for the ability to scan specific SSIDs. Until the scan_capa + * field gets added to wireless-tools, need to work around that by casting + * to the custom structure. + */ + scan_capa_range = (struct iw_range_with_scan_capa *) ⦥ + if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { + wext->parent.can_scan_ssid = TRUE; + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): driver supports SSID scans (scan_capa 0x%02X).", + wext->parent.iface, + scan_capa_range->scan_capa); + } else { + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): driver does not support SSID scans (scan_capa 0x%02X).", + wext->parent.iface, + scan_capa_range->scan_capa); + } + + wext->parent.caps = wext_get_caps (wext, &range); + + nm_log_info (LOGD_HW | LOGD_WIFI, + "(%s): using WEXT for WiFi device control", + wext->parent.iface); + + return (WifiData *) wext; + +error: + wifi_utils_deinit ((WifiData *) wext); + return NULL; +} + +gboolean +wifi_wext_is_wifi (const char *iface) +{ + int fd; + struct iwreq iwr; + gboolean is_wifi = FALSE; + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd >= 0) { + strncpy (iwr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); + if (ioctl (fd, SIOCGIWNAME, &iwr) == 0) + is_wifi = TRUE; + close (fd); + } + return is_wifi; +} + diff --git a/src/wifi/wifi-utils-wext.h b/src/wifi/wifi-utils-wext.h new file mode 100644 index 00000000..96ad74eb --- /dev/null +++ b/src/wifi/wifi-utils-wext.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef WIFI_UTILS_WEXT_H +#define WIFI_UTILS_WEXT_H + +#include "wifi-utils.h" + +WifiData *wifi_wext_init (const char *iface, int ifindex, gboolean check_scan); + +gboolean wifi_wext_is_wifi (const char *iface); + +#endif /* WIFI_UTILS_WEXT_H */ diff --git a/src/wifi/wifi-utils.c b/src/wifi/wifi-utils.c new file mode 100644 index 00000000..a99a4b7b --- /dev/null +++ b/src/wifi/wifi-utils.c @@ -0,0 +1,213 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include <config.h> +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#include "wifi-utils.h" +#include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" +#if HAVE_WEXT +#include "wifi-utils-wext.h" +#endif + +gpointer +wifi_data_new (const char *iface, int ifindex, gsize len) +{ + WifiData *data; + + data = g_malloc0 (len); + data->iface = g_strdup (iface); + data->ifindex = ifindex; + return data; +} + +void +wifi_data_free (WifiData *data) +{ + g_free (data->iface); + memset (data, 0, sizeof (*data)); + g_free (data); +} + +/***************************************************************/ + +WifiData * +wifi_utils_init (const char *iface, int ifindex, gboolean check_scan) +{ + WifiData *ret; + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (ifindex > 0, NULL); + + ret = wifi_nl80211_init (iface, ifindex); + if (ret == NULL) { +#if HAVE_WEXT + ret = wifi_wext_init (iface, ifindex, check_scan); +#endif + } + return ret; +} + +NMDeviceWifiCapabilities +wifi_utils_get_caps (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); + + return data->caps; +} + +gboolean +wifi_utils_can_scan_ssid (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + return data->can_scan_ssid; +} + +NM80211Mode +wifi_utils_get_mode (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); + return data->get_mode (data); +} + +gboolean +wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail ((mode == NM_802_11_MODE_INFRA) || (mode == NM_802_11_MODE_ADHOC), FALSE); + + /* nl80211 probably doesn't need this */ + return data->set_mode ? data->set_mode (data, mode) : TRUE; +} + +guint32 +wifi_utils_get_freq (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->get_freq (data); +} + +guint32 +wifi_utils_find_freq (WifiData *data, const guint32 *freqs) +{ + g_return_val_if_fail (data != NULL, 0); + g_return_val_if_fail (freqs != NULL, 0); + return data->find_freq (data, freqs); +} + +GByteArray * +wifi_utils_get_ssid (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NULL); + return data->get_ssid (data); +} + +gboolean +wifi_utils_get_bssid (WifiData *data, struct ether_addr *out_bssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (out_bssid != NULL, FALSE); + + memset (out_bssid, 0, sizeof (*out_bssid)); + return data->get_bssid (data, out_bssid); +} + +guint32 +wifi_utils_get_rate (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->get_rate (data); +} + +int +wifi_utils_get_qual (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->get_qual (data); +} + +void +wifi_utils_deinit (WifiData *data) +{ + g_return_if_fail (data != NULL); + data->deinit (data); + wifi_data_free (data); +} + +gboolean +wifi_utils_is_wifi (const char *iface, const char *sysfs_path) +{ + char phy80211_path[255]; + struct stat s; + + g_return_val_if_fail (iface != NULL, FALSE); + + if (sysfs_path) { + /* Check for nl80211 sysfs paths */ + snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path); + if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + return TRUE; + } + + if (wifi_nl80211_is_wifi (iface)) + return TRUE; + +#if HAVE_WEXT + if (wifi_wext_is_wifi (iface)) + return TRUE; +#endif + + return FALSE; +} + + +/* OLPC Mesh-only functions */ + +guint32 +wifi_utils_get_mesh_channel (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->get_mesh_channel != NULL, FALSE); + return data->get_mesh_channel (data); +} + +gboolean +wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (channel >= 0, FALSE); + g_return_val_if_fail (channel <= 13, FALSE); + g_return_val_if_fail (data->set_mesh_channel != NULL, FALSE); + return data->set_mesh_channel (data, channel); +} + +gboolean +wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->set_mesh_ssid != NULL, FALSE); + return data->set_mesh_ssid (data, ssid); +} + diff --git a/src/wifi/wifi-utils.h b/src/wifi/wifi-utils.h new file mode 100644 index 00000000..09583e7b --- /dev/null +++ b/src/wifi/wifi-utils.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef WIFI_UTILS_H +#define WIFI_UTILS_H + +#include <net/ethernet.h> +#include <glib.h> + +#include "NetworkManager.h" + +typedef struct WifiData WifiData; + +gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path); + +WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); + +void wifi_utils_deinit (WifiData *data); + +NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); + +gboolean wifi_utils_can_scan_ssid (WifiData *data); + +NM80211Mode wifi_utils_get_mode (WifiData *data); + +gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); + +/* Returns frequency in MHz */ +guint32 wifi_utils_get_freq (WifiData *data); + +/* Return the first supported frequency in the zero-terminated list */ +guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); + +/* Caller must free returned byte array */ +GByteArray *wifi_utils_get_ssid (WifiData *data); + +/* Caller must free returned byte array */ +gboolean wifi_utils_get_bssid (WifiData *data, struct ether_addr *out_bssid); + +/* Returns current bitrate in Kbps */ +guint32 wifi_utils_get_rate (WifiData *data); + +/* Returns quality 0 - 100% on succes, or -1 on error */ +int wifi_utils_get_qual (WifiData *data); + + +/* OLPC Mesh-only functions */ +guint32 wifi_utils_get_mesh_channel (WifiData *data); + +gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); + +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid); + +#endif /* WIFI_UTILS_H */ diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am index 91f1dc4e..63c95dc7 100644 --- a/src/wimax/Makefile.am +++ b/src/wimax/Makefile.am @@ -1,13 +1,14 @@ INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_srcdir}/libnm-util -noinst_LTLIBRARIES = libwimax.la +pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la -libwimax_la_SOURCES = \ +libnm_device_plugin_wimax_la_SOURCES = \ + nm-wimax-factory.c \ nm-device-wimax.c \ nm-device-wimax.h \ nm-wimax-nsp.c \ @@ -18,14 +19,18 @@ libwimax_la_SOURCES = \ iwmxsdk.c \ iwmxsdk.h -libwimax_la_CPPFLAGS = \ +libnm_device_plugin_wimax_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ - $(IWMX_SDK_CFLAGS) + $(IWMX_SDK_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) -libwimax_la_LIBADD = \ +libnm_device_plugin_wimax_la_LDFLAGS = -module -avoid-version +libnm_device_plugin_wimax_la_LIBADD = \ $(DBUS_LIBS) \ $(IWMX_SDK_LIBS) \ - $(top_builddir)/marshallers/libmarshallers.la + $(GUDEV_LIBS) \ + $(top_builddir)/src/generated/libnm-generated.la nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml dbus-binding-tool --prefix=nm_wimax_nsp --mode=glib-server --output=$@ $< diff --git a/src/wimax/Makefile.in b/src/wimax/Makefile.in index e9b51e9f..2de52180 100644 --- a/src/wimax/Makefile.in +++ b/src/wimax/Makefile.in @@ -54,17 +54,48 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = -libwimax_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(top_builddir)/marshallers/libmarshallers.la -am_libwimax_la_OBJECTS = libwimax_la-nm-device-wimax.lo \ - libwimax_la-nm-wimax-nsp.lo libwimax_la-nm-wimax-util.lo \ - libwimax_la-iwmxsdk.lo -libwimax_la_OBJECTS = $(am_libwimax_la_OBJECTS) +libnm_device_plugin_wimax_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/generated/libnm-generated.la +am_libnm_device_plugin_wimax_la_OBJECTS = \ + libnm_device_plugin_wimax_la-nm-wimax-factory.lo \ + libnm_device_plugin_wimax_la-nm-device-wimax.lo \ + libnm_device_plugin_wimax_la-nm-wimax-nsp.lo \ + libnm_device_plugin_wimax_la-nm-wimax-util.lo \ + libnm_device_plugin_wimax_la-iwmxsdk.lo +libnm_device_plugin_wimax_la_OBJECTS = \ + $(am_libnm_device_plugin_wimax_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent +libnm_device_plugin_wimax_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libnm_device_plugin_wimax_la_LDFLAGS) \ + $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles @@ -91,8 +122,8 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libwimax_la_SOURCES) -DIST_SOURCES = $(libwimax_la_SOURCES) +SOURCES = $(libnm_device_plugin_wimax_la_SOURCES) +DIST_SOURCES = $(libnm_device_plugin_wimax_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -141,6 +172,8 @@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ @@ -195,11 +228,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ +LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -210,6 +247,7 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -249,6 +287,8 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ @@ -314,13 +354,14 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/generated \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/marshallers + -I${top_srcdir}/libnm-util -noinst_LTLIBRARIES = libwimax.la -libwimax_la_SOURCES = \ +pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la +libnm_device_plugin_wimax_la_SOURCES = \ + nm-wimax-factory.c \ nm-device-wimax.c \ nm-device-wimax.h \ nm-wimax-nsp.c \ @@ -331,14 +372,18 @@ libwimax_la_SOURCES = \ iwmxsdk.c \ iwmxsdk.h -libwimax_la_CPPFLAGS = \ +libnm_device_plugin_wimax_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ - $(IWMX_SDK_CFLAGS) + $(IWMX_SDK_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) -libwimax_la_LIBADD = \ +libnm_device_plugin_wimax_la_LDFLAGS = -module -avoid-version +libnm_device_plugin_wimax_la_LIBADD = \ $(DBUS_LIBS) \ $(IWMX_SDK_LIBS) \ - $(top_builddir)/marshallers/libmarshallers.la + $(GUDEV_LIBS) \ + $(top_builddir)/src/generated/libnm-generated.la BUILT_SOURCES = \ nm-wimax-nsp-glue.h \ @@ -380,17 +425,39 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libwimax.la: $(libwimax_la_OBJECTS) $(libwimax_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libwimax_la_OBJECTS) $(libwimax_la_LIBADD) $(LIBS) +libnm-device-plugin-wimax.la: $(libnm_device_plugin_wimax_la_OBJECTS) $(libnm_device_plugin_wimax_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_device_plugin_wimax_la_LINK) -rpath $(pkglibdir) $(libnm_device_plugin_wimax_la_OBJECTS) $(libnm_device_plugin_wimax_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -398,10 +465,11 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-iwmxsdk.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-device-wimax.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-wimax-nsp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-wimax-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_device_plugin_wimax_la-iwmxsdk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_device_plugin_wimax_la-nm-device-wimax.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-factory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-nsp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-util.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -430,37 +498,45 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< -libwimax_la-nm-device-wimax.lo: nm-device-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-device-wimax.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-device-wimax.Tpo -c -o libwimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-device-wimax.Tpo $(DEPDIR)/libwimax_la-nm-device-wimax.Plo +libnm_device_plugin_wimax_la-nm-wimax-factory.lo: nm-wimax-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_device_plugin_wimax_la-nm-wimax-factory.lo -MD -MP -MF $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-factory.Tpo -c -o libnm_device_plugin_wimax_la-nm-wimax-factory.lo `test -f 'nm-wimax-factory.c' || echo '$(srcdir)/'`nm-wimax-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-factory.Tpo $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-factory.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-factory.c' object='libnm_device_plugin_wimax_la-nm-wimax-factory.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_device_plugin_wimax_la-nm-wimax-factory.lo `test -f 'nm-wimax-factory.c' || echo '$(srcdir)/'`nm-wimax-factory.c + +libnm_device_plugin_wimax_la-nm-device-wimax.lo: nm-device-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_device_plugin_wimax_la-nm-device-wimax.lo -MD -MP -MF $(DEPDIR)/libnm_device_plugin_wimax_la-nm-device-wimax.Tpo -c -o libnm_device_plugin_wimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_device_plugin_wimax_la-nm-device-wimax.Tpo $(DEPDIR)/libnm_device_plugin_wimax_la-nm-device-wimax.Plo @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-wimax.c' object='libwimax_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-wimax.c' object='libnm_device_plugin_wimax_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_device_plugin_wimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c -libwimax_la-nm-wimax-nsp.lo: nm-wimax-nsp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-wimax-nsp.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-wimax-nsp.Tpo -c -o libwimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-wimax-nsp.Tpo $(DEPDIR)/libwimax_la-nm-wimax-nsp.Plo +libnm_device_plugin_wimax_la-nm-wimax-nsp.lo: nm-wimax-nsp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_device_plugin_wimax_la-nm-wimax-nsp.lo -MD -MP -MF $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-nsp.Tpo -c -o libnm_device_plugin_wimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-nsp.Tpo $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-nsp.Plo @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-nsp.c' object='libwimax_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-nsp.c' object='libnm_device_plugin_wimax_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_device_plugin_wimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c -libwimax_la-nm-wimax-util.lo: nm-wimax-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-wimax-util.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-wimax-util.Tpo -c -o libwimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-wimax-util.Tpo $(DEPDIR)/libwimax_la-nm-wimax-util.Plo +libnm_device_plugin_wimax_la-nm-wimax-util.lo: nm-wimax-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_device_plugin_wimax_la-nm-wimax-util.lo -MD -MP -MF $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-util.Tpo -c -o libnm_device_plugin_wimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-util.Tpo $(DEPDIR)/libnm_device_plugin_wimax_la-nm-wimax-util.Plo @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-util.c' object='libwimax_la-nm-wimax-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-util.c' object='libnm_device_plugin_wimax_la-nm-wimax-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_device_plugin_wimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c -libwimax_la-iwmxsdk.lo: iwmxsdk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-iwmxsdk.lo -MD -MP -MF $(DEPDIR)/libwimax_la-iwmxsdk.Tpo -c -o libwimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-iwmxsdk.Tpo $(DEPDIR)/libwimax_la-iwmxsdk.Plo +libnm_device_plugin_wimax_la-iwmxsdk.lo: iwmxsdk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_device_plugin_wimax_la-iwmxsdk.lo -MD -MP -MF $(DEPDIR)/libnm_device_plugin_wimax_la-iwmxsdk.Tpo -c -o libnm_device_plugin_wimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_device_plugin_wimax_la-iwmxsdk.Tpo $(DEPDIR)/libnm_device_plugin_wimax_la-iwmxsdk.Plo @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iwmxsdk.c' object='libwimax_la-iwmxsdk.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iwmxsdk.c' object='libnm_device_plugin_wimax_la-iwmxsdk.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_device_plugin_wimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_device_plugin_wimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c mostlyclean-libtool: -rm -f *.lo @@ -555,6 +631,9 @@ check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am @@ -585,7 +664,7 @@ maintainer-clean-generic: -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am @@ -612,7 +691,7 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: +install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am @@ -652,22 +731,23 @@ ps: ps-am ps-am: -uninstall-am: +uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am + install-pdf install-pdf-am install-pkglibLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 2d8553a0..1f1a622c 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -25,6 +25,7 @@ #include <net/ethernet.h> #include <sys/socket.h> #include <linux/if.h> +#include <netinet/ether.h> #include <WiMaxAPI.h> #include <WiMaxAPIEx.h> @@ -32,7 +33,6 @@ #include "nm-device-wimax.h" #include "nm-wimax-util.h" #include "nm-logging.h" -#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-system.h" #include "NetworkManagerUtils.h" @@ -43,15 +43,13 @@ #include "nm-utils.h" #include "nm-rfkill.h" #include "iwmxsdk.h" +#include "nm-enum-types.h" static gboolean impl_device_get_nsp_list (NMDeviceWimax *device, GPtrArray **list, GError **error); #include "nm-device-wimax-glue.h" -static void device_interface_init (NMDeviceInterface *iface_class); - -G_DEFINE_TYPE_EXTENDED (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) +G_DEFINE_TYPE (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE) enum { PROP_0, @@ -113,16 +111,7 @@ typedef struct { /***********************************************************/ -typedef enum -{ - NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0, - NM_WIMAX_ERROR_CONNECTION_INVALID, - NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, - NM_WIMAX_ERROR_NSP_NOT_FOUND, -} NMWimaxError; - #define NM_WIMAX_ERROR (nm_wimax_error_quark ()) -#define NM_TYPE_WIMAX_ERROR (nm_wimax_error_get_type ()) static GQuark nm_wimax_error_quark (void) @@ -133,31 +122,6 @@ nm_wimax_error_quark (void) return quark; } -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -static GType -nm_wimax_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* Connection was not a wired connection. */ - ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX, "ConnectionNotWimax"), - /* Connection was not a valid wired connection. */ - ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), - /* Connection does not apply to this device. */ - ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), - /* NSP not found in the scan list. */ - ENUM_ENTRY (NM_WIMAX_ERROR_NSP_NOT_FOUND, "NspNotFound"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("NMWimaxError", values); - } - return etype; -} - /***********************************************************/ void @@ -321,7 +285,7 @@ update_availability (NMDeviceWimax *self, gboolean old_available) if (new_available == old_available) return FALSE; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + state = nm_device_get_state (device); if (state == NM_DEVICE_STATE_UNAVAILABLE) { if (new_available == TRUE) { nm_device_state_changed (device, @@ -344,7 +308,7 @@ update_availability (NMDeviceWimax *self, gboolean old_available) /* NMDeviceInterface interface */ static void -real_set_enabled (NMDeviceInterface *device, gboolean enabled) +real_set_enabled (NMDevice *device, gboolean enabled) { NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); @@ -446,6 +410,35 @@ real_update_hw_address (NMDevice *dev) } static gboolean +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + NMSettingWimax *s_wimax; + const GByteArray *mac = NULL; + + s_wimax = nm_connection_get_setting_wimax (connection); + if (s_wimax) + mac = nm_setting_wimax_get_mac_address (s_wimax); + + if (mac) { + g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, priv->hw_addr.ether_addr_octet, mac->len) == 0) + return TRUE; + } else if (fail_if_no_hwaddr == FALSE) + return TRUE; + + return FALSE; +} + +static gboolean real_check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) @@ -731,7 +724,7 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) if (!req) return NM_ACT_STAGE_RETURN_FAILURE; - path = nm_act_request_get_specific_object (req); + path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); if (!path) return NM_ACT_STAGE_RETURN_FAILURE; @@ -774,7 +767,7 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) iface = nm_device_get_iface (device); g_assert (iface); - connection = nm_act_request_get_connection (nm_device_get_act_request (device)); + connection = nm_device_get_connection (device); g_assert (connection); s_wimax = nm_connection_get_setting_wimax (connection); @@ -878,7 +871,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, if (new_status == old_status) return; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + state = nm_device_get_state (NM_DEVICE (self)); old_available = nm_device_is_available (NM_DEVICE (self)); priv->status = new_status; @@ -917,7 +910,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, } /* Handle activation success and failure */ - if (IS_ACTIVATING_STATE (state)) { + if (nm_device_is_activating (NM_DEVICE (self))) { if (new_status == WIMAX_API_DEVICE_STATUS_Data_Connected) { /* Success */ clear_activation_timeout (self); @@ -993,7 +986,7 @@ wmx_media_status_cb (struct wmxsdk *wmxsdk, const char *iface; iface = nm_device_get_iface (NM_DEVICE (self)); - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + state = nm_device_get_state (NM_DEVICE (self)); nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %s", iface, iwmx_sdk_media_status_to_str (new_status)); @@ -1032,10 +1025,8 @@ wmx_connect_result_cb (struct wmxsdk *wmxsdk, { NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); - NMDeviceState state; - state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - if (IS_ACTIVATING_STATE (state)) { + if (nm_device_is_activating (NM_DEVICE (self))) { priv->connect_failed = (result == WIMAX_API_CONNECTION_SUCCESS); /* Wait for the state change so we can get the reason code; we * cache the connect failure so we don't have to wait for the @@ -1373,12 +1364,12 @@ nm_device_wimax_new (const char *udi, g_return_val_if_fail (driver != NULL, NULL); device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIMAX, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_IFACE, iface, - NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_TYPE_DESC, "WiMAX", - NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIMAX, - NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WIMAX, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "WiMAX", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIMAX, + NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WIMAX, NULL); if (device) { struct wmxsdk *sdk; @@ -1399,12 +1390,6 @@ nm_device_wimax_new (const char *udi, } static void -device_interface_init (NMDeviceInterface *iface_class) -{ - iface_class->set_enabled = real_set_enabled; -} - -static void nm_device_wimax_init (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); @@ -1434,7 +1419,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: nm_device_wimax_get_hw_address (self, &hw_addr); - g_value_take_string (value, nm_ether_ntop (&hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&hw_addr, ARPHRD_ETHER)); break; case PROP_ACTIVE_NSP: if (priv->current_nsp) @@ -1526,6 +1511,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) device_class->act_stage1_prepare = real_act_stage1_prepare; device_class->act_stage2_config = real_act_stage2_config; device_class->deactivate = real_deactivate; + device_class->set_enabled = real_set_enabled; + device_class->hwaddr_matches = hwaddr_matches; /* Properties */ g_object_class_install_property diff --git a/src/wimax/nm-device-wimax.h b/src/wimax/nm-device-wimax.h index d70380ac..a67ff17d 100644 --- a/src/wimax/nm-device-wimax.h +++ b/src/wimax/nm-device-wimax.h @@ -35,6 +35,14 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX)) #define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) +typedef enum +{ + NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0, /*< nick=ConnectionNotWimax >*/ + NM_WIMAX_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_WIMAX_ERROR_NSP_NOT_FOUND, /*< nick=NspNotFound >*/ +} NMWimaxError; + #define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" #define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" #define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" diff --git a/src/wimax/nm-wimax-factory.c b/src/wimax/nm-wimax-factory.c new file mode 100644 index 00000000..95cb4bf7 --- /dev/null +++ b/src/wimax/nm-wimax-factory.c @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include <gmodule.h> + +#include "nm-device-factory.h" +#include "nm-device-wimax.h" + +G_MODULE_EXPORT GObject * +nm_device_factory_create_device (GUdevDevice *device, + const char *devpath, + const char *ifname, + const char *driver, + GError **error) +{ + GObject *dev; + + /* FIXME: check 'DEVTYPE' instead; but since we only support Intel + * WiMAX devices for now this is appropriate. + */ + if (g_strcmp0 (driver, "i2400m_usb") != 0) + return NULL; /* unsupported */ + + dev = (GObject *) nm_device_wimax_new (devpath, ifname, driver); + if (dev == NULL) + g_set_error_literal (error, 0, 0, "Failed to create WiMAX device."); + return dev; +} + +G_MODULE_EXPORT guint32 +nm_device_factory_get_priority (void) +{ + return 0; +} + +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_type (void) +{ + return NM_DEVICE_TYPE_WIMAX; +} + diff --git a/src/wimax/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c index b10cee39..491cb5da 100644 --- a/src/wimax/nm-wimax-nsp.c +++ b/src/wimax/nm-wimax-nsp.c @@ -118,7 +118,7 @@ nm_wimax_nsp_check_compatible (NMWimaxNsp *self, priv = GET_PRIVATE (self); - s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX)); + s_wimax = nm_connection_get_setting_wimax (connection); if (!s_wimax) return FALSE; diff --git a/src/wpa.c b/src/wpa.c deleted file mode 100644 index 7d0e2261..00000000 --- a/src/wpa.c +++ /dev/null @@ -1,455 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * WPA Supplicant - WPA state machine and EAPOL-Key processing - * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this file may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "wireless-helper.h" - -#include <stdint.h> -#include <string.h> -#include <glib.h> - -#include "wpa.h" -#include "nm-logging.h" - -typedef guint16 u16; -typedef guint8 u8; - -#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) - -#define BIT(n) (1 << (n)) -#define WPA_CAPABILITY_PREAUTH BIT(0) - -#define WPA_REPLAY_COUNTER_LEN 8 -#define WPA_NONCE_LEN 32 - -#define PMKID_LEN 16 - -static const int WPA_SELECTOR_LEN = 4; -static const u8 WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; -static const u16 WPA_VERSION = 1; -static const u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; -static const u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; -static const u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; -static const u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; -static const u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; -static const u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; -static const u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; -static const u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; -static const u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; - -/* WPA IE version 1 - * 00-50-f2:1 (OUI:OUI type) - * 0x01 0x00 (version; little endian) - * (all following fields are optional:) - * Group Suite Selector (4 octets) (default: TKIP) - * Pairwise Suite Count (2 octets, little endian) (default: 1) - * Pairwise Suite List (4 * n octets) (default: TKIP) - * Authenticated Key Management Suite Count (2 octets, little endian) - * (default: 1) - * Authenticated Key Management Suite List (4 * n octets) - * (default: unspec 802.1X) - * WPA Capabilities (2 octets, little endian) (default: 0) - */ - -struct wpa_ie_hdr { - u8 elem_id; - u8 len; - u8 oui[3]; - u8 oui_type; - u8 version[2]; -} __attribute__ ((packed)); - - -static const int RSN_SELECTOR_LEN = 4; -static const u16 RSN_VERSION = 1; -static const u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; -static const u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; -static const u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; -static const u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; -static const u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; -static const u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; -static const u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; -static const u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; - -/* EAPOL-Key Key Data Encapsulation - * GroupKey and STAKey require encryption, otherwise, encryption is optional. - */ -static const u8 RSN_KEY_DATA_GROUPKEY[] = { 0x00, 0x0f, 0xac, 1 }; -static const u8 RSN_KEY_DATA_STAKEY[] = { 0x00, 0x0f, 0xac, 2 }; -static const u8 RSN_KEY_DATA_MAC_ADDR[] = { 0x00, 0x0f, 0xac, 3 }; -static const u8 RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 }; - -/* RSN IE version 1 - * 0x01 0x00 (version; little endian) - * (all following fields are optional:) - * Group Suite Selector (4 octets) (default: CCMP) - * Pairwise Suite Count (2 octets, little endian) (default: 1) - * Pairwise Suite List (4 * n octets) (default: CCMP) - * Authenticated Key Management Suite Count (2 octets, little endian) - * (default: 1) - * Authenticated Key Management Suite List (4 * n octets) - * (default: unspec 802.1X) - * RSN Capabilities (2 octets, little endian) (default: 0) - * PMKID Count (2 octets) (default: 0) - * PMKID List (16 * n octets) - */ - -struct rsn_ie_hdr { - u8 elem_id; /* WLAN_EID_RSN */ - u8 len; - u8 version[2]; -} __attribute__ ((packed)); - - -#define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2)) -#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0) -#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1) -#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ -/* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */ -#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5)) -#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4 -#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */ -#define WPA_KEY_INFO_TXRX BIT(6) /* group */ -#define WPA_KEY_INFO_ACK BIT(7) -#define WPA_KEY_INFO_MIC BIT(8) -#define WPA_KEY_INFO_SECURE BIT(9) -#define WPA_KEY_INFO_ERROR BIT(10) -#define WPA_KEY_INFO_REQUEST BIT(11) -#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only */ - - - -static int wpa_selector_to_bitfield(const u8 *s) -{ - if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_NONE; - if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_WEP40; - if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_TKIP; - if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_CCMP; - if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_WEP104; - return 0; -} - - -static int wpa_key_mgmt_to_bitfield(const u8 *s) -{ - if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0) - return IW_AUTH_KEY_MGMT_802_1X; - if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) == - 0) - return IW_AUTH_KEY_MGMT_PSK; - if (memcmp(s, WPA_AUTH_KEY_MGMT_NONE, WPA_SELECTOR_LEN) == 0) - return 0; - return 0; -} - - -static int rsn_selector_to_bitfield(const u8 *s) -{ - if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_NONE; - if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_WEP40; - if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_TKIP; - if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_CCMP; - if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_CIPHER_WEP104; - return 0; -} - - -static int rsn_key_mgmt_to_bitfield(const u8 *s) -{ - if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0) - return IW_AUTH_KEY_MGMT_802_1X; - if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) == - 0) - return IW_AUTH_KEY_MGMT_PSK; - return 0; -} - - -static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, - struct wpa_ie_data *data) -{ - const struct wpa_ie_hdr *hdr; - const u8 *pos; - int left; - int i, count; - - data->proto = IW_AUTH_WPA_VERSION_WPA; - data->pairwise_cipher = IW_AUTH_CIPHER_TKIP; - data->group_cipher = IW_AUTH_CIPHER_TKIP; - data->key_mgmt = IW_AUTH_KEY_MGMT_802_1X; - data->capabilities = 0; - data->pmkid = NULL; - data->num_pmkid = 0; - - if (wpa_ie_len == 0) { - /* No WPA IE - fail silently */ - return -1; - } - - if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) { - nm_log_dbg (LOGD_WIFI, "IE len too short %lu", - (unsigned long) wpa_ie_len); - return -1; - } - - hdr = (const struct wpa_ie_hdr *) wpa_ie; - - if (hdr->elem_id != WPA_GENERIC_INFO_ELEM || - hdr->len != wpa_ie_len - 2 || - memcmp(hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN) != 0 || - WPA_GET_LE16(hdr->version) != WPA_VERSION) { - nm_log_dbg (LOGD_WIFI, "malformed IE or unknown version"); - return -1; - } - - pos = (const u8 *) (hdr + 1); - left = wpa_ie_len - sizeof(*hdr); - - if (left >= WPA_SELECTOR_LEN) { - data->group_cipher = wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } else if (left > 0) { - nm_log_dbg (LOGD_WIFI, "IE length mismatch, %u too much", left); - return -1; - } - - if (left >= 2) { - data->pairwise_cipher = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) { - nm_log_dbg (LOGD_WIFI, "IE count botch (pairwise), " - "count %u left %u", count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->pairwise_cipher |= wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - nm_log_dbg (LOGD_WIFI, "IE too short (for key mgmt)"); - return -1; - } - - if (left >= 2) { - data->key_mgmt = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) { - nm_log_dbg (LOGD_WIFI, "IE count botch (key mgmt), " - "count %u left %u", count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - nm_log_dbg (LOGD_WIFI, "IE too short (for capabilities)"); - return -1; - } - - if (left >= 2) { - if (WPA_GET_LE16 (pos) & WPA_CAPABILITY_PREAUTH) - data->capabilities |= IW_PMKID_CAND_PREAUTH; - pos += 2; - left -= 2; - } - - if (left > 0) { - nm_log_dbg (LOGD_WIFI, "IE has %u trailing bytes", left); - return -1; - } - - return 0; -} - - -static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, - struct wpa_ie_data *data) -{ - const struct rsn_ie_hdr *hdr; - const u8 *pos; - int left; - int i, count; - - data->proto = IW_AUTH_WPA_VERSION_WPA2; - data->pairwise_cipher = IW_AUTH_CIPHER_CCMP; - data->group_cipher = IW_AUTH_CIPHER_CCMP; - data->key_mgmt = IW_AUTH_KEY_MGMT_802_1X; - data->capabilities = 0; - data->pmkid = NULL; - data->num_pmkid = 0; - - if (rsn_ie_len == 0) { - /* No RSN IE - fail silently */ - return -1; - } - - if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) { - nm_log_dbg (LOGD_WIFI, "IE len too short %lu", - (unsigned long) rsn_ie_len); - return -1; - } - - hdr = (const struct rsn_ie_hdr *) rsn_ie; - - if (hdr->elem_id != WPA_RSN_INFO_ELEM || - hdr->len != rsn_ie_len - 2 || - WPA_GET_LE16(hdr->version) != RSN_VERSION) { - nm_log_dbg (LOGD_WIFI, "malformed IE or unknown version"); - return -1; - } - - pos = (const u8 *) (hdr + 1); - left = rsn_ie_len - sizeof(*hdr); - - if (left >= RSN_SELECTOR_LEN) { - data->group_cipher = rsn_selector_to_bitfield(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } else if (left > 0) { - nm_log_dbg (LOGD_WIFI, "IE length mismatch, %u too much", left); - return -1; - } - - if (left >= 2) { - data->pairwise_cipher = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * RSN_SELECTOR_LEN) { - nm_log_dbg (LOGD_WIFI, "IE count botch (pairwise), " - "count %u left %u", count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->pairwise_cipher |= rsn_selector_to_bitfield(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } - } else if (left == 1) { - nm_log_dbg (LOGD_WIFI, "IE too short (for key mgmt)"); - return -1; - } - - if (left >= 2) { - data->key_mgmt = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * RSN_SELECTOR_LEN) { - nm_log_dbg (LOGD_WIFI, "IE count botch (key mgmt), " - "count %u left %u", count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } - } else if (left == 1) { - nm_log_dbg (LOGD_WIFI, "IE too short (for capabilities)"); - return -1; - } - - if (left >= 2) { - if (WPA_GET_LE16 (pos) & WPA_CAPABILITY_PREAUTH) - data->capabilities |= IW_PMKID_CAND_PREAUTH; - pos += 2; - left -= 2; - } - - if (left >= 2) { - data->num_pmkid = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (left < data->num_pmkid * PMKID_LEN) { - nm_log_dbg (LOGD_WIFI, "PMKID underflow " - "(num_pmkid=%d left=%d)", - data->num_pmkid, left); - data->num_pmkid = 0; - } else { - data->pmkid = pos; - pos += data->num_pmkid * PMKID_LEN; - left -= data->num_pmkid * PMKID_LEN; - } - } - - if (left > 0) { - nm_log_dbg (LOGD_WIFI, "IE has %u trailing bytes - ignored", left); - } - - return 0; -} - - -/** - * wpa_parse_wpa_ie - Parse WPA/RSN IE - * @wpa_ie: Pointer to WPA or RSN IE - * @wpa_ie_len: Length of the WPA/RSN IE - * @data: Pointer to data area for parsing results - * Returns: parsed results on success, NULL on failure - * - * Parse the contents of WPA or RSN IE and write the parsed data into data. - */ -wpa_ie_data * wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len) -{ - wpa_ie_data *data = NULL; - int err = -1; - - if (!wpa_ie || wpa_ie_len <= 0) - return NULL; - - data = g_slice_new0 (wpa_ie_data); - - if (wpa_ie_len >= 1 && wpa_ie[0] == WPA_RSN_INFO_ELEM) - err = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); - else - err = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); - - if (err != 0) { - g_slice_free (wpa_ie_data, data); - data = NULL; - } - - if (data) { - nm_log_dbg (LOGD_WIFI, "WPA IE: -------------------"); - nm_log_dbg (LOGD_WIFI, " proto 0x%X", data->proto); - nm_log_dbg (LOGD_WIFI, " pw cipher 0x%X", data->pairwise_cipher); - nm_log_dbg (LOGD_WIFI, " gr cipher 0x%X", data->group_cipher); - nm_log_dbg (LOGD_WIFI, " key mgmt 0x%X", data->key_mgmt); - nm_log_dbg (LOGD_WIFI, " capabilities 0x%X", data->capabilities); - nm_log_dbg (LOGD_WIFI, " # pmkid 0x%X", data->num_pmkid); - nm_log_dbg (LOGD_WIFI, " "); - } - - return data; -} - diff --git a/src/wpa.h b/src/wpa.h deleted file mode 100644 index 18d1dbee..00000000 --- a/src/wpa.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * wpa_supplicant - WPA definitions - * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this file may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#ifndef WPA_H -#define WPA_H - -#include <stdint.h> - -#define WPA_GENERIC_INFO_ELEM 0xdd -#define WPA_RSN_INFO_ELEM 0x30 - -#define WPA_MAX_IE_LEN 40 - -typedef struct wpa_ie_data { - int proto; - int pairwise_cipher; - int group_cipher; - int key_mgmt; - int capabilities; - int num_pmkid; - const uint8_t *pmkid; -} wpa_ie_data; - - -wpa_ie_data * wpa_parse_wpa_ie (const uint8_t *wpa_ie, size_t wpa_ie_len); - -#endif /* WPA_H */ |