diff --git a/configure.ac b/configure.ac index 34b92d1afe..570aae3984 100644 --- a/configure.ac +++ b/configure.ac @@ -742,48 +742,71 @@ AM_CONDITIONAL(WITH_OFONO, test "${with_ofono}" = "yes") # DHCP client support AC_ARG_WITH([dhclient], AS_HELP_STRING([--with-dhclient=yes|no|path], [Enable dhclient 4.x support])) -AC_ARG_WITH([dhcpcd], AS_HELP_STRING([--with-dhcpcd=yes|no|path], [Enable dhcpcd 4.x support])) -# Default to "yes" -AS_IF([test -z "$with_dhclient"], with_dhclient=yes) -AS_IF([test -z "$with_dhcpcd"], with_dhcpcd=yes) -# Search and check the executables -if test "$with_dhclient" = "yes"; then - AC_PATH_PROGS(with_dhclient, dhclient, no, /sbin:/usr/sbin:/usr/local/sbin) - if test "$with_dhclient" != "no"; then - if ! $with_dhclient --version 2>&1 | grep -q "^isc-dhclient-4\."; then - AC_MSG_WARN([Cannot use dhclient, version 4.x is required]) - with_dhclient=no - fi - fi -fi -if test "$with_dhcpcd" = "yes"; then - AC_PATH_PROGS(with_dhcpcd, dhcpcd, no, /sbin:/usr/sbin:/usr/local/sbin) - if test "$with_dhcpcd" != "no"; then - if ! $with_dhcpcd --version 2>&1 | grep -q "^dhcpcd [[456789]]\."; then - AC_MSG_WARN([Cannot use dhcpcd, version 4.x or higher is required]) - with_dhcpcd=no - elif $with_dhcpcd --version 2>&1 | grep -q "^dhcpcd [[6789]]\."; then - AC_DEFINE(DHCPCD_SUPPORTS_IPV6, 1, [Define if dhcpcd supports IPv6 (6.x+)]) - fi - fi -fi -# Fallback -if test "$with_dhclient" = "no" -a "$with_dhcpcd" = "no"; then - AC_MSG_WARN([Could not find a suitable DHCP client, falling back to dhclient]) - with_dhclient=/sbin/dhclient -fi -# Add substitutions if test "$with_dhclient" != "no"; then - AC_DEFINE(WITH_DHCLIENT, TRUE, [Define if you have dhclient]) + with_dhclient_="$with_dhclient" + AC_PATH_PROGS(with_dhclient, dhclient, no, /sbin:/usr/sbin:/usr/local/sbin) + if test "$with_dhclient" == "no"; then + if test "$with_dhclient_" == yes; then + AC_MSG_WARN([dhclient not found, assume path /usr/sbin/dhclient]) + with_dhclient=/usr/sbin/dhclient + fi + else + if ! $with_dhclient --version 2>&1 | grep -q "^isc-dhclient-4\."; then + AC_MSG_WARN([Seems version of dhclient $with_dhclient is too old, version 4.x or newer is required.]) + fi + fi +fi +if test "$with_dhclient" != "no"; then + AC_DEFINE(WITH_DHCLIENT, 1, [Define if you have dhclient]) AC_SUBST(DHCLIENT_PATH, $with_dhclient) else - AC_DEFINE(WITH_DHCLIENT, FALSE, [Define if you have dhclient]) + AC_DEFINE(WITH_DHCLIENT, 0, [Define if you have dhclient]) +fi + +AC_ARG_WITH([dhcpcd], AS_HELP_STRING([--with-dhcpcd=yes|no|path], [Enable dhcpcd 4.x support])) +AC_ARG_WITH([dhcpcd-supports-ipv6], AS_HELP_STRING([--with-dhcpcd-supports-ipv6=yes|no|auto], [Whether using dhcpcd >= 6.x which has IPv6 support]), [with_dhcpcd_supports_ipv6=$withval], [with_dhcpcd_supports_ipv6=auto]) +if test "$with_dhcpcd" != "no"; then + with_dhcpcd_="$with_dhcpcd" + AC_PATH_PROGS(with_dhcpcd, dhcpcd, no, /sbin:/usr/sbin:/usr/local/sbin) + if test "$with_dhcpcd" == "no"; then + if test "$with_dhcpcd_" == yes; then + AC_MSG_WARN([dhcpcd not found, assume path /usr/sbin/dhcpcd]) + with_dhcpcd=/usr/sbin/dhcpcd + if test "$with_dhcpcd_supports_ipv6" == auto; then + with_dhcpcd_supports_ipv6=yes + fi + fi + else + if ! $with_dhcpcd --version 2>&1 | grep -q "^dhcpcd [[456789]]\."; then + AC_MSG_WARN([Seems version of dhcpcd $with_dhcpcd is too old, version 4.x or newer is required]) + fi + fi fi if test "$with_dhcpcd" != "no"; then - AC_DEFINE(WITH_DHCPCD, TRUE, [Define if you have dhcpcd]) + if $with_dhcpcd --version 2>&1 | grep -q "^dhcpcd [[6789]]\."; then + if test "$with_dhcpcd_supports_ipv6" == no; then + AC_MSG_WARN([Seems version of dhcpcd $with_dhcpcd supports IPv6, but compiling --with-dhcpcd-supports-ipv6=no]) + else + with_dhcpcd_supports_ipv6=yes + fi + else + if test "$with_dhcpcd_supports_ipv6" == yes; then + AC_MSG_WARN([Seems version of dhcpcd $with_dhcpcd does not support IPv6, but compiling --with-dhcpcd-supports-ipv6=yes]) + else + with_dhcpcd_supports_ipv6=no + fi + fi + if test "$with_dhcpcd_supports_ipv6" != no; then + AC_DEFINE(DHCPCD_SUPPORTS_IPV6, 1, [Define if dhcpcd supports IPv6 (6.x+)]) + fi +else + with_dhcpcd_supports_ipv6=no +fi +if test "$with_dhcpcd" != "no"; then + AC_DEFINE(WITH_DHCPCD, 1, [Define if you have dhcpcd]) AC_SUBST(DHCPCD_PATH, $with_dhcpcd) else - AC_DEFINE(WITH_DHCPCD, FALSE, [Define if you have dhcpcd]) + AC_DEFINE(WITH_DHCPCD, 0, [Define if you have dhcpcd]) fi # resolvconf and netconfig support @@ -792,6 +815,7 @@ AC_ARG_WITH(netconfig, AS_HELP_STRING([--with-netconfig=yes|no], [Enable SUSE ne AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval]) if test "$config_dns_rc_manager_default" != symlink -a \ "$config_dns_rc_manager_default" != file -a \ + "$config_dns_rc_manager_default" != "" -a \ "$config_dns_rc_manager_default" != netconfig -a \ "$config_dns_rc_manager_default" != resolvconf; then AC_MSG_WARN([Unknown --with-config-dns-rc-manager-default=$config_dns_rc_manager_default setting.]) @@ -1265,6 +1289,7 @@ echo echo "DHCP clients:" echo " dhclient: $with_dhclient" echo " dhcpcd: $with_dhcpcd" +echo " dhcpcd-supports-ipv6: $with_dhcpcd_supports_ipv6" echo echo "Miscellaneous:" diff --git a/src/Makefile.am b/src/Makefile.am index 8c87c6a4ee..6e2742a8d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,7 +90,6 @@ noinst_LTLIBRARIES = \ libNetworkManagerBase.la \ libNetworkManager.la \ libNetworkManagerTest.la \ - libnm-iface-helper.la \ libsystemd-nm.la ############################################################################### @@ -290,24 +289,9 @@ nm_device_headers = \ devices/nm-device-vxlan.h \ $(NULL) -nm_dhcp_client_sources = \ - dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhcpcd.c \ - dhcp-manager/nm-dhcp-systemd.c \ - $(NULL) - -nm_dhcp_client_headers = \ - dhcp-manager/nm-dhcp-dhclient.h \ - dhcp-manager/nm-dhcp-dhcpcd.h \ - dhcp-manager/nm-dhcp-systemd.h \ - $(NULL) - ############################################################################### libNetworkManager_la_SOURCES = \ - \ - dhcp-manager/nm-dhcp-dhclient-utils.c \ - dhcp-manager/nm-dhcp-dhclient-utils.h \ \ nm-checkpoint-manager.c \ nm-checkpoint-manager.h \ @@ -332,13 +316,18 @@ libNetworkManager_la_SOURCES = \ dhcp-manager/nm-dhcp-client.c \ dhcp-manager/nm-dhcp-client.h \ dhcp-manager/nm-dhcp-client-logging.h \ - dhcp-manager/nm-dhcp-helper-api.h \ dhcp-manager/nm-dhcp-utils.c \ - dhcp-manager/nm-dhcp-utils.h \ - dhcp-manager/nm-dhcp-listener.c \ - dhcp-manager/nm-dhcp-listener.h \ dhcp-manager/nm-dhcp-manager.c \ dhcp-manager/nm-dhcp-manager.h \ + dhcp-manager/nm-dhcp-utils.h \ + dhcp-manager/nm-dhcp-dhclient.c \ + dhcp-manager/nm-dhcp-dhcpcd.c \ + dhcp-manager/nm-dhcp-systemd.c \ + dhcp-manager/nm-dhcp-helper-api.h \ + dhcp-manager/nm-dhcp-listener.c \ + dhcp-manager/nm-dhcp-listener.h \ + dhcp-manager/nm-dhcp-dhclient-utils.c \ + dhcp-manager/nm-dhcp-dhclient-utils.h \ \ dns-manager/nm-dns-dnsmasq.c \ dns-manager/nm-dns-dnsmasq.h \ @@ -524,9 +513,6 @@ NetworkManager_SOURCES = \ $(nm_device_sources) \ $(nm_device_headers) \ \ - $(nm_dhcp_client_sources) \ - $(nm_dhcp_client_headers) \ - \ main-utils.c \ main-utils.h \ main.c @@ -540,7 +526,10 @@ NetworkManager_LDFLAGS = \ ############################################################################### -libnm_iface_helper_la_SOURCES = \ +nm_iface_helper_CFLAGS = \ + -DNM_DHCP_INTERNAL_ONLY + +nm_iface_helper_SOURCES = \ \ dhcp-manager/nm-dhcp-client.c \ dhcp-manager/nm-dhcp-client.h \ @@ -549,6 +538,7 @@ libnm_iface_helper_la_SOURCES = \ dhcp-manager/nm-dhcp-utils.h \ dhcp-manager/nm-dhcp-manager.c \ dhcp-manager/nm-dhcp-manager.h \ + dhcp-manager/nm-dhcp-systemd.c \ \ platform/nmp-netns.c \ platform/nmp-netns.h \ @@ -586,15 +576,19 @@ libnm_iface_helper_la_SOURCES = \ nm-multi-index.c \ nm-multi-index.h \ NetworkManagerUtils.c \ - NetworkManagerUtils.h + NetworkManagerUtils.h \ + \ + nm-iface-helper.c \ + main-utils.c \ + main-utils.h if WITH_WEXT -libnm_iface_helper_la_SOURCES += \ +nm_iface_helper_SOURCES += \ platform/wifi/wifi-utils-wext.c \ platform/wifi/wifi-utils-wext.h endif -libnm_iface_helper_la_LIBADD = \ +nm_iface_helper_LDADD = \ $(top_builddir)/libnm-core/libnm-core.la \ $(top_builddir)/introspection/libnmdbus.la \ libNetworkManagerBase.la \ @@ -606,22 +600,6 @@ libnm_iface_helper_la_LIBADD = \ $(DL_LIBS) \ $(LIBM) -nm_iface_helper_SOURCES = \ - dhcp-manager/nm-dhcp-systemd.h \ - dhcp-manager/nm-dhcp-systemd.c \ - nm-iface-helper.c \ - main-utils.c \ - main-utils.h - -nm_iface_helper_LDADD = \ - $(top_builddir)/libnm-core/libnm-core.la \ - libnm-iface-helper.la \ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) \ - $(LIBNL_LIBS) \ - $(LIBNDP_LIBS) \ - $(LIBM) - nm_iface_helper_LDFLAGS = \ -rdynamic diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 776f9dd38b..9a2d21f713 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -99,19 +99,6 @@ typedef struct { GType nm_dhcp_client_get_type (void); -typedef const char *(*NMDhcpClientGetPathFunc) (void); - -typedef GSList * (*NMDhcpClientGetLeaseConfigsFunc) (const char *iface, - int ifindex, - const char *uuid, - gboolean ipv6, - guint32 default_route_metric); - -void _nm_dhcp_client_register (GType gtype, - const char *name, - NMDhcpClientGetPathFunc get_path_func, - NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func); - pid_t nm_dhcp_client_get_pid (NMDhcpClient *self); const char *nm_dhcp_client_get_iface (NMDhcpClient *self); @@ -173,4 +160,23 @@ gboolean nm_dhcp_client_handle_event (gpointer unused, void nm_dhcp_client_set_client_id (NMDhcpClient *self, GBytes *client_id); +/***************************************************************************** + * Client data + *****************************************************************************/ + +typedef struct { + GType (*get_type)(void); + const char *name; + const char *(*get_path) (void); + GSList *(*get_lease_ip_configs) (const char *iface, + int ifindex, + const char *uuid, + gboolean ipv6, + guint32 default_route_metric); +} NMDhcpClientFactory; + +extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient; +extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd; +extern const NMDhcpClientFactory _nm_dhcp_client_factory_internal; + #endif /* __NETWORKMANAGER_DHCP_CLIENT_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index e7c266032c..a055e54179 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -27,7 +27,7 @@ #include "nm-default.h" -#include "nm-dhcp-dhclient.h" +#if WITH_DHCLIENT #include #include @@ -47,6 +47,20 @@ /*****************************************************************************/ +#define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type ()) +#define NM_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclient)) +#define NM_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) +#define NM_IS_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCLIENT)) +#define NM_IS_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCLIENT)) +#define NM_DHCP_DHCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) + +typedef struct _NMDhcpDhclient NMDhcpDhclient; +typedef struct _NMDhcpDhclientClass NMDhcpDhclientClass; + +static GType nm_dhcp_dhclient_get_type (void); + +/*****************************************************************************/ + typedef struct { char *conf_file; const char *def_leasefile; @@ -73,11 +87,7 @@ G_DEFINE_TYPE (NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) static const char * nm_dhcp_dhclient_get_path (void) { - const char *path = NULL; - - if (WITH_DHCLIENT) - path = nm_utils_find_helper ("dhclient", DHCLIENT_PATH, NULL); - return path; + return nm_utils_find_helper ("dhclient", DHCLIENT_PATH, NULL); } /** @@ -682,13 +692,11 @@ nm_dhcp_dhclient_class_init (NMDhcpDhclientClass *dhclient_class) client_class->state_changed = state_changed; } -static void __attribute__((constructor)) -register_dhcp_dhclient (void) -{ - nm_g_type_init (); - _nm_dhcp_client_register (NM_TYPE_DHCP_DHCLIENT, - "dhclient", - nm_dhcp_dhclient_get_path, - nm_dhcp_dhclient_get_lease_ip_configs); -} +const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = { + .name = "dhclient", + .get_type = nm_dhcp_dhclient_get_type, + .get_path = nm_dhcp_dhclient_get_path, + .get_lease_ip_configs = nm_dhcp_dhclient_get_lease_ip_configs, +}; +#endif /* WITH_DHCLIENT */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.h b/src/dhcp-manager/nm-dhcp-dhclient.h deleted file mode 100644 index d0c3188b00..0000000000 --- a/src/dhcp-manager/nm-dhcp-dhclient.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2010 Red Hat, Inc. - */ - -#ifndef __NM_DHCP_DHCLIENT_H__ -#define __NM_DHCP_DHCLIENT_H__ - -#include "nm-dhcp-client.h" - -#define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type ()) -#define NM_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclient)) -#define NM_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) -#define NM_IS_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCLIENT)) -#define NM_IS_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCLIENT)) -#define NM_DHCP_DHCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) - -typedef struct _NMDhcpDhclient NMDhcpDhclient; -typedef struct _NMDhcpDhclientClass NMDhcpDhclientClass; - -GType nm_dhcp_dhclient_get_type (void); - -#endif /* __NM_DHCP_DHCLIENT_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index e448bb980a..6b7fe38bbf 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -22,7 +22,7 @@ #include "nm-default.h" -#include "nm-dhcp-dhcpcd.h" +#if WITH_DHCPCD #include #include @@ -40,6 +40,20 @@ /*****************************************************************************/ +#define NM_TYPE_DHCP_DHCPCD (nm_dhcp_dhcpcd_get_type ()) +#define NM_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcd)) +#define NM_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) +#define NM_IS_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCPCD)) +#define NM_IS_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCPCD)) +#define NM_DHCP_DHCPCD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) + +typedef struct _NMDhcpDhcpcd NMDhcpDhcpcd; +typedef struct _NMDhcpDhcpcdClass NMDhcpDhcpcdClass; + +static GType nm_dhcp_dhcpcd_get_type (void); + +/*****************************************************************************/ + typedef struct { char *pid_file; NMDhcpListener *dhcp_listener; @@ -63,11 +77,7 @@ G_DEFINE_TYPE (NMDhcpDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT) static const char * nm_dhcp_dhcpcd_get_path (void) { - const char *path = NULL; - - if (WITH_DHCPCD) - path = nm_utils_find_helper ("dhcpcd", DHCPCD_PATH, NULL); - return path; + return nm_utils_find_helper ("dhcpcd", DHCPCD_PATH, NULL); } static gboolean @@ -244,13 +254,11 @@ nm_dhcp_dhcpcd_class_init (NMDhcpDhcpcdClass *dhcpcd_class) client_class->stop = stop; } -static void __attribute__((constructor)) -register_dhcp_dhclient (void) -{ - nm_g_type_init (); - _nm_dhcp_client_register (NM_TYPE_DHCP_DHCPCD, - "dhcpcd", - nm_dhcp_dhcpcd_get_path, - NULL); -} +const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd = { + .name = "dhcpcd", + .get_type = nm_dhcp_dhcpcd_get_type, + .get_path = nm_dhcp_dhcpcd_get_path, + .get_lease_ip_configs = NULL, +}; +#endif /* WITH_DHCPCD */ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.h b/src/dhcp-manager/nm-dhcp-dhcpcd.h deleted file mode 100644 index ceba9bebe3..0000000000 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2010 Red Hat, Inc. - */ - -#ifndef __NETWORKMANAGER_DHCP_DHCPCD_H__ -#define __NETWORKMANAGER_DHCP_DHCPCD_H__ - -#include "nm-dhcp-client.h" - -#define NM_TYPE_DHCP_DHCPCD (nm_dhcp_dhcpcd_get_type ()) -#define NM_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcd)) -#define NM_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) -#define NM_IS_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCPCD)) -#define NM_IS_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCPCD)) -#define NM_DHCP_DHCPCD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) - -typedef struct _NMDhcpDhcpcd NMDhcpDhcpcd; -typedef struct _NMDhcpDhcpcdClass NMDhcpDhcpcdClass; - -GType nm_dhcp_dhcpcd_get_type (void); - -#endif /* __NETWORKMANAGER_DHCP_DHCPCD_H__ */ - diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 461bb4aa0f..570626dbc7 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -34,9 +34,6 @@ #include #include -#include "nm-dhcp-dhclient.h" -#include "nm-dhcp-dhcpcd.h" -#include "nm-dhcp-systemd.h" #include "nm-config.h" #include "NetworkManagerUtils.h" @@ -45,7 +42,7 @@ /*****************************************************************************/ typedef struct { - GType client_type; + const NMDhcpClientFactory *client_factory; GHashTable * clients; char * default_hostname; } NMDhcpManagerPrivate; @@ -70,70 +67,45 @@ const char *nm_dhcp_helper_path = LIBEXECDIR "/nm-dhcp-helper"; /*****************************************************************************/ -typedef struct { - GType gtype; - const char *name; - NMDhcpClientGetPathFunc get_path_func; - NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func; -} ClientDesc; +const NMDhcpClientFactory *const _factories[] = { -static GSList *client_descs = NULL; + /* the order here matters, as we will try the plugins in this order to find + * the first available plugin. */ -void -_nm_dhcp_client_register (GType gtype, - const char *name, - NMDhcpClientGetPathFunc get_path_func, - NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func) +#ifndef NM_DHCP_INTERNAL_ONLY +#if WITH_DHCLIENT + &_nm_dhcp_client_factory_dhclient, +#endif +#if WITH_DHCPCD + &_nm_dhcp_client_factory_dhcpcd, +#endif +#endif + &_nm_dhcp_client_factory_internal, +}; + +static const NMDhcpClientFactory * +_client_factory_find_by_name (const char *name) { - ClientDesc *desc; - GSList *iter; + int i; - g_return_if_fail (gtype != G_TYPE_INVALID); - g_return_if_fail (name != NULL); + g_return_val_if_fail (name, NULL); - for (iter = client_descs; iter; iter = iter->next) { - desc = iter->data; - g_return_if_fail (desc->gtype != gtype); - g_return_if_fail (strcmp (desc->name, name) != 0); - } + for (i = 0; i < G_N_ELEMENTS (_factories); i++) { + const NMDhcpClientFactory *f = _factories[i]; - desc = g_slice_new0 (ClientDesc); - desc->gtype = gtype; - desc->name = name; - desc->get_path_func = get_path_func; - desc->get_lease_configs_func = get_lease_configs_func; - client_descs = g_slist_prepend (client_descs, desc); -} - -static ClientDesc * -find_client_desc (const char *name, GType gtype) -{ - GSList *iter; - - g_return_val_if_fail (name || gtype, NULL); - - for (iter = client_descs; iter; iter = iter->next) { - ClientDesc *desc = iter->data; - - if (name && strcmp (desc->name, name) != 0) - continue; - if (gtype && desc->gtype != gtype) - continue; - return desc; + if (nm_streq (f->name, name)) + return f; } return NULL; } -static GType -is_client_enabled (const char *name) +static const NMDhcpClientFactory * +_client_factory_available (const NMDhcpClientFactory *client_factory) { - ClientDesc *desc; - - desc = find_client_desc (name, G_TYPE_INVALID); - if (desc && (!desc->get_path_func || desc->get_path_func())) - return desc->gtype; - - return G_TYPE_INVALID; + if ( client_factory + && (!client_factory->get_path || client_factory->get_path ())) + return client_factory; + return NULL; } /*****************************************************************************/ @@ -224,7 +196,7 @@ client_start (NMDhcpManager *self, priv = NM_DHCP_MANAGER_GET_PRIVATE (self); /* Ensure we have a usable DHCP client */ - if (priv->client_type == G_TYPE_INVALID) + if (!priv->client_factory) return NULL; /* Kill any old client instance */ @@ -237,7 +209,7 @@ client_start (NMDhcpManager *self, } /* And make a new one */ - client = g_object_new (priv->client_type, + client = g_object_new (priv->client_factory->get_type (), NM_DHCP_CLIENT_INTERFACE, iface, NM_DHCP_CLIENT_IFINDEX, ifindex, NM_DHCP_CLIENT_HWADDR, hwaddr, @@ -351,7 +323,6 @@ nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, guint32 default_route_metric) { NMDhcpManagerPrivate *priv; - ClientDesc *desc; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (iface != NULL, NULL); @@ -359,12 +330,9 @@ nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, g_return_val_if_fail (uuid != NULL, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - if (priv->client_type == G_TYPE_INVALID) - return NULL; - - desc = find_client_desc (NULL, priv->client_type); - if (desc && desc->get_lease_configs_func) - return desc->get_lease_configs_func (iface, ifindex, uuid, ipv6, default_route_metric); + if ( priv->client_factory + && priv->client_factory->get_lease_ip_configs) + return priv->client_factory->get_lease_ip_configs (iface, ifindex, uuid, ipv6, default_route_metric); return NULL; } @@ -378,44 +346,43 @@ nm_dhcp_manager_init (NMDhcpManager *self) NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); NMConfig *config = nm_config_get (); const char *client; - GSList *iter; - GType type = G_TYPE_INVALID; + int i; + const NMDhcpClientFactory *client_factory = NULL; - for (iter = client_descs; iter; iter = iter->next) { - ClientDesc *desc = iter->data; + for (i = 0; i < G_N_ELEMENTS (_factories); i++) { + const NMDhcpClientFactory *f = _factories[i]; - nm_log_dbg (LOGD_DHCP, "dhcp-init: Registered DHCP client '%s' (%s)", - desc->name, g_type_name (desc->gtype)); + nm_log_dbg (LOGD_DHCP, "dhcp-init: enabled DHCP client '%s' (%s)%s", + f->name, g_type_name (f->get_type ()), + _client_factory_available (f) ? "" : " (not available)"); } /* Client-specific setup */ client = nm_config_get_dhcp_client (config); if (nm_config_get_configure_and_quit (config)) { - if (g_strcmp0 (client, "internal") != 0) + client_factory = &_nm_dhcp_client_factory_internal; + if (client && !nm_streq (client, client_factory->name)) nm_log_warn (LOGD_DHCP, "dhcp-init: Using internal DHCP client since configure-and-quit is set."); - client = "internal"; + } else { + if (client) { + client_factory = _client_factory_available (_client_factory_find_by_name (client)); + if (!client_factory) + nm_log_warn (LOGD_DHCP, "dhcp-init: DHCP client '%s' not available", client); + } + if (!client_factory) { + for (i = 0; i < G_N_ELEMENTS (_factories); i++) { + client_factory = _client_factory_available (_factories[i]); + if (client_factory) + break; + } + } } - if (client) - type = is_client_enabled (client); + nm_assert (client_factory); - if (type == G_TYPE_INVALID) { - if (client) - nm_log_warn (LOGD_DHCP, "dhcp-init: DHCP client '%s' not available", client); + nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", client_factory->name); - type = is_client_enabled ("dhclient"); - if (type == G_TYPE_INVALID) - type = is_client_enabled ("dhcpcd"); - if (type == G_TYPE_INVALID) - type = is_client_enabled ("internal"); - } - - if (type == G_TYPE_INVALID) - nm_log_warn (LOGD_DHCP, "dhcp-init: No usable DHCP client found! DHCP configurations will fail"); - else - nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", find_client_desc (NULL, type)->name); - - priv->client_type = type; + priv->client_factory = client_factory; priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_object_unref); @@ -429,7 +396,7 @@ dispose (GObject *object) if (priv->clients) { values = g_hash_table_get_values (priv->clients); - for (iter = values; iter; iter = g_list_next (iter)) + for (iter = values; iter; iter = g_list_next (iter)) remove_client (NM_DHCP_MANAGER (object), NM_DHCP_CLIENT (iter->data)); g_list_free (values); } diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c index 65fa071b9f..4e3f85deb9 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -18,8 +18,6 @@ #include "nm-default.h" -#include "nm-dhcp-systemd.h" - #include #include #include @@ -37,6 +35,22 @@ #include "nm-dhcp-client-logging.h" #include "systemd/nm-sd.h" +/*****************************************************************************/ + +#define NM_TYPE_DHCP_SYSTEMD (nm_dhcp_systemd_get_type ()) +#define NM_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemd)) +#define NM_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) +#define NM_IS_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_SYSTEMD)) +#define NM_IS_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_SYSTEMD)) +#define NM_DHCP_SYSTEMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) + +typedef struct _NMDhcpSystemd NMDhcpSystemd; +typedef struct _NMDhcpSystemdClass NMDhcpSystemdClass; + +static GType nm_dhcp_systemd_get_type (void); + +/*****************************************************************************/ + typedef struct { sd_dhcp_client *client4; sd_dhcp6_client *client6; @@ -1042,13 +1056,9 @@ nm_dhcp_systemd_class_init (NMDhcpSystemdClass *sdhcp_class) client_class->stop = stop; } -static void __attribute__((constructor)) -register_dhcp_dhclient (void) -{ - nm_g_type_init (); - _nm_dhcp_client_register (NM_TYPE_DHCP_SYSTEMD, - "internal", - NULL, - nm_dhcp_systemd_get_lease_ip_configs); -} - +const NMDhcpClientFactory _nm_dhcp_client_factory_internal = { + .name = "internal", + .get_type = nm_dhcp_systemd_get_type, + .get_path = NULL, + .get_lease_ip_configs = nm_dhcp_systemd_get_lease_ip_configs, +}; diff --git a/src/dhcp-manager/nm-dhcp-systemd.h b/src/dhcp-manager/nm-dhcp-systemd.h deleted file mode 100644 index b712bc2391..0000000000 --- a/src/dhcp-manager/nm-dhcp-systemd.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2014 Red Hat, Inc. - */ - -#ifndef __NM_DHCP_SYSTEMD_H__ -#define __NM_DHCP_SYSTEMD_H__ - -#include "nm-dhcp-client.h" - -#define NM_TYPE_DHCP_SYSTEMD (nm_dhcp_systemd_get_type ()) -#define NM_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemd)) -#define NM_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) -#define NM_IS_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_SYSTEMD)) -#define NM_IS_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_SYSTEMD)) -#define NM_DHCP_SYSTEMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) - -typedef struct _NMDhcpSystemd NMDhcpSystemd; -typedef struct _NMDhcpSystemdClass NMDhcpSystemdClass; - -GType nm_dhcp_systemd_get_type (void); - -#endif /* __NM_DHCP_SYSTEMD_H__ */ -