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.
This commit is contained in:
Thomas Haller 2016-10-01 16:19:24 +02:00
parent 4d37f7a1e9
commit ad0f403f9d
10 changed files with 228 additions and 336 deletions

View file

@ -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:"

View file

@ -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

View file

@ -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__ */

View file

@ -27,7 +27,7 @@
#include "nm-default.h"
#include "nm-dhcp-dhclient.h"
#if WITH_DHCLIENT
#include <string.h>
#include <stdlib.h>
@ -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 */

View file

@ -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__ */

View file

@ -22,7 +22,7 @@
#include "nm-default.h"
#include "nm-dhcp-dhcpcd.h"
#if WITH_DHCPCD
#include <string.h>
#include <stdlib.h>
@ -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 */

View file

@ -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__ */

View file

@ -34,9 +34,6 @@
#include <fcntl.h>
#include <stdio.h>
#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);
}

View file

@ -18,8 +18,6 @@
#include "nm-default.h"
#include "nm-dhcp-systemd.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
@ -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,
};

View file

@ -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__ */