From ad0f403f9d2bfc7aa57b1bf9adb1d7666ccb5498 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 1 Oct 2016 16:19:24 +0200 Subject: [PATCH] dhcp: refactor loading of DHCP plugins The DHCP plugins are linked statically and don't have a plugin mechanism to be loaded from a shared library. Change the _nm_dhcp_client_register() mechanism to something more static. Also, only link the plugins into the binary if they are actually enabled. Previously, they would always be linked in (and always register themself). However, nm_dhcp_dh*_get_path() would return NULL which made the plugin unusable. The autoconf code to detect the DHCP plugins is still not stellar, but seems to work well enough for now. At least, we log the result of the detection at the end of the configure-script, so a user can at least notice what happend. --- configure.ac | 95 ++++++++++------- src/Makefile.am | 64 ++++-------- src/dhcp-manager/nm-dhcp-client.h | 32 +++--- src/dhcp-manager/nm-dhcp-dhclient.c | 38 ++++--- src/dhcp-manager/nm-dhcp-dhclient.h | 36 ------- src/dhcp-manager/nm-dhcp-dhcpcd.c | 38 ++++--- src/dhcp-manager/nm-dhcp-dhcpcd.h | 37 ------- src/dhcp-manager/nm-dhcp-manager.c | 153 +++++++++++----------------- src/dhcp-manager/nm-dhcp-systemd.c | 34 ++++--- src/dhcp-manager/nm-dhcp-systemd.h | 37 ------- 10 files changed, 228 insertions(+), 336 deletions(-) delete mode 100644 src/dhcp-manager/nm-dhcp-dhclient.h delete mode 100644 src/dhcp-manager/nm-dhcp-dhcpcd.h delete mode 100644 src/dhcp-manager/nm-dhcp-systemd.h 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__ */ -