Merge remote branch 'origin/dhcp6'

This commit is contained in:
Dan Williams
2010-02-18 10:17:47 -08:00
38 changed files with 3615 additions and 1638 deletions

View File

@@ -292,67 +292,73 @@ else
fi fi
AC_SUBST(PPPD_PLUGIN_DIR) AC_SUBST(PPPD_PLUGIN_DIR)
# DHCP client # dhclient support
AC_ARG_WITH([dhcp-client], AS_HELP_STRING([--with-dhcp-client=dhcpcd|dhclient], [path to the chosen dhcp client])) AC_ARG_WITH([dhclient], AS_HELP_STRING([--with-dhclient=yes|no|path], [Enable dhclient 4.x support]))
# If a full path is given, use that and do not test if it works or not. # If a full path is given, use that and do not test if it works or not.
case "${with_dhcp_client}" in case "${with_dhclient}" in
/*) /*)
DHCP_CLIENT_PATH="${with_dhcp_client}" DHCLIENT_PATH="${with_dhclient}"
AC_MSG_NOTICE(using the DHCP client ${DHCP_CLIENT_PATH}) AC_MSG_NOTICE(using dhclient at ${DHCLIENT_PATH})
;;
no) AC_MSG_NOTICE(dhclient support disabled)
;;
*)
AC_MSG_CHECKING(for dhclient)
# NM only works with ISC dhclient - other derivatives don't have
# the same userland. NM also requires dhclient 4.x since older
# versions do not have IPv6 support.
for path in /sbin /usr/sbin /usr/pkg/sbin /usr/local/sbin; do
test -x "${path}/dhclient" || continue
case `"$path/dhclient" --version 2>&1` in
"isc-dhclient-4"*) DHCLIENT_PATH="$path/dhclient"; break;;
esac
done
if test -n "${DHCLIENT_PATH}"; then
AC_MSG_RESULT($DHCLIENT_PATH)
else
AC_MSG_RESULT(no)
fi
;; ;;
esac esac
if test -z "$DHCP_CLIENT_PATH" -a \( -z "$with_dhcp_client" -o x`basename "$with_dhcp_client"` = "xdhclient" \); then
# We only work with ISC dhclient - the FreeBSD and OpenBSD derivatives don't have the same userland. # dhcpcd support
AC_MSG_CHECKING(for dhclient) AC_ARG_WITH([dhcpcd], AS_HELP_STRING([--with-dhcpcd=yes|no|path], [Enable dhcpcd 4.x support]))
for client in "$with_dhcp_client" /sbin/dhclient /usr/pkg/sbin/dhclient /usr/local/sbin/dhclient; do # If a full path is given, use that and do not test if it works or not.
test -x "$client" || continue case "${with_dhcpcd}" in
case `"$client" --version 2>&1` in /*)
"isc-dhclient-"*) DHCP_CLIENT_PATH="$client"; break;; DHCPCD_PATH="${with_dhcpcd}"
esac AC_MSG_NOTICE(using dhcpcd at ${DHCPCD_PATH})
done ;;
if test -z "$DHCP_CLIENT_PATH"; then no) AC_MSG_NOTICE(dhcpcd support disabled)
AC_MSG_RESULT(no) ;;
if test -n "$with_dhcp_client"; then *)
AC_MSG_ERROR([Could not find ISC dhclient]) AC_MSG_CHECKING(for dhcpcd)
# We fully work with upstream dhcpcd-4
for path in /sbin /usr/sbin /usr/pkg/sbin /usr/local/sbin; do
test -x "${path}/dhclient" || continue
case `"$path/dhcpcd" --version 2>/dev/null` in
"dhcpcd "[123]*);;
"dhcpcd "*) DHCP_CLIENT_PATH="$path/dhcpcd"; break;;
esac
done
if test -n "${DHCPCD_PATH}"; then
AC_MSG_RESULT($DHCPCD_PATH)
else
AC_MSG_RESULT(no)
fi fi
else ;;
AC_MSG_RESULT($DHCP_CLIENT_PATH) esac
fi
fi if test -z "$DHCPCD_PATH" -a -z "$DHCLIENT_PATH"; then
if test -z "$DHCP_CLIENT_PATH" -a \( -z "$with_dhcp_client" -o x`basename "$with_dhcp_client"` = "xdhcpcd" \); then
test -n "$DHCP_CLIENT_PATH" && echo bar
# We fully work with upstream dhcpcd-4
AC_MSG_CHECKING([for dhcpcd])
for client in "$with_dhcp_client" /sbin/dhcpcd /usr/pkg/sbin/dhcpcd /usr/local/sbin/dhcpcd; do
test -x "$client" || continue
case `"$client" --version 2>/dev/null` in
"dhcpcd "[123]*);;
"dhcpcd "*) DHCP_CLIENT_PATH="$client"; break;;
esac
done
if test -z "$DHCP_CLIENT_PATH"; then
AC_MSG_RESULT(no)
if test -n "$with_dhcp_client"; then
AC_MSG_ERROR([Could not find dhcpcd-4 or newer])
fi
else
AC_MSG_RESULT($DHCP_CLIENT_PATH)
fi
fi
if test -z "$DHCP_CLIENT_PATH"; then
# DHCP clients are not a build time dependency, only runtime. # DHCP clients are not a build time dependency, only runtime.
# dhclient has been the longtime default for NM and it's in /sbin # dhclient has been the longtime default for NM and it's in /sbin
# in most distros, so use it. # in most distros, so use it.
AC_MSG_WARN([Could not find a suitable DHCP client]) AC_MSG_WARN([Could not find a suitable DHCP client])
DHCP_CLIENT_PATH=/sbin/dhclient DHCLIENT_PATH=/sbin/dhclient
AC_MSG_WARN([Falling back to ISC dhclient, ${DHCP_CLIENT_PATH}]) AC_MSG_WARN([Falling back to ISC dhclient, ${DHCP_CLIENT_PATH}])
fi fi
AC_SUBST(DHCP_CLIENT_PATH) AC_SUBST(DHCLIENT_PATH)
DHCP_CLIENT=`basename "$DHCP_CLIENT_PATH"` AC_SUBST(DHCPCD_PATH)
if test "$DHCP_CLIENT" != "dhclient" -a "$DHCP_CLIENT" != "dhcpcd"; then
AC_MSG_ERROR([No backend for the DHCP client ${DHCP_CLIENT}])
fi
AC_SUBST(DHCP_CLIENT)
# resolvconf support # resolvconf support
AC_ARG_WITH([resolvconf], AC_ARG_WITH([resolvconf],
@@ -500,12 +506,25 @@ examples/python/Makefile
AC_OUTPUT AC_OUTPUT
echo echo
echo Distribution targeting: ${with_distro} echo Distribution target: ${with_distro}
echo 'if this is not correct, please specifiy your distro with --with-distro=DISTRO' echo 'if this is not correct, please specifiy your distro with --with-distro=DISTRO'
echo
if test -n "${DHCLIENT_PATH}"; then
echo ISC dhclient support: ${DHCLIENT_PATH}
else
echo ISC dhclient support: no
fi
if test -n "${DHCPCD_PATH}"; then
echo dhcpcd support: ${DHCPCD_PATH}
else
echo dhcpcd support: no
fi
echo echo
echo Building documentation: ${with_docs} echo Building documentation: ${with_docs}
echo
echo Building tests: ${with_tests} echo Building tests: ${with_tests}
echo echo

View File

@@ -42,6 +42,7 @@
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config" #define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config" #define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config" #define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config"
#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config"
#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings" #define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings"

View File

@@ -23,5 +23,6 @@ EXTRA_DIST = \
nm-vpn-connection.xml \ nm-vpn-connection.xml \
nm-ppp-manager.xml \ nm-ppp-manager.xml \
nm-active-connection.xml \ nm-active-connection.xml \
nm-dhcp4-config.xml nm-dhcp4-config.xml \
nm-dhcp6-config.xml

View File

@@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<xi:include href="nm-ip4-config.xml"/> <xi:include href="nm-ip4-config.xml"/>
<xi:include href="nm-ip6-config.xml"/> <xi:include href="nm-ip6-config.xml"/>
<xi:include href="nm-dhcp4-config.xml"/> <xi:include href="nm-dhcp4-config.xml"/>
<xi:include href="nm-dhcp6-config.xml"/>
<xi:include href="nm-settings.xml"/> <xi:include href="nm-settings.xml"/>
<xi:include href="nm-exported-connection.xml"/> <xi:include href="nm-exported-connection.xml"/>
<xi:include href="nm-active-connection.xml"/> <xi:include href="nm-active-connection.xml"/>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.DHCP6Config">
<tp:docstring>
Options and configuration returned by the IPv6 DHCP server.
</tp:docstring>
<property name="Options" type="a{sv}" access="read">
<tp:docstring>Configuration options returned by a DHCP server, if any.</tp:docstring>
</property>
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
<tp:docstring>
A dictionary mapping property names to variant boxed values
</tp:docstring>
</arg>
</signal>
</interface>
</node>

View File

@@ -20,7 +20,8 @@ BUILT_SOURCES = \
nm-active-connection-bindings.h \ nm-active-connection-bindings.h \
nm-ip4-config-bindings.h \ nm-ip4-config-bindings.h \
nm-dhcp4-config-bindings.h \ nm-dhcp4-config-bindings.h \
nm-ip6-config-bindings.h nm-ip6-config-bindings.h \
nm-dhcp6-config-bindings.h
lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la
@@ -52,6 +53,7 @@ libnminclude_HEADERS = \
nm-active-connection.h \ nm-active-connection.h \
nm-dhcp4-config.h \ nm-dhcp4-config.h \
nm-ip6-config.h \ nm-ip6-config.h \
nm-dhcp6-config.h \
nm-remote-connection.h \ nm-remote-connection.h \
nm-settings-interface.h \ nm-settings-interface.h \
nm-settings-system-interface.h \ nm-settings-system-interface.h \
@@ -86,6 +88,7 @@ libnm_glib_la_SOURCES = \
nm-active-connection.c \ nm-active-connection.c \
nm-dhcp4-config.c \ nm-dhcp4-config.c \
nm-ip6-config.c \ nm-ip6-config.c \
nm-dhcp6-config.c \
nm-remote-connection.c \ nm-remote-connection.c \
nm-remote-connection-private.h \ nm-remote-connection-private.h \
nm-settings-interface.c \ nm-settings-interface.c \
@@ -172,6 +175,9 @@ nm-dhcp4-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
nm-ip6-config-bindings.h: $(top_srcdir)/introspection/nm-ip6-config.xml nm-ip6-config-bindings.h: $(top_srcdir)/introspection/nm-ip6-config.xml
dbus-binding-tool --prefix=nm_ip6_config --mode=glib-client --output=$@ $< dbus-binding-tool --prefix=nm_ip6_config --mode=glib-client --output=$@ $<
nm-dhcp6-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml
dbus-binding-tool --prefix=nm_dhcp6_config --mode=glib-client --output=$@ $<
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc

View File

@@ -59,6 +59,8 @@ typedef struct {
gboolean null_dhcp4_config; gboolean null_dhcp4_config;
NMIP6Config *ip6_config; NMIP6Config *ip6_config;
gboolean null_ip6_config; gboolean null_ip6_config;
NMDHCP6Config *dhcp6_config;
gboolean null_dhcp6_config;
NMDeviceState state; NMDeviceState state;
GUdevClient *client; GUdevClient *client;
@@ -79,6 +81,7 @@ enum {
PROP_STATE, PROP_STATE,
PROP_PRODUCT, PROP_PRODUCT,
PROP_VENDOR, PROP_VENDOR,
PROP_DHCP6_CONFIG,
LAST_PROP LAST_PROP
}; };
@@ -220,6 +223,46 @@ demarshal_ip6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
return TRUE; return TRUE;
} }
static gboolean
demarshal_dhcp6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
const char *path;
NMDHCP6Config *config = NULL;
DBusGConnection *connection;
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_dhcp6_config = FALSE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_dhcp6_config = TRUE;
else {
config = NM_DHCP6_CONFIG (_nm_object_cache_get (path));
if (config)
config = g_object_ref (config);
else {
connection = nm_object_get_connection (object);
config = NM_DHCP6_CONFIG (nm_dhcp6_config_new (connection, path));
}
}
}
if (priv->dhcp6_config) {
g_object_unref (priv->dhcp6_config);
priv->dhcp6_config = NULL;
}
if (config)
priv->dhcp6_config = config;
_nm_object_queue_notify (object, NM_DEVICE_DHCP6_CONFIG);
return TRUE;
}
static void static void
register_for_property_changed (NMDevice *device) register_for_property_changed (NMDevice *device)
{ {
@@ -230,9 +273,10 @@ register_for_property_changed (NMDevice *device)
{ NM_DEVICE_DRIVER, _nm_object_demarshal_generic, &priv->driver }, { NM_DEVICE_DRIVER, _nm_object_demarshal_generic, &priv->driver },
{ NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities }, { NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities },
{ NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed }, { NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed },
{ NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
{ NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config }, { NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config },
{ NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config }, { NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config },
{ NM_DEVICE_DHCP6_CONFIG, demarshal_dhcp6_config, &priv->dhcp6_config },
{ NULL }, { NULL },
}; };
@@ -318,6 +362,8 @@ dispose (GObject *object)
g_object_unref (priv->dhcp4_config); g_object_unref (priv->dhcp4_config);
if (priv->ip6_config) if (priv->ip6_config)
g_object_unref (priv->ip6_config); g_object_unref (priv->ip6_config);
if (priv->dhcp6_config)
g_object_unref (priv->dhcp6_config);
if (priv->client) if (priv->client)
g_object_unref (priv->client); g_object_unref (priv->client);
@@ -371,6 +417,9 @@ get_property (GObject *object,
case PROP_IP6_CONFIG: case PROP_IP6_CONFIG:
g_value_set_object (value, nm_device_get_ip6_config (device)); g_value_set_object (value, nm_device_get_ip6_config (device));
break; break;
case PROP_DHCP6_CONFIG:
g_value_set_object (value, nm_device_get_dhcp6_config (device));
break;
case PROP_STATE: case PROP_STATE:
g_value_set_uint (value, nm_device_get_state (device)); g_value_set_uint (value, nm_device_get_state (device));
break; break;
@@ -505,6 +554,19 @@ nm_device_class_init (NMDeviceClass *device_class)
NM_TYPE_IP6_CONFIG, NM_TYPE_IP6_CONFIG,
G_PARAM_READABLE)); G_PARAM_READABLE));
/**
* NMDevice:dhcp6-config:
*
* The #NMDHCP6Config of the device.
**/
g_object_class_install_property
(object_class, PROP_DHCP6_CONFIG,
g_param_spec_object (NM_DEVICE_DHCP6_CONFIG,
"DHCP6 Config",
"DHCP6 Config",
NM_TYPE_DHCP6_CONFIG,
G_PARAM_READABLE));
/** /**
* NMDevice:state: * NMDevice:state:
* *
@@ -870,6 +932,41 @@ nm_device_get_ip6_config (NMDevice *device)
return priv->ip6_config; return priv->ip6_config;
} }
/**
* nm_device_get_dhcp6_config:
* @device: a #NMDevice
*
* Gets the current #NMDHCP6Config associated with the #NMDevice.
*
* Returns: the #NMDHCPConfig or %NULL if the device is not activated or not
* using DHCP.
**/
NMDHCP6Config *
nm_device_get_dhcp6_config (NMDevice *device)
{
NMDevicePrivate *priv;
char *path;
GValue value = { 0, };
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->dhcp6_config)
return priv->dhcp6_config;
if (priv->null_dhcp6_config)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp6Config");
if (path) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_dhcp6_config (NM_OBJECT (device), NULL, &value, &priv->dhcp6_config);
g_value_unset (&value);
}
return priv->dhcp6_config;
}
/** /**
* nm_device_get_state: * nm_device_get_state:
* @device: a #NMDevice * @device: a #NMDevice

View File

@@ -32,6 +32,7 @@
#include "nm-ip4-config.h" #include "nm-ip4-config.h"
#include "nm-dhcp4-config.h" #include "nm-dhcp4-config.h"
#include "nm-ip6-config.h" #include "nm-ip6-config.h"
#include "nm-dhcp6-config.h"
#include "nm-connection.h" #include "nm-connection.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -51,6 +52,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_IP4_CONFIG "ip4-config" #define NM_DEVICE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_IP6_CONFIG "ip6-config" #define NM_DEVICE_IP6_CONFIG "ip6-config"
#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config"
#define NM_DEVICE_STATE "state" #define NM_DEVICE_STATE "state"
#define NM_DEVICE_VENDOR "vendor" #define NM_DEVICE_VENDOR "vendor"
#define NM_DEVICE_PRODUCT "product" #define NM_DEVICE_PRODUCT "product"
@@ -89,6 +91,7 @@ gboolean nm_device_get_managed (NMDevice *device);
NMIP4Config * nm_device_get_ip4_config (NMDevice *device); NMIP4Config * nm_device_get_ip4_config (NMDevice *device);
NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device); NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device);
NMIP6Config * nm_device_get_ip6_config (NMDevice *device); NMIP6Config * nm_device_get_ip6_config (NMDevice *device);
NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *device);
NMDeviceState nm_device_get_state (NMDevice *device); NMDeviceState nm_device_get_state (NMDevice *device);
const char * nm_device_get_product (NMDevice *device); const char * nm_device_get_product (NMDevice *device);
const char * nm_device_get_vendor (NMDevice *device); const char * nm_device_get_vendor (NMDevice *device);

View File

@@ -0,0 +1,248 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* libnm_glib -- Access network status & information from glib applications
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 - 2010 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
#include <string.h>
#include "nm-dhcp6-config.h"
#include "NetworkManager.h"
#include "nm-types-private.h"
#include "nm-object-private.h"
#include "nm-utils.h"
G_DEFINE_TYPE (NMDHCP6Config, nm_dhcp6_config, NM_TYPE_OBJECT)
#define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigPrivate))
typedef struct {
DBusGProxy *proxy;
GHashTable *options;
} NMDHCP6ConfigPrivate;
enum {
PROP_0,
PROP_OPTIONS,
LAST_PROP
};
static void
nm_dhcp6_config_init (NMDHCP6Config *config)
{
}
static void
copy_options (gpointer key, gpointer data, gpointer user_data)
{
GHashTable *options = (GHashTable *) user_data;
GValue *value = (GValue *) data;
g_hash_table_insert (options, g_strdup (key), g_value_dup_string (value));
}
static gboolean
demarshal_dhcp6_options (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
GHashTable *new_options;
g_hash_table_remove_all (priv->options);
new_options = g_value_get_boxed (value);
if (new_options)
g_hash_table_foreach (new_options, copy_options, priv->options);
_nm_object_queue_notify (object, NM_DHCP6_CONFIG_OPTIONS);
return TRUE;
}
static void
register_for_property_changed (NMDHCP6Config *config)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (config);
const NMPropertiesChangedInfo property_changed_info[] = {
{ NM_DHCP6_CONFIG_OPTIONS, demarshal_dhcp6_options, &priv->options },
{ NULL },
};
_nm_object_handle_properties_changed (NM_OBJECT (config),
priv->proxy,
property_changed_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
{
NMObject *object;
DBusGConnection *connection;
NMDHCP6ConfigPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
connection = nm_object_get_connection (object);
priv->proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
nm_object_get_path (object),
NM_DBUS_INTERFACE_DHCP6_CONFIG);
register_for_property_changed (NM_DHCP6_CONFIG (object));
return G_OBJECT (object);
}
static void
finalize (GObject *object)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
if (priv->options)
g_hash_table_destroy (priv->options);
g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->finalize (object);
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMDHCP6Config *self = NM_DHCP6_CONFIG (object);
switch (prop_id) {
case PROP_OPTIONS:
g_value_set_boxed (value, nm_dhcp6_config_get_options (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
g_type_class_add_private (config_class, sizeof (NMDHCP6ConfigPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->get_property = get_property;
object_class->finalize = finalize;
/* properties */
/**
* NMDHCP6Config:options:
*
* The #GHashTable containing options of the configuration.
**/
g_object_class_install_property
(object_class, PROP_OPTIONS,
g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS,
"Options",
"Options",
G_TYPE_HASH_TABLE,
G_PARAM_READABLE));
}
/**
* nm_dhcp6_config_new:
* @connection: the #DBusGConnection
* @object_path: the DBus object path of the device
*
* Creates a new #NMDHCP6Config.
*
* Returns: a new configuration
**/
GObject *
nm_dhcp6_config_new (DBusGConnection *connection, const char *object_path)
{
return (GObject *) g_object_new (NM_TYPE_DHCP6_CONFIG,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, object_path,
NULL);
}
/**
* nm_dhcp6_config_get_options:
* @config: a #NMDHCP6Config
*
* Gets all the options contained in the configuration.
*
* Returns: the #GHashTable containing strings for keys and values.
* This is the internal copy used by the configuration, and must not be modified.
**/
GHashTable *
nm_dhcp6_config_get_options (NMDHCP6Config *config)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (config);
GValue value = { 0, };
if (g_hash_table_size (priv->options))
return priv->options;
if (!_nm_object_get_property (NM_OBJECT (config),
"org.freedesktop.DBus.Properties",
"Options",
&value))
goto out;
demarshal_dhcp6_options (NM_OBJECT (config), NULL, &value, &priv->options);
g_value_unset (&value);
out:
return priv->options;
}
/**
* nm_dhcp6_config_get_one_option:
* @config: a #NMDHCP6Config
* @option: the option to retrieve
*
* Gets one option by option name.
*
* Returns: the configuration option's value. This is the internal string used by the
* configuration, and must not be modified.
**/
const char *
nm_dhcp6_config_get_one_option (NMDHCP6Config *config, const char *option)
{
g_return_val_if_fail (NM_IS_DHCP6_CONFIG (config), NULL);
return g_hash_table_lookup (nm_dhcp6_config_get_options (config), option);
}

View File

@@ -0,0 +1,68 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* libnm_glib -- Access network status & information from glib applications
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 - 2010 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
#ifndef NM_DHCP6_CONFIG_H
#define NM_DHCP6_CONFIG_H
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "nm-object.h"
G_BEGIN_DECLS
#define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type ())
#define NM_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP6_CONFIG, NMDHCP6Config))
#define NM_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigClass))
#define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP6_CONFIG))
#define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP6_CONFIG))
typedef struct {
NMObject parent;
} NMDHCP6Config;
typedef struct {
NMObjectClass parent;
/* Padding for future expansion */
void (*_reserved1) (void);
void (*_reserved2) (void);
void (*_reserved3) (void);
void (*_reserved4) (void);
void (*_reserved5) (void);
void (*_reserved6) (void);
} NMDHCP6ConfigClass;
#define NM_DHCP6_CONFIG_OPTIONS "options"
GType nm_dhcp6_config_get_type (void);
GObject *nm_dhcp6_config_new (DBusGConnection *connection, const char *object_path);
GHashTable * nm_dhcp6_config_get_options (NMDHCP6Config *config);
const char * nm_dhcp6_config_get_one_option (NMDHCP6Config *config, const char *option);
G_END_DECLS
#endif /* NM_DHCP6_CONFIG_H */

View File

@@ -19,7 +19,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA. * Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2007 - 2008 Red Hat, Inc. * (C) Copyright 2007 - 2010 Red Hat, Inc.
*/ */
#include <string.h> #include <string.h>
@@ -435,26 +435,23 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_IP6_CONFIG_ADDRESSES); NM_SETTING_IP6_CONFIG_ADDRESSES);
return FALSE; return FALSE;
} }
} else if ( !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) } else if ( !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
|| !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
|| !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) || !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)
|| !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { || !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
if (!priv->ignore_auto_dns) { if (g_slist_length (priv->dns)) {
if (priv->dns && g_slist_length (priv->dns)) { g_set_error (error,
g_set_error (error, NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR, NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, NM_SETTING_IP6_CONFIG_DNS);
NM_SETTING_IP6_CONFIG_DNS); return FALSE;
return FALSE; }
}
if (g_slist_length (priv->dns_search)) { if (g_slist_length (priv->dns_search)) {
g_set_error (error, g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR, NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_DNS_SEARCH); NM_SETTING_IP6_CONFIG_DNS_SEARCH);
return FALSE; return FALSE;
}
} }
if (g_slist_length (priv->addresses)) { if (g_slist_length (priv->addresses)) {
@@ -464,6 +461,9 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_IP6_CONFIG_ADDRESSES); NM_SETTING_IP6_CONFIG_ADDRESSES);
return FALSE; return FALSE;
} }
} else if ( !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|| !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
/* nothing to do */
} else { } else {
g_set_error (error, g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR, NM_SETTING_IP6_CONFIG_ERROR,
@@ -598,30 +598,33 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
* *
* IPv6 configuration method. If 'auto' is specified then the appropriate * IPv6 configuration method. If 'auto' is specified then the appropriate
* automatic method (DHCP, PPP, advertisement, etc) is used for the * automatic method (DHCP, PPP, advertisement, etc) is used for the
* interface and most other properties can be left unset. If 'link-local' * interface and most other properties can be left unset. To force the use
* is specified, then an IPv6 link-local address will be assigned to the * of DHCP only, specify 'dhcp'; this method is only valid for ethernet-
* interface. If 'manual' is specified, static IP addressing is used and * based hardware. If 'link-local' is specified, then an IPv6 link-local
* at least one IP address must be given in the 'addresses' property. If * address will be assigned to the interface. If 'manual' is specified,
* 'ignored' is specified, IPv6 configuration is not done. This property * static IP addressing is used and at least one IP address must be given
* must be set. NOTE: DHCP configuration and the 'shared' method are not * in the 'addresses' property. If 'ignored' is specified, IPv6
* yet supported. * configuration is not done. This property must be set. NOTE: the 'shared'
* method are not yet supported.
**/ **/
g_object_class_install_property g_object_class_install_property
(object_class, PROP_METHOD, (object_class, PROP_METHOD,
g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD, g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD,
"Method", "Method",
"IPv6 configuration method. If 'auto' is specified " "IPv6 configuration method. If 'auto' is specified "
"then the appropriate automatic method (DHCP, PPP, " "then the appropriate automatic method (PPP, router "
"advertisement, etc) is used for the device and " "advertisement, etc) is used for the device and "
"most other properties can be left unset. If " "most other properties can be left unset. To force "
"the use of DHCP only, specify 'dhcp'; this method "
"is only valid for ethernet-based hardware. If "
"'link-local' is specified, then an IPv6 link-local " "'link-local' is specified, then an IPv6 link-local "
"address will be assigned to the interface. If " "address will be assigned to the interface. If "
"'manual' is specified, static IP addressing is " "'manual' is specified, static IP addressing is "
"used and at least one IP address must be given in " "used and at least one IP address must be given in "
" the 'addresses' property. If 'ignored' is " " the 'addresses' property. If 'ignored' is "
"specified, IPv6 configuration is not done. This " "specified, IPv6 configuration is not done. This "
"property must be set. NOTE: DHCP configuration " "property must be set. NOTE: the 'shared' method"
"and the 'shared' method are not yet supported.", "is not yet supported.",
NULL, NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
@@ -740,38 +743,39 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
/** /**
* NMSettingIP6Config:ignore-auto-routes: * NMSettingIP6Config:ignore-auto-routes:
* *
* When the method is set to 'auto' and this property to TRUE, automatically * When the method is set to 'auto' or 'dhcp' and this property is set to
* configured routes are ignored and only routes specified in * TRUE, automatically configured routes are ignored and only routes
* #NMSettingIP6Config:routes, if any, are used. * specified in #NMSettingIP6Config:routes, if any, are used.
**/ **/
g_object_class_install_property g_object_class_install_property
(object_class, PROP_IGNORE_AUTO_ROUTES, (object_class, PROP_IGNORE_AUTO_ROUTES,
g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES,
"Ignore automatic routes", "Ignore automatic routes",
"When the method is set to 'auto' and this property " "When the method is set to 'auto' or 'dhcp' and this "
"to TRUE, automatically configured routes are " "property is set to TRUE, automatically configured "
"ignored and only routes specified in the 'routes' " "routes are ignored and only routes specified in the "
"property, if any, are used.", "'routes' property, if any, are used.",
FALSE, FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
/** /**
* NMSettingIP6Config:ignore-auto-dns: * NMSettingIP6Config:ignore-auto-dns:
* *
* When the method is set to 'auto' and this property to TRUE, automatically * When the method is set to 'auto' or 'dhcp' and this property is set to
* configured nameservers and search domains are ignored and only namservers * TRUE, automatically configured nameservers and search domains are ignored
* and search domains specified in #NMSettingIP6Config:dns and * and only namservers and search domains specified in
* #NMSettingIP6Config:dns-search, if any, are used. * #NMSettingIP6Config:dns and #NMSettingIP6Config:dns-search, if any, are
* used.
**/ **/
g_object_class_install_property g_object_class_install_property
(object_class, PROP_IGNORE_AUTO_DNS, (object_class, PROP_IGNORE_AUTO_DNS,
g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS,
"Ignore DHCPv6/RDNSS DNS", "Ignore DHCPv6/RDNSS DNS",
"When the method is set to 'auto' and this property " "When the method is set to 'auto' or 'dhcp' and this "
"to TRUE, automatically configured nameservers and " "property is set to TRUE, automatically configured "
"search domains are ignored and only namservers and " "nameservers and search domains are ignored and only "
"search domains specified in the 'dns' and 'dns-search' " "namservers and search domains specified in the 'dns' "
"properties, if any, are used.", "and 'dns-search' properties, if any, are used.",
FALSE, FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));

View File

@@ -19,7 +19,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA. * Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2007 - 2008 Red Hat, Inc. * (C) Copyright 2007 - 2010 Red Hat, Inc.
*/ */
#ifndef NM_SETTING_IP6_CONFIG_H #ifndef NM_SETTING_IP6_CONFIG_H
@@ -65,6 +65,7 @@ GQuark nm_setting_ip6_config_error_quark (void);
#define NM_SETTING_IP6_CONFIG_METHOD_IGNORE "ignore" #define NM_SETTING_IP6_CONFIG_METHOD_IGNORE "ignore"
#define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto" #define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto"
#define NM_SETTING_IP6_CONFIG_METHOD_DHCP "dhcp"
#define NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL "link-local" #define NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL "link-local"
#define NM_SETTING_IP6_CONFIG_METHOD_MANUAL "manual" #define NM_SETTING_IP6_CONFIG_METHOD_MANUAL "manual"
#define NM_SETTING_IP6_CONFIG_METHOD_SHARED "shared" #define NM_SETTING_IP6_CONFIG_METHOD_SHARED "shared"

View File

@@ -118,7 +118,7 @@ int main (int argc, char **argv)
test_defaults (NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_SETTING_NAME); test_defaults (NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_SETTING_NAME);
test_defaults (NM_TYPE_SETTING_GSM, NM_SETTING_GSM_SETTING_NAME); test_defaults (NM_TYPE_SETTING_GSM, NM_SETTING_GSM_SETTING_NAME);
test_defaults (NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_SETTING_NAME); test_defaults (NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_SETTING_NAME);
// test_defaults (NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_SETTING_NAME); test_defaults (NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_SETTING_NAME);
test_defaults (NM_TYPE_SETTING_PPP, NM_SETTING_PPP_SETTING_NAME); test_defaults (NM_TYPE_SETTING_PPP, NM_SETTING_PPP_SETTING_NAME);
test_defaults (NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_SETTING_NAME); test_defaults (NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_SETTING_NAME);
test_defaults (NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_SETTING_NAME); test_defaults (NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_SETTING_NAME);

View File

@@ -16,6 +16,7 @@ VOID:STRING,STRING,STRING,UINT
VOID:OBJECT,UINT,UINT VOID:OBJECT,UINT,UINT
VOID:STRING,INT VOID:STRING,INT
VOID:STRING,UINT VOID:STRING,UINT
VOID:STRING,UINT,BOOLEAN
VOID:OBJECT,OBJECT,ENUM VOID:OBJECT,OBJECT,ENUM
VOID:POINTER,STRING VOID:POINTER,STRING
VOID:STRING,BOXED VOID:STRING,BOXED

View File

@@ -37,6 +37,7 @@ noinst_LTLIBRARIES = libtest-dhcp.la
libtest_dhcp_la_SOURCES = \ libtest_dhcp_la_SOURCES = \
nm-ip4-config.c \ nm-ip4-config.c \
nm-ip6-config.c \
nm-hostname-provider.c \ nm-hostname-provider.c \
nm-dbus-manager.c nm-dbus-manager.c
@@ -46,6 +47,7 @@ libtest_dhcp_la_CPPFLAGS = \
$(LIBNL_CFLAGS) $(LIBNL_CFLAGS)
libtest_dhcp_la_LIBADD = \ libtest_dhcp_la_LIBADD = \
$(top_builddir)/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-util/libnm-util.la \
$(GLIB_LIBS) \ $(GLIB_LIBS) \
$(DBUS_LIBS) \ $(DBUS_LIBS) \
@@ -113,6 +115,8 @@ NetworkManager_SOURCES = \
nm-netlink.h \ nm-netlink.h \
nm-dhcp4-config.c \ nm-dhcp4-config.c \
nm-dhcp4-config.h \ nm-dhcp4-config.h \
nm-dhcp6-config.c \
nm-dhcp6-config.h \
nm-rfkill.h nm-rfkill.h
nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml
@@ -148,6 +152,9 @@ nm-active-connection-glue.h: $(top_srcdir)/introspection/nm-active-connection.xm
nm-dhcp4-config-glue.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml nm-dhcp4-config-glue.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
dbus-binding-tool --prefix=nm_dhcp4_config --mode=glib-server --output=$@ $< dbus-binding-tool --prefix=nm_dhcp4_config --mode=glib-server --output=$@ $<
nm-dhcp6-config-glue.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml
dbus-binding-tool --prefix=nm_dhcp6_config --mode=glib-server --output=$@ $<
BUILT_SOURCES = \ BUILT_SOURCES = \
nm-access-point-glue.h \ nm-access-point-glue.h \
nm-manager-glue.h \ nm-manager-glue.h \
@@ -159,7 +166,8 @@ BUILT_SOURCES = \
nm-ip4-config-glue.h \ nm-ip4-config-glue.h \
nm-ip6-config-glue.h \ nm-ip6-config-glue.h \
nm-active-connection-glue.h \ nm-active-connection-glue.h \
nm-dhcp4-config-glue.h nm-dhcp4-config-glue.h \
nm-dhcp6-config-glue.h
NetworkManager_CPPFLAGS = \ NetworkManager_CPPFLAGS = \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \

View File

@@ -302,7 +302,10 @@ done:
} }
static gboolean static gboolean
parse_config_file (const char *filename, char **plugins, GError **error) parse_config_file (const char *filename,
char **plugins,
char **dhcp_client,
GError **error)
{ {
GKeyFile *config; GKeyFile *config;
@@ -321,6 +324,8 @@ parse_config_file (const char *filename, char **plugins, GError **error)
if (*error) if (*error)
return FALSE; return FALSE;
*dhcp_client = g_key_file_get_value (config, "main", "dhcp", NULL);
g_key_file_free (config); g_key_file_free (config);
return TRUE; return TRUE;
} }
@@ -435,7 +440,7 @@ main (int argc, char *argv[])
gboolean become_daemon = FALSE; gboolean become_daemon = FALSE;
gboolean g_fatal_warnings = FALSE; gboolean g_fatal_warnings = FALSE;
char *pidfile = NULL, *user_pidfile = NULL; char *pidfile = NULL, *user_pidfile = NULL;
char *config = NULL, *plugins = NULL; char *config = NULL, *plugins = NULL, *dhcp = NULL;
char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE; char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE;
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE; gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE;
gboolean success; gboolean success;
@@ -498,7 +503,7 @@ main (int argc, char *argv[])
/* Parse the config file */ /* Parse the config file */
if (config) { if (config) {
if (!parse_config_file (config, &plugins, &error)) { if (!parse_config_file (config, &plugins, &dhcp, &error)) {
g_warning ("Config file %s invalid: (%d) %s.", g_warning ("Config file %s invalid: (%d) %s.",
config, config,
error ? error->code : -1, error ? error->code : -1,
@@ -507,7 +512,7 @@ main (int argc, char *argv[])
} }
} else { } else {
config = NM_DEFAULT_SYSTEM_CONF_FILE; config = NM_DEFAULT_SYSTEM_CONF_FILE;
if (!parse_config_file (config, &plugins, &error)) { if (!parse_config_file (config, &plugins, &dhcp, &error)) {
g_warning ("Default config file %s invalid: (%d) %s.", g_warning ("Default config file %s invalid: (%d) %s.",
config, config,
error ? error->code : -1, error ? error->code : -1,
@@ -620,9 +625,9 @@ main (int argc, char *argv[])
goto done; goto done;
} }
dhcp_mgr = nm_dhcp_manager_get (); dhcp_mgr = nm_dhcp_manager_new (dhcp ? dhcp : "dhclient", &error);
if (!dhcp_mgr) { if (!dhcp_mgr) {
nm_warning ("Failed to start the DHCP manager."); nm_warning ("Failed to start the DHCP manager: %s.", error->message);
goto done; goto done;
} }

View File

@@ -9,9 +9,14 @@ INCLUDES = \
noinst_LTLIBRARIES = libdhcp-manager.la noinst_LTLIBRARIES = libdhcp-manager.la
libdhcp_manager_la_SOURCES = \ libdhcp_manager_la_SOURCES = \
nm-dhcp-client.c \
nm-dhcp-client.h \
nm-dhcp-manager.c \ nm-dhcp-manager.c \
nm-dhcp-manager.h \ nm-dhcp-manager.h \
nm-dhcp-@DHCP_CLIENT@.c nm-dhcp-dhclient.h \
nm-dhcp-dhclient.c \
nm-dhcp-dhcpcd.h \
nm-dhcp-dhcpcd.c
libdhcp_manager_la_CPPFLAGS = \ libdhcp_manager_la_CPPFLAGS = \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
@@ -22,13 +27,11 @@ libdhcp_manager_la_CPPFLAGS = \
-DSYSCONFDIR=\"$(sysconfdir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \
-DLIBEXECDIR=\"$(libexecdir)\" \ -DLIBEXECDIR=\"$(libexecdir)\" \
-DLOCALSTATEDIR=\"$(localstatedir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" \
-DDHCP_CLIENT_PATH=\"$(DHCP_CLIENT_PATH)\" -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
libdhcp_manager_la_LIBADD = \ libdhcp_manager_la_LIBADD = \
$(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/marshallers/libmarshallers.la \
$(DBUS_LIBS) \ $(DBUS_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
EXTRA_DIST = \
nm-dhcp-dhclient.c \
nm-dhcp-dhcpcd.c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,138 @@
/* -*- 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_CLIENT_H
#define NM_DHCP_CLIENT_H
#include <glib.h>
#include <glib-object.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
#include <nm-ip4-config.h>
#include <nm-ip6-config.h>
#define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ())
#define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDHCPClient))
#define NM_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CLIENT, NMDHCPClientClass))
#define NM_IS_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_CLIENT))
#define NM_IS_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP_CLIENT))
#define NM_DHCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_CLIENT, NMDHCPClientClass))
#define NM_DHCP_CLIENT_INTERFACE "iface"
#define NM_DHCP_CLIENT_IPV6 "ipv6"
#define NM_DHCP_CLIENT_UUID "uuid"
#define NM_DHCP_CLIENT_TIMEOUT "timeout"
typedef enum {
DHC_NBI = 0, /* no broadcast interfaces found */
DHC_PREINIT, /* configuration started */
DHC_PREINIT6, /* configuration started */
DHC_BOUND4, /* IPv4 lease obtained */
DHC_BOUND6, /* IPv6 lease obtained */
DHC_IPV4LL, /* IPv4LL address obtained */
DHC_RENEW4, /* IPv4 lease renewed */
DHC_RENEW6, /* IPv6 lease renewed */
DHC_REBOOT, /* have valid lease, but now obtained a different one */
DHC_REBIND4, /* IPv4 new/different lease */
DHC_REBIND6, /* IPv6 new/different lease */
DHC_DEPREF6, /* IPv6 lease depreferred */
DHC_STOP, /* remove old lease */
DHC_MEDIUM, /* media selection begun */
DHC_TIMEOUT, /* timed out contacting DHCP server */
DHC_FAIL, /* all attempts to contact server timed out, sleeping */
DHC_EXPIRE, /* lease has expired, renewing */
DHC_RELEASE, /* releasing lease */
DHC_START, /* sent when dhclient started OK */
DHC_ABEND, /* dhclient exited abnormally */
DHC_END, /* dhclient exited normally */
DHC_END_OPTIONS, /* last option in subscription sent */
} NMDHCPState;
typedef struct {
GObject parent;
} NMDHCPClient;
typedef struct {
GObjectClass parent;
/* Methods */
/* Given the options table, extract any classless routes, add them to
* the IP4 config and return TRUE if any existed. If a gateway was sent
* as a classless route return that in out_gwaddr.
*/
gboolean (*ip4_process_classless_routes) (NMDHCPClient *self,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *out_gwaddr);
GPid (*ip4_start) (NMDHCPClient *self,
NMSettingIP4Config *s_ip4,
guint8 *anycast_addr);
GPid (*ip6_start) (NMDHCPClient *self,
NMSettingIP6Config *s_ip6,
guint8 *anycast_addr,
gboolean info_only);
void (*stop) (NMDHCPClient *self);
/* Signals */
void (*state_changed) (NMDHCPClient *self, NMDHCPState state);
void (*timeout) (NMDHCPClient *self);
} NMDHCPClientClass;
GType nm_dhcp_client_get_type (void);
GPid nm_dhcp_client_get_pid (NMDHCPClient *self);
const char *nm_dhcp_client_get_iface (NMDHCPClient *self);
gboolean nm_dhcp_client_get_ipv6 (NMDHCPClient *self);
const char *nm_dhcp_client_get_uuid (NMDHCPClient *self);
gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr);
gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self,
NMSettingIP6Config *s_ip6,
guint8 *dhcp_anycast_addr,
gboolean info_only);
void nm_dhcp_client_stop (NMDHCPClient *self);
void nm_dhcp_client_new_options (NMDHCPClient *self,
GHashTable *options,
const char *reason);
gboolean nm_dhcp_client_foreach_option (NMDHCPClient *self,
GHFunc func,
gpointer user_data);
NMIP4Config *nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test);
NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test);
/* Backend helpers */
void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name);
#endif /* NM_DHCP_CLIENT_H */

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2005 - 2008 Red Hat, Inc. * Copyright (C) 2005 - 2010 Red Hat, Inc.
*/ */
#define _XOPEN_SOURCE #define _XOPEN_SOURCE
@@ -36,46 +36,38 @@
#include <config.h> #include <config.h>
#include "nm-dhcp-manager.h" #include "nm-dhcp-dhclient.h"
#include "nm-utils.h" #include "nm-utils.h"
G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
#define NM_DHCP_MANAGER_PID_FILENAME "dhclient" #define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientPrivate))
#define NM_DHCP_MANAGER_PID_FILE_EXT "pid"
#if defined(TARGET_DEBIAN) #if defined(TARGET_DEBIAN)
#define NM_DHCP_MANAGER_LEASE_DIR LOCALSTATEDIR "/lib/dhcp3" #define NM_DHCLIENT_LEASE_DIR LOCALSTATEDIR "/lib/dhcp3"
#elif defined(TARGET_SUSE) || defined(TARGET_MANDRIVA) #elif defined(TARGET_SUSE) || defined(TARGET_MANDRIVA)
#define NM_DHCP_MANAGER_LEASE_DIR LOCALSTATEDIR "/lib/dhcp" #define NM_DHCLIENT_LEASE_DIR LOCALSTATEDIR "/lib/dhcp"
#else #else
#define NM_DHCP_MANAGER_LEASE_DIR LOCALSTATEDIR "/lib/dhclient" #define NM_DHCLIENT_LEASE_DIR LOCALSTATEDIR "/lib/dhclient"
#endif #endif
#define NM_DHCP_MANAGER_LEASE_FILENAME "dhclient"
#define NM_DHCP_MANAGER_LEASE_FILE_EXT "lease"
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action" #define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action"
typedef struct {
static char * char *conf_file;
get_pidfile_for_iface (const char * iface) char *lease_file;
{ char *pid_file;
return g_strdup_printf ("%s/%s-%s.%s", } NMDHCPDhclientPrivate;
NM_DHCP_MANAGER_RUN_DIR,
NM_DHCP_MANAGER_PID_FILENAME,
iface,
NM_DHCP_MANAGER_PID_FILE_EXT);
}
static char * static char *
get_leasefile_for_iface (const char * iface, const char *uuid) get_leasefile_for_iface (const char * iface, const char *uuid, gboolean ipv6)
{ {
return g_strdup_printf ("%s/%s-%s-%s.%s", return g_strdup_printf ("%s/dhclient%s-%s-%s.lease",
NM_DHCP_MANAGER_LEASE_DIR, NM_DHCLIENT_LEASE_DIR,
NM_DHCP_MANAGER_LEASE_FILENAME, ipv6 ? "6" : "",
uuid, uuid,
iface, iface);
NM_DHCP_MANAGER_LEASE_FILE_EXT);
} }
static void static void
@@ -119,7 +111,7 @@ add_lease_option (GHashTable *hash, char *line)
} }
GSList * GSList *
nm_dhcp_client_get_lease_ip4_config (const char *iface, const char *uuid) nm_dhcp_dhclient_get_lease_config (const char *iface, const char *uuid)
{ {
GSList *parsed = NULL, *iter, *leases = NULL; GSList *parsed = NULL, *iter, *leases = NULL;
char *contents = NULL; char *contents = NULL;
@@ -127,7 +119,7 @@ nm_dhcp_client_get_lease_ip4_config (const char *iface, const char *uuid)
char **line, **split = NULL; char **line, **split = NULL;
GHashTable *hash = NULL; GHashTable *hash = NULL;
leasefile = get_leasefile_for_iface (iface, uuid); leasefile = get_leasefile_for_iface (iface, uuid, FALSE);
if (!leasefile) if (!leasefile)
return NULL; return NULL;
@@ -288,28 +280,39 @@ out:
#define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager" #define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager"
static gboolean static gboolean
merge_dhclient_config (NMDHCPDevice *device, merge_dhclient_config (const char *iface,
const char *conf_file,
NMSettingIP4Config *s_ip4, NMSettingIP4Config *s_ip4,
guint8 *anycast_addr, guint8 *anycast_addr,
const char *contents, const char *orig_path,
const char *orig,
GError **error) GError **error)
{ {
GString *new_contents; GString *new_contents;
char *orig_contents = NULL;
gboolean success = FALSE; gboolean success = FALSE;
g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (device->iface != NULL, FALSE); g_return_val_if_fail (conf_file != NULL, FALSE);
new_contents = g_string_new (_("# Created by NetworkManager\n")); new_contents = g_string_new (_("# Created by NetworkManager\n"));
if (g_file_test (orig_path, G_FILE_TEST_EXISTS)) {
GError *read_error = NULL;
if (!g_file_get_contents (orig_path, &orig_contents, NULL, &read_error)) {
nm_warning ("%s: error reading dhclient configuration %s: %s",
iface, orig_path, read_error->message);
g_error_free (read_error);
}
}
/* Add existing options, if any, but ignore stuff NM will replace. */ /* Add existing options, if any, but ignore stuff NM will replace. */
if (contents) { if (orig_contents) {
char **lines = NULL, **line; char **lines = NULL, **line;
g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig); g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);
lines = g_strsplit_set (contents, "\n\r", 0); lines = g_strsplit_set (orig_contents, "\n\r", 0);
for (line = lines; lines && *line; line++) { for (line = lines; lines && *line; line++) {
gboolean ignore = FALSE; gboolean ignore = FALSE;
@@ -334,6 +337,7 @@ merge_dhclient_config (NMDHCPDevice *device,
if (lines) if (lines)
g_strfreev (lines); g_strfreev (lines);
g_free (orig_contents);
} else } else
g_string_append_c (new_contents, '\n'); g_string_append_c (new_contents, '\n');
@@ -374,14 +378,13 @@ merge_dhclient_config (NMDHCPDevice *device,
" initial-interval 1; \n" " initial-interval 1; \n"
" anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n"
"}\n", "}\n",
device->iface, iface,
anycast_addr[0], anycast_addr[1], anycast_addr[0], anycast_addr[1],
anycast_addr[2], anycast_addr[3], anycast_addr[2], anycast_addr[3],
anycast_addr[4], anycast_addr[5]); anycast_addr[4], anycast_addr[5]);
} }
if (g_file_set_contents (device->conf_file, new_contents->str, -1, error)) success = g_file_set_contents (conf_file, new_contents->str, -1, error);
success = TRUE;
g_string_free (new_contents, TRUE); g_string_free (new_contents, TRUE);
return success; return success;
@@ -393,17 +396,16 @@ merge_dhclient_config (NMDHCPDevice *device,
* read their single config file and merge that into a custom per-interface * read their single config file and merge that into a custom per-interface
* config file along with the NM options. * config file along with the NM options.
*/ */
static gboolean static char *
create_dhclient_config (NMDHCPDevice *device, create_dhclient_config (const char *iface,
NMSettingIP4Config *s_ip4, NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr) guint8 *dhcp_anycast_addr)
{ {
char *orig = NULL, *contents = NULL; char *orig = NULL, *tmp, *conf_file = NULL;
GError *error = NULL; GError *error = NULL;
gboolean success = FALSE; gboolean success = FALSE;
char *tmp;
g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
#if defined(TARGET_SUSE) #if defined(TARGET_SUSE)
orig = g_strdup (SYSCONFDIR "/dhclient.conf"); orig = g_strdup (SYSCONFDIR "/dhclient.conf");
@@ -412,41 +414,28 @@ create_dhclient_config (NMDHCPDevice *device,
#elif defined(TARGET_GENTOO) #elif defined(TARGET_GENTOO)
orig = g_strdup (SYSCONFDIR "/dhcp/dhclient.conf"); orig = g_strdup (SYSCONFDIR "/dhcp/dhclient.conf");
#else #else
orig = g_strdup_printf (SYSCONFDIR "/dhclient-%s.conf", device->iface); orig = g_strdup_printf (SYSCONFDIR "/dhclient-%s.conf", iface);
#endif #endif
if (!orig) { if (!orig) {
nm_warning ("%s: not enough memory for dhclient options.", device->iface); nm_warning ("%s: not enough memory for dhclient options.", iface);
return FALSE; return FALSE;
} }
tmp = g_strdup_printf ("nm-dhclient-%s.conf", device->iface); tmp = g_strdup_printf ("nm-dhclient-%s.conf", iface);
device->conf_file = g_build_filename ("/var", "run", tmp, NULL); conf_file = g_build_filename ("/var", "run", tmp, NULL);
g_free (tmp); g_free (tmp);
if (!g_file_test (orig, G_FILE_TEST_EXISTS))
goto out;
if (!g_file_get_contents (orig, &contents, NULL, &error)) {
nm_warning ("%s: error reading dhclient configuration %s: %s",
device->iface, orig, error->message);
g_error_free (error);
goto out;
}
out:
error = NULL; error = NULL;
if (merge_dhclient_config (device, s_ip4, dhcp_anycast_addr, contents, orig, &error)) success = merge_dhclient_config (iface, conf_file, s_ip4, dhcp_anycast_addr, orig, &error);
success = TRUE; if (!success) {
else {
nm_warning ("%s: error creating dhclient configuration: %s", nm_warning ("%s: error creating dhclient configuration: %s",
device->iface, error->message); iface, error->message);
g_error_free (error); g_error_free (error);
} }
g_free (contents);
g_free (orig); g_free (orig);
return success; return conf_file;
} }
@@ -458,80 +447,129 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED)
setpgid (pid, pid); setpgid (pid, pid);
} }
static GPid
GPid dhclient_start (NMDHCPClient *client,
nm_dhcp_client_start (NMDHCPDevice *device, const char *ip_opt,
const char *uuid, const char *mode_opt)
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
{ {
GPtrArray *dhclient_argv = NULL; NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
GPtrArray *argv = NULL;
GPid pid = 0; GPid pid = 0;
GError *error = NULL; GError *error = NULL;
char *pid_contents = NULL; const char *iface, *uuid;
char *binary_name;
gboolean ipv6;
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) { g_return_val_if_fail (priv->pid_file == NULL, -1);
nm_warning (DHCP_CLIENT_PATH " does not exist."); g_return_val_if_fail (ip_opt != NULL, -1);
goto out;
iface = nm_dhcp_client_get_iface (client);
uuid = nm_dhcp_client_get_uuid (client);
ipv6 = nm_dhcp_client_get_ipv6 (client);
priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid",
ipv6 ? "6" : "",
iface);
if (!priv->pid_file) {
nm_warning ("%s: not enough memory for dhcpcd options.", iface);
return -1;
} }
device->pid_file = get_pidfile_for_iface (device->iface); if (!g_file_test (DHCLIENT_PATH, G_FILE_TEST_EXISTS)) {
if (!device->pid_file) { nm_warning (DHCLIENT_PATH " does not exist.");
nm_warning ("%s: not enough memory for dhclient options.", device->iface); return -1;
goto out;
} }
device->lease_file = get_leasefile_for_iface (device->iface, uuid); /* Kill any existing dhclient from the pidfile */
if (!device->lease_file) { binary_name = g_path_get_basename (DHCLIENT_PATH);
nm_warning ("%s: not enough memory for dhclient options.", device->iface); nm_dhcp_client_stop_existing (priv->pid_file, binary_name);
goto out; g_free (binary_name);
priv->lease_file = get_leasefile_for_iface (iface, uuid, ipv6);
if (!priv->lease_file) {
nm_warning ("%s: not enough memory for dhclient options.", iface);
return -1;
} }
if (!create_dhclient_config (device, s_ip4, dhcp_anycast_addr)) argv = g_ptr_array_new ();
goto out; g_ptr_array_add (argv, (gpointer) DHCLIENT_PATH);
/* Kill any existing dhclient bound to this interface */ g_ptr_array_add (argv, (gpointer) "-d");
if (g_file_get_contents (device->pid_file, &pid_contents, NULL, NULL)) {
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
if (!((tmp == ULONG_MAX) && (errno == ERANGE))) g_ptr_array_add (argv, (gpointer) ip_opt);
nm_dhcp_client_stop (device, (pid_t) tmp);
remove (device->pid_file); if (mode_opt)
g_ptr_array_add (argv, (gpointer) mode_opt);
g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */
g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH );
g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */
g_ptr_array_add (argv, (gpointer) priv->pid_file);
g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */
g_ptr_array_add (argv, (gpointer) priv->lease_file);
if (priv->conf_file) {
g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */
g_ptr_array_add (argv, (gpointer) priv->conf_file);
} }
dhclient_argv = g_ptr_array_new (); g_ptr_array_add (argv, (gpointer) iface);
g_ptr_array_add (dhclient_argv, (gpointer) DHCP_CLIENT_PATH); g_ptr_array_add (argv, NULL);
g_ptr_array_add (dhclient_argv, (gpointer) "-d"); if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
g_ptr_array_add (dhclient_argv, (gpointer) "-sf"); /* Set script file */
g_ptr_array_add (dhclient_argv, (gpointer) ACTION_SCRIPT_PATH );
g_ptr_array_add (dhclient_argv, (gpointer) "-pf"); /* Set pid file */
g_ptr_array_add (dhclient_argv, (gpointer) device->pid_file);
g_ptr_array_add (dhclient_argv, (gpointer) "-lf"); /* Set lease file */
g_ptr_array_add (dhclient_argv, (gpointer) device->lease_file);
g_ptr_array_add (dhclient_argv, (gpointer) "-cf"); /* Set interface config file */
g_ptr_array_add (dhclient_argv, (gpointer) device->conf_file);
g_ptr_array_add (dhclient_argv, (gpointer) device->iface);
g_ptr_array_add (dhclient_argv, NULL);
if (!g_spawn_async (NULL, (char **) dhclient_argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
&dhclient_child_setup, NULL, &pid, &error)) { &dhclient_child_setup, NULL, &pid, &error)) {
nm_warning ("dhclient failed to start. error: '%s'", error->message); nm_warning ("dhclient failed to start. error: '%s'", error->message);
g_error_free (error); g_error_free (error);
goto out; pid = -1;
} else
nm_info ("dhclient started with pid %d", pid);
g_ptr_array_free (argv, TRUE);
return pid;
}
static GPid
real_ip4_start (NMDHCPClient *client,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
{
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
const char *iface;
iface = nm_dhcp_client_get_iface (client);
priv->conf_file = create_dhclient_config (iface, s_ip4, dhcp_anycast_addr);
if (!priv->conf_file) {
nm_warning ("%s: error creating dhclient configuration file.", iface);
return -1;
} }
nm_info ("dhclient started with pid %d", pid); return dhclient_start (client, "-4", NULL);
}
out: static GPid
g_free (pid_contents); real_ip6_start (NMDHCPClient *client,
g_ptr_array_free (dhclient_argv, TRUE); NMSettingIP6Config *s_ip6,
return pid; guint8 *dhcp_anycast_addr,
gboolean info_only)
{
return dhclient_start (client, "-6", info_only ? "-S" : "-N");
}
static void
real_stop (NMDHCPClient *client)
{
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
/* Chain up to parent */
NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client);
if (priv->conf_file)
remove (priv->conf_file);
if (priv->pid_file)
remove (priv->pid_file);
} }
static const char ** static const char **
@@ -595,10 +633,11 @@ error:
return o; return o;
} }
gboolean static gboolean
nm_dhcp_client_process_classless_routes (GHashTable *options, real_ip4_process_classless_routes (NMDHCPClient *client,
NMIP4Config *ip4_config, GHashTable *options,
guint32 *gwaddr) NMIP4Config *ip4_config,
guint32 *gwaddr)
{ {
const char *str; const char *str;
char **octets, **o; char **octets, **o;
@@ -663,3 +702,39 @@ out:
return have_routes; return have_routes;
} }
/***************************************************/
static void
nm_dhcp_dhclient_init (NMDHCPDhclient *self)
{
}
static void
dispose (GObject *object)
{
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (object);
g_free (priv->pid_file);
g_free (priv->conf_file);
g_free (priv->lease_file);
G_OBJECT_CLASS (nm_dhcp_dhclient_parent_class)->dispose (object);
}
static void
nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class)
{
NMDHCPClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhclient_class);
GObjectClass *object_class = G_OBJECT_CLASS (dhclient_class);
g_type_class_add_private (dhclient_class, sizeof (NMDHCPDhclientPrivate));
/* virtual methods */
object_class->dispose = dispose;
client_class->ip4_start = real_ip4_start;
client_class->ip6_start = real_ip6_start;
client_class->stop = real_stop;
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
}

View File

@@ -0,0 +1,47 @@
/* -*- 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 <glib.h>
#include <glib-object.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 ((obj), NM_TYPE_DHCP_DHCLIENT))
#define NM_DHCP_DHCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientClass))
typedef struct {
NMDHCPClient parent;
} NMDHCPDhclient;
typedef struct {
NMDHCPClientClass parent;
} NMDHCPDhclientClass;
GType nm_dhcp_dhclient_get_type (void);
GSList *nm_dhcp_dhclient_get_lease_config (const char *iface, const char *uuid);
#endif /* NM_DHCP_DHCLIENT_H */

View File

@@ -2,6 +2,7 @@
/* nm-dhcp-dhcpcd.c - dhcpcd specific hooks for NetworkManager /* nm-dhcp-dhcpcd.c - dhcpcd specific hooks for NetworkManager
* *
* Copyright (C) 2008 Roy Marples * Copyright (C) 2008 Roy Marples
* Copyright (C) 2010 Dan Williams <dcbw@redhat.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -31,26 +32,22 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "nm-dhcp-manager.h" #include "nm-dhcp-dhcpcd.h"
#include "nm-utils.h" #include "nm-utils.h"
#define NM_DHCP_MANAGER_PID_FILENAME "dhcpcd" G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_DHCPCD)
#define NM_DHCP_MANAGER_PID_FILE_EXT "pid"
#define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdPrivate))
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action" #define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action"
typedef struct {
char *pid_file;
} NMDHCPDhcpcdPrivate;
static char *
get_pidfile_for_iface (const char * iface)
{
return g_strdup_printf ("/var/run/%s-%s.%s",
NM_DHCP_MANAGER_PID_FILENAME,
iface,
NM_DHCP_MANAGER_PID_FILE_EXT);
}
GSList * GSList *
nm_dhcp_client_get_lease_ip4_config (const char *iface, const char *uuid) nm_dhcp_dhcpcd_get_lease_config (const char *iface, const char *uuid)
{ {
return NULL; return NULL;
} }
@@ -63,40 +60,41 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED)
setpgid (pid, pid); setpgid (pid, pid);
} }
static GPid
GPid real_ip4_start (NMDHCPClient *client,
nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4,
const char *uuid, guint8 *dhcp_anycast_addr)
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
{ {
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
GPtrArray *argv = NULL; GPtrArray *argv = NULL;
GPid pid = 0; GPid pid = 0;
GError *error = NULL; GError *error = NULL;
char *pid_contents = NULL; char *pid_contents = NULL, *binary_name;
const char *iface, *uuid;
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) { g_return_val_if_fail (priv->pid_file == NULL, -1);
nm_warning (DHCP_CLIENT_PATH " does not exist.");
goto out; iface = nm_dhcp_client_get_iface (client);
uuid = nm_dhcp_client_get_uuid (client);
priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhcpcd-%s.pid", iface);
if (!priv->pid_file) {
nm_warning ("%s: not enough memory for dhcpcd options.", iface);
return -1;
} }
device->pid_file = get_pidfile_for_iface (device->iface); if (!g_file_test (DHCPCD_PATH, G_FILE_TEST_EXISTS)) {
if (!device->pid_file) { nm_warning (DHCPCD_PATH " does not exist.");
nm_warning ("%s: not enough memory for dhcpcd options.", device->iface); return -1;
goto out;
} }
/* Kill any existing dhcpcd bound to this interface */ /* Kill any existing dhclient from the pidfile */
if (g_file_get_contents (device->pid_file, &pid_contents, NULL, NULL)) { binary_name = g_path_get_basename (DHCPCD_PATH);
unsigned long int tmp = strtoul (pid_contents, NULL, 10); nm_dhcp_client_stop_existing (priv->pid_file, binary_name);
g_free (binary_name);
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
nm_dhcp_client_stop (device, (pid_t) tmp);
remove (device->pid_file);
}
argv = g_ptr_array_new (); argv = g_ptr_array_new ();
g_ptr_array_add (argv, (gpointer) DHCP_CLIENT_PATH); g_ptr_array_add (argv, (gpointer) DHCPCD_PATH);
g_ptr_array_add (argv, (gpointer) "-B"); /* Don't background on lease (disable fork()) */ g_ptr_array_add (argv, (gpointer) "-B"); /* Don't background on lease (disable fork()) */
@@ -107,28 +105,48 @@ nm_dhcp_client_start (NMDHCPDevice *device,
g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */
g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH );
g_ptr_array_add (argv, (gpointer) device->iface); g_ptr_array_add (argv, (gpointer) iface);
g_ptr_array_add (argv, NULL); g_ptr_array_add (argv, NULL);
if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
&dhcpcd_child_setup, NULL, &pid, &error)) { &dhcpcd_child_setup, NULL, &pid, &error)) {
nm_warning ("dhcpcd failed to start. error: '%s'", error->message); nm_warning ("dhcpcd failed to start. error: '%s'", error->message);
g_error_free (error); g_error_free (error);
goto out; } else
} nm_info ("dhcpcd started with pid %d", pid);
nm_info ("dhcpcd started with pid %d", pid);
out:
g_free (pid_contents); g_free (pid_contents);
g_ptr_array_free (argv, TRUE); g_ptr_array_free (argv, TRUE);
return pid; return pid;
} }
gboolean static GPid
nm_dhcp_client_process_classless_routes (GHashTable *options, real_ip6_start (NMDHCPClient *client,
NMIP4Config *ip4_config, NMSettingIP6Config *s_ip6,
guint32 *gwaddr) guint8 *dhcp_anycast_addr,
gboolean info_only)
{
g_warning ("The dhcpcd backend does not support IPv6.");
return -1;
}
static void
real_stop (NMDHCPClient *client)
{
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
/* Chain up to parent */
NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client);
if (priv->pid_file)
remove (priv->pid_file);
}
static gboolean
real_ip4_process_classless_routes (NMDHCPClient *client,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{ {
const char *str; const char *str;
char **routes, **r; char **routes, **r;
@@ -201,3 +219,37 @@ out:
return have_routes; return have_routes;
} }
/***************************************************/
static void
nm_dhcp_dhcpcd_init (NMDHCPDhcpcd *self)
{
}
static void
dispose (GObject *object)
{
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (object);
g_free (priv->pid_file);
G_OBJECT_CLASS (nm_dhcp_dhcpcd_parent_class)->dispose (object);
}
static void
nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class)
{
NMDHCPClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhcpcd_class);
GObjectClass *object_class = G_OBJECT_CLASS (dhcpcd_class);
g_type_class_add_private (dhcpcd_class, sizeof (NMDHCPDhcpcdPrivate));
/* virtual methods */
object_class->dispose = dispose;
client_class->ip4_start = real_ip4_start;
client_class->ip6_start = real_ip6_start;
client_class->stop = real_stop;
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
}

View File

@@ -0,0 +1,47 @@
/* -*- 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_DHCPCD_H
#define NM_DHCP_DHCPCD_H
#include <glib.h>
#include <glib-object.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 ((obj), NM_TYPE_DHCP_DHCPCD))
#define NM_DHCP_DHCPCD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdClass))
typedef struct {
NMDHCPClient parent;
} NMDHCPDhcpcd;
typedef struct {
NMDHCPClientClass parent;
} NMDHCPDhcpcdClass;
GType nm_dhcp_dhcpcd_get_type (void);
GSList *nm_dhcp_dhcpcd_get_lease_config (const char *iface, const char *uuid);
#endif /* NM_DHCP_DHCPCD_H */

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2005 - 2008 Red Hat, Inc. * Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2006 - 2008 Novell, Inc.
*/ */
@@ -26,13 +26,13 @@
#include <glib-object.h> #include <glib-object.h>
#include <nm-setting-ip4-config.h> #include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
#include "nm-dhcp-client.h"
#include "nm-ip4-config.h" #include "nm-ip4-config.h"
#include "nm-dhcp4-config.h" #include "nm-dhcp4-config.h"
#include "nm-hostname-provider.h" #include "nm-hostname-provider.h"
#define NM_DHCP_MANAGER_RUN_DIR LOCALSTATEDIR "/run"
#define NM_TYPE_DHCP_MANAGER (nm_dhcp_manager_get_type ()) #define NM_TYPE_DHCP_MANAGER (nm_dhcp_manager_get_type ())
#define NM_DHCP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManager)) #define NM_DHCP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManager))
#define NM_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass)) #define NM_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass))
@@ -40,93 +40,47 @@
#define NM_IS_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP_MANAGER)) #define NM_IS_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP_MANAGER))
#define NM_DHCP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass)) #define NM_DHCP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass))
typedef enum {
DHC_NBI=0, /* no broadcast interfaces found */
DHC_PREINIT, /* configuration started */
DHC_BOUND, /* lease obtained */
DHC_IPV4LL, /* IPv4LL address obtained */
DHC_RENEW, /* lease renewed */
DHC_REBOOT, /* have valid lease, but now obtained a different one */
DHC_REBIND, /* new, different lease */
DHC_STOP, /* remove old lease */
DHC_MEDIUM, /* media selection begun */
DHC_TIMEOUT, /* timed out contacting DHCP server */
DHC_FAIL, /* all attempts to contact server timed out, sleeping */
DHC_EXPIRE, /* lease has expired, renewing */
DHC_RELEASE, /* releasing lease */
DHC_START, /* sent when dhclient started OK */
DHC_ABEND, /* dhclient exited abnormally */
DHC_END, /* dhclient exited normally */
DHC_END_OPTIONS, /* last option in subscription sent */
} NMDHCPState;
typedef struct { typedef struct {
GObject parent; GObject parent;
} NMDHCPManager; } NMDHCPManager;
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
/* Signals */
void (*state_changed) (NMDHCPManager *manager, char *iface, NMDHCPState state);
void (*timeout) (NMDHCPManager *manager, char *iface);
} NMDHCPManagerClass; } NMDHCPManagerClass;
typedef struct {
char * iface;
guchar state;
GPid pid;
char * pid_file;
char * conf_file;
char * lease_file;
guint timeout_id;
guint watch_id;
NMDHCPManager * manager;
GHashTable * options;
} NMDHCPDevice;
GType nm_dhcp_manager_get_type (void); GType nm_dhcp_manager_get_type (void);
NMDHCPManager *nm_dhcp_manager_get (void); NMDHCPManager *nm_dhcp_manager_get (void);
void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager, void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager,
NMHostnameProvider *provider); NMHostnameProvider *provider);
gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager,
const char *iface, const char *iface,
const char *uuid, const char *uuid,
NMSettingIP4Config *s_ip4, NMSettingIP4Config *s_ip4,
guint32 timeout, guint32 timeout,
guint8 *dhcp_anycast_addr); guint8 *dhcp_anycast_addr);
void nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager,
const char *iface);
NMIP4Config * nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, const char *iface);
NMDHCPState nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, const char *iface);
gboolean nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self, NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager,
const char *iface, const char *iface,
GHFunc func, const char *uuid,
gpointer user_data); NMSettingIP6Config *s_ip6,
guint32 timeout,
guint8 *dhcp_anycast_addr,
gboolean info_only);
GSList * nm_dhcp_manager_get_lease_ip4_config (NMDHCPManager *self, GSList * nm_dhcp_manager_get_lease_config (NMDHCPManager *self,
const char *iface, const char *iface,
const char *uuid); const char *uuid);
/* The following are implemented by the DHCP client backends */ /* For testing only */
GPid nm_dhcp_client_start (NMDHCPDevice *device, NMIP4Config *nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client,
const char *uuid, const char *iface,
NMSettingIP4Config *s_ip4, GHashTable *options,
guint8 *anycast_addr); const char *reason);
void nm_dhcp_client_stop (NMDHCPDevice *device, pid_t pid);
gboolean nm_dhcp_client_process_classless_routes (GHashTable *options, /* Only for NetworkManager.c */
NMIP4Config *ip4_config, NMDHCPManager *nm_dhcp_manager_new (const char *client, GError **error);
guint32 *gwaddr);
GSList * nm_dhcp_client_get_lease_ip4_config (const char *iface,
const char *uuid);
/* Test functions */
NMIP4Config *nm_dhcp_manager_options_to_ip4_config (const char *iface,
GHashTable *options);
#endif /* NM_DHCP_MANAGER_H */ #endif /* NM_DHCP_MANAGER_H */

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2009 Red Hat, Inc. * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/ */
#include <errno.h> #include <errno.h>
@@ -165,10 +165,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete), G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete),
NULL, NULL, NULL, NULL,
_nm_marshal_VOID__STRING_BOOLEAN, _nm_marshal_VOID__STRING_UINT_BOOLEAN,
G_TYPE_NONE, 2, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
G_TYPE_STRING,
G_TYPE_BOOLEAN);
signals[CONFIG_CHANGED] = signals[CONFIG_CHANGED] =
g_signal_new ("config-changed", g_signal_new ("config-changed",
@@ -176,9 +174,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed), G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__STRING, _nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 1, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
G_TYPE_STRING);
} }
static void static void
@@ -233,10 +230,16 @@ nm_ip6_manager_get_device (NMIP6Manager *manager, int ifindex)
GINT_TO_POINTER (ifindex)); GINT_TO_POINTER (ifindex));
} }
typedef struct {
NMIP6Device *device;
guint dhcp_opts;
} CallbackInfo;
static gboolean static gboolean
finish_addrconf (gpointer user_data) finish_addrconf (gpointer user_data)
{ {
NMIP6Device *device = user_data; CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager; NMIP6Manager *manager = device->manager;
char *iface_copy; char *iface_copy;
@@ -245,7 +248,7 @@ finish_addrconf (gpointer user_data)
if (device->state >= device->target_state) { if (device->state >= device->target_state) {
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
device->iface, TRUE); device->iface, info->dhcp_opts, TRUE);
} else { } else {
nm_info ("Device '%s' IP6 addrconf timed out or failed.", nm_info ("Device '%s' IP6 addrconf timed out or failed.",
device->iface); device->iface);
@@ -254,7 +257,7 @@ finish_addrconf (gpointer user_data)
nm_ip6_manager_cancel_addrconf (manager, device->iface); nm_ip6_manager_cancel_addrconf (manager, device->iface);
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
iface_copy, FALSE); iface_copy, info->dhcp_opts, FALSE);
g_free (iface_copy); g_free (iface_copy);
} }
@@ -265,11 +268,12 @@ finish_addrconf (gpointer user_data)
static gboolean static gboolean
emit_config_changed (gpointer user_data) emit_config_changed (gpointer user_data)
{ {
NMIP6Device *device = user_data; CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager; NMIP6Manager *manager = device->manager;
device->config_changed_id = 0; device->config_changed_id = 0;
g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->iface); g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->iface, info->dhcp_opts);
return FALSE; return FALSE;
} }
@@ -279,9 +283,10 @@ static gboolean
rdnss_expired (gpointer user_data) rdnss_expired (gpointer user_data)
{ {
NMIP6Device *device = user_data; NMIP6Device *device = user_data;
CallbackInfo info = { device, IP6_DHCP_OPT_NONE };
set_rdnss_timeout (device); set_rdnss_timeout (device);
emit_config_changed (device); emit_config_changed (&info);
return FALSE; return FALSE;
} }
@@ -323,6 +328,18 @@ set_rdnss_timeout (NMIP6Device *device)
} }
} }
static CallbackInfo *
callback_info_new (NMIP6Device *device, guint dhcp_opts)
{
CallbackInfo *info;
info = g_malloc0 (sizeof (CallbackInfo));
info->device = device;
info->dhcp_opts = dhcp_opts;
return info;
}
static void static void
nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
{ {
@@ -333,6 +350,8 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
struct in6_addr *addr; struct in6_addr *addr;
struct rtnl_link *link; struct rtnl_link *link;
guint flags; guint flags;
CallbackInfo *info;
guint dhcp_opts = IP6_DHCP_OPT_NONE;
for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache); for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache);
rtnladdr; rtnladdr;
@@ -365,8 +384,10 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
if ((flags & IF_RA_RCVD) && device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT) if ((flags & IF_RA_RCVD) && device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT; device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;
// if (flags & (IF_RA_MANAGED | IF_RA_OTHERCONF)) if (flags & IF_RA_MANAGED)
// device->need_dhcp = TRUE; dhcp_opts = IP6_DHCP_OPT_MANAGED;
else if (flags & IF_RA_OTHERCONF)
dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
if (!device->addrconf_complete) { if (!device->addrconf_complete) {
if (device->state >= device->target_state || if (device->state >= device->target_state ||
@@ -376,13 +397,20 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
*/ */
if (device->finish_addrconf_id) if (device->finish_addrconf_id)
g_source_remove (device->finish_addrconf_id); g_source_remove (device->finish_addrconf_id);
device->finish_addrconf_id = g_idle_add (finish_addrconf,
device); info = callback_info_new (device, dhcp_opts);
device->finish_addrconf_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
finish_addrconf,
info,
(GDestroyNotify) g_free);
} }
} else if (config_changed) { } else if (config_changed) {
if (!device->config_changed_id) { if (!device->config_changed_id) {
device->config_changed_id = g_idle_add (emit_config_changed, info = callback_info_new (device, dhcp_opts);
device); device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
emit_config_changed,
info,
(GDestroyNotify) g_free);
} }
} }
} }
@@ -717,6 +745,7 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
{ {
NMIP6ManagerPrivate *priv; NMIP6ManagerPrivate *priv;
NMIP6Device *device; NMIP6Device *device;
CallbackInfo *info;
g_return_if_fail (NM_IS_IP6_MANAGER (manager)); g_return_if_fail (NM_IS_IP6_MANAGER (manager));
g_return_if_fail (iface != NULL); g_return_if_fail (iface != NULL);
@@ -731,9 +760,12 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
device->addrconf_complete = FALSE; device->addrconf_complete = FALSE;
/* Set up a timeout on the transaction to kill it after the timeout */ /* Set up a timeout on the transaction to kill it after the timeout */
device->finish_addrconf_id = g_timeout_add_seconds (NM_IP6_TIMEOUT, info = callback_info_new (device, 0);
finish_addrconf, device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
device); NM_IP6_TIMEOUT,
finish_addrconf,
info,
(GDestroyNotify) g_free);
/* Sync flags, etc, from netlink; this will also notice if the /* Sync flags, etc, from netlink; this will also notice if the
* device is already fully configured and schedule the * device is already fully configured and schedule the

View File

@@ -35,6 +35,12 @@
#define NM_IS_IP6_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IP6_MANAGER)) #define NM_IS_IP6_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IP6_MANAGER))
#define NM_IP6_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_MANAGER, NMIP6ManagerClass)) #define NM_IP6_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_MANAGER, NMIP6ManagerClass))
enum {
IP6_DHCP_OPT_NONE = 0,
IP6_DHCP_OPT_OTHERCONF,
IP6_DHCP_OPT_MANAGED
};
typedef struct { typedef struct {
GObject parent; GObject parent;
} NMIP6Manager; } NMIP6Manager;
@@ -47,13 +53,18 @@ typedef struct {
/* addrconf_complete is emitted only during initial configuration to indicate /* addrconf_complete is emitted only during initial configuration to indicate
* that the initial configuration is complete. * that the initial configuration is complete.
*/ */
void (*addrconf_complete) (NMIP6Manager *manager, char *iface, gboolean success); void (*addrconf_complete) (NMIP6Manager *manager,
char *iface,
guint dhcp_opts,
gboolean success);
/* config_changed gets emitted only *after* initial configuration is /* config_changed gets emitted only *after* initial configuration is
* complete; it's like DHCP renew and indicates that the existing config * complete; it's like DHCP renew and indicates that the existing config
* of the interface has changed. * of the interface has changed.
*/ */
void (*config_changed) (NMIP6Manager *manager, char *iface); void (*config_changed) (NMIP6Manager *manager,
char *iface,
guint dhcp_opts);
} NMIP6ManagerClass; } NMIP6ManagerClass;
GType nm_ip6_manager_get_type (void); GType nm_ip6_manager_get_type (void);

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2005 - 2008 Red Hat, Inc. * Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2006 - 2008 Novell, Inc.
*/ */
@@ -1608,9 +1608,9 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
/* Get any saved leases that apply to this connection */ /* Get any saved leases that apply to this connection */
dhcp_mgr = nm_dhcp_manager_get (); dhcp_mgr = nm_dhcp_manager_get ();
leases = nm_dhcp_manager_get_lease_ip4_config (dhcp_mgr, leases = nm_dhcp_manager_get_lease_config (dhcp_mgr,
nm_device_get_iface (self), nm_device_get_iface (self),
nm_setting_connection_get_uuid (s_con)); nm_setting_connection_get_uuid (s_con));
g_object_unref (dhcp_mgr); g_object_unref (dhcp_mgr);
method = nm_setting_ip4_config_get_method (s_ip4); method = nm_setting_ip4_config_get_method (s_ip4);

View File

@@ -137,6 +137,14 @@ nm_device_interface_init (gpointer g_iface)
DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READWRITE)); 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_object_interface_install_property
(g_iface, (g_iface,
g_param_spec_uint (NM_DEVICE_INTERFACE_STATE, g_param_spec_uint (NM_DEVICE_INTERFACE_STATE,

View File

@@ -53,6 +53,7 @@ typedef enum
#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" #define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-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_STATE "state"
#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
#define NM_DEVICE_INTERFACE_MANAGED "managed" #define NM_DEVICE_INTERFACE_MANAGED "managed"
@@ -69,6 +70,7 @@ typedef enum {
NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, NM_DEVICE_INTERFACE_PROP_IP4_CONFIG,
NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG, NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG,
NM_DEVICE_INTERFACE_PROP_IP6_CONFIG, NM_DEVICE_INTERFACE_PROP_IP6_CONFIG,
NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG,
NM_DEVICE_INTERFACE_PROP_STATE, NM_DEVICE_INTERFACE_PROP_STATE,
NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
NM_DEVICE_INTERFACE_PROP_MANAGED, NM_DEVICE_INTERFACE_PROP_MANAGED,

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@
#include "nm-ip4-config.h" #include "nm-ip4-config.h"
#include "nm-ip6-config.h" #include "nm-ip6-config.h"
#include "nm-dhcp4-config.h" #include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
#include "nm-connection.h" #include "nm-connection.h"
typedef enum NMActStageReturn typedef enum NMActStageReturn
@@ -140,10 +141,8 @@ int nm_device_get_priority (NMDevice *dev);
guint32 nm_device_get_ip4_address (NMDevice *dev); guint32 nm_device_get_ip4_address (NMDevice *dev);
void nm_device_update_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev);
gboolean nm_device_get_use_dhcp (NMDevice *dev);
void nm_device_set_use_dhcp (NMDevice *dev,
gboolean use_dhcp);
NMDHCP4Config * nm_device_get_dhcp4_config (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); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
NMIP6Config * nm_device_get_ip6_config (NMDevice *dev); NMIP6Config * nm_device_get_ip6_config (NMDevice *dev);

192
src/nm-dhcp6-config.c Normal file
View File

@@ -0,0 +1,192 @@
/* -*- 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) 2008 Red Hat, Inc.
*/
#include <glib.h>
#include <string.h>
#include "NetworkManager.h"
#include "nm-dbus-manager.h"
#include "nm-dhcp6-config.h"
#include "nm-dhcp6-config-glue.h"
#include "nm-dbus-glib-types.h"
#include "nm-properties-changed-signal.h"
#include "nm-utils.h"
G_DEFINE_TYPE (NMDHCP6Config, nm_dhcp6_config, G_TYPE_OBJECT)
#define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigPrivate))
typedef struct {
char *dbus_path;
GHashTable *options;
} NMDHCP6ConfigPrivate;
enum {
PROP_0,
PROP_OPTIONS,
LAST_PROP
};
enum {
PROPERTIES_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
NMDHCP6Config *
nm_dhcp6_config_new (void)
{
return NM_DHCP6_CONFIG (g_object_new (NM_TYPE_DHCP6_CONFIG, NULL));
}
void
nm_dhcp6_config_add_option (NMDHCP6Config *self,
const char *key,
const char *option)
{
GValue *svalue;
g_return_if_fail (NM_IS_DHCP6_CONFIG (self));
g_return_if_fail (key != NULL);
g_return_if_fail (option != NULL);
svalue = g_slice_new0 (GValue);
g_value_init (svalue, G_TYPE_STRING);
g_value_set_string (svalue, option);
g_hash_table_insert (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options, g_strdup (key), svalue);
g_object_notify (G_OBJECT (self), NM_DHCP6_CONFIG_OPTIONS);
}
void
nm_dhcp6_config_reset (NMDHCP6Config *self)
{
g_return_if_fail (NM_IS_DHCP6_CONFIG (self));
g_hash_table_remove_all (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options);
g_object_notify (G_OBJECT (self), NM_DHCP6_CONFIG_OPTIONS);
}
const char *
nm_dhcp6_config_get_option (NMDHCP6Config *self, const char *key)
{
GValue *value;
g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL);
g_return_val_if_fail (key != NULL, NULL);
value = g_hash_table_lookup (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options, key);
return value ? g_value_get_string (value) : NULL;
}
const char *
nm_dhcp6_config_get_dbus_path (NMDHCP6Config *self)
{
g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL);
return NM_DHCP6_CONFIG_GET_PRIVATE (self)->dbus_path;
}
static void
nm_gvalue_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, value);
}
static void
nm_dhcp6_config_init (NMDHCP6Config *self)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self);
static guint32 counter = 0;
DBusGConnection *connection;
NMDBusManager *dbus_mgr;
dbus_mgr = nm_dbus_manager_get ();
connection = nm_dbus_manager_get_connection (dbus_mgr);
priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/DHCP6Config/%d", counter++);
dbus_g_connection_register_g_object (connection, priv->dbus_path, G_OBJECT (self));
g_object_unref (dbus_mgr);
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
}
static void
finalize (GObject *object)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
g_free (priv->dbus_path);
g_hash_table_destroy (priv->options);
G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->finalize (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
switch (prop_id) {
case PROP_OPTIONS:
g_value_set_boxed (value, priv->options);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
g_type_class_add_private (config_class, sizeof (NMDHCP6ConfigPrivate));
/* virtual methods */
object_class->get_property = get_property;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_OPTIONS,
g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS,
"Options",
"DHCP configuration options returned by the server",
DBUS_TYPE_G_MAP_OF_VARIANT,
G_PARAM_READABLE));
/* Signals */
signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMDHCP6ConfigClass, properties_changed));
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
&dbus_glib_nm_dhcp6_config_object_info);
}

61
src/nm-dhcp6-config.h Normal file
View File

@@ -0,0 +1,61 @@
/* -*- 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) 2008 Red Hat, Inc.
*/
#ifndef NM_DHCP6_CONFIG_H
#define NM_DHCP6_CONFIG_H
#include <glib.h>
#include <glib-object.h>
#define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type ())
#define NM_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP6_CONFIG, NMDHCP6Config))
#define NM_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigClass))
#define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP6_CONFIG))
#define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP6_CONFIG))
#define NM_DHCP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigClass))
typedef struct {
GObject parent;
} NMDHCP6Config;
typedef struct {
GObjectClass parent;
/* Signals */
void (*properties_changed) (NMDHCP6Config *config, GHashTable *properties);
} NMDHCP6ConfigClass;
#define NM_DHCP6_CONFIG_OPTIONS "options"
GType nm_dhcp6_config_get_type (void);
NMDHCP6Config *nm_dhcp6_config_new (void);
const char *nm_dhcp6_config_get_dbus_path (NMDHCP6Config *config);
void nm_dhcp6_config_add_option (NMDHCP6Config *config,
const char *key,
const char *option);
void nm_dhcp6_config_reset (NMDHCP6Config *config);
const char *nm_dhcp6_config_get_option (NMDHCP6Config *config, const char *option);
#endif /* NM_DHCP6_CONFIG_H */

View File

@@ -13,7 +13,9 @@ test_dhcp_options_SOURCES = \
test_dhcp_options_CPPFLAGS = \ test_dhcp_options_CPPFLAGS = \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(DBUS_CFLAGS) $(DBUS_CFLAGS) \
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
test_dhcp_options_LDADD = \ test_dhcp_options_LDADD = \
$(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-util/libnm-util.la \

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2008 Red Hat, Inc. * Copyright (C) 2008 - 2010 Red Hat, Inc.
* *
*/ */
@@ -35,15 +35,43 @@ typedef struct {
const char *value; const char *value;
} Option; } Option;
static void
destroy_gvalue (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, value);
}
static GValue *
string_to_byte_array_gvalue (const char *str)
{
GByteArray *array;
GValue *val;
array = g_byte_array_sized_new (strlen (str));
g_byte_array_append (array, (const guint8 *) str, strlen (str));
val = g_slice_new0 (GValue);
g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
g_value_take_boxed (val, array);
return val;
}
static GHashTable * static GHashTable *
fill_table (Option *test_options, GHashTable *table) fill_table (Option *test_options, GHashTable *table)
{ {
Option *opt; Option *opt;
if (!table) if (!table)
table = g_hash_table_new (g_str_hash, g_str_equal); table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue);
for (opt = test_options; opt->name; opt++) for (opt = test_options; opt->name; opt++) {
g_hash_table_insert (table, (gpointer) opt->name, (gpointer) opt->value); g_hash_table_insert (table,
(gpointer) opt->name,
string_to_byte_array_gvalue (opt->value));
}
return table; return table;
} }
@@ -69,7 +97,7 @@ static Option generic_options[] = {
}; };
static void static void
test_generic_options (void) test_generic_options (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -88,7 +116,7 @@ test_generic_options (void)
const char *expected_route2_gw = "10.1.1.1"; const char *expected_route2_gw = "10.1.1.1";
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-generic", "failed to parse DHCP4 options"); "dhcp-generic", "failed to parse DHCP4 options");
@@ -187,7 +215,7 @@ static Option wins_options[] = {
}; };
static void static void
test_wins_options (void) test_wins_options (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -199,7 +227,7 @@ test_wins_options (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (wins_options, options); options = fill_table (wins_options, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-wins", "failed to parse DHCP4 options"); "dhcp-wins", "failed to parse DHCP4 options");
@@ -231,7 +259,7 @@ static Option classless_routes_options[] = {
}; };
static void static void
test_classless_static_routes (void) test_classless_static_routes (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -245,7 +273,7 @@ test_classless_static_routes (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (classless_routes_options, options); options = fill_table (classless_routes_options, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-rfc3442", "failed to parse DHCP4 options"); "dhcp-rfc3442", "failed to parse DHCP4 options");
@@ -299,7 +327,7 @@ static Option invalid_classless_routes1[] = {
}; };
static void static void
test_invalid_classless_routes1 (void) test_invalid_classless_routes1 (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -311,7 +339,7 @@ test_invalid_classless_routes1 (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes1, options); options = fill_table (invalid_classless_routes1, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-1", "failed to parse DHCP4 options"); "dhcp-rfc3442-invalid-1", "failed to parse DHCP4 options");
@@ -348,7 +376,7 @@ static Option invalid_classless_routes2[] = {
}; };
static void static void
test_invalid_classless_routes2 (void) test_invalid_classless_routes2 (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -362,7 +390,7 @@ test_invalid_classless_routes2 (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes2, options); options = fill_table (invalid_classless_routes2, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-2", "failed to parse DHCP4 options"); "dhcp-rfc3442-invalid-2", "failed to parse DHCP4 options");
@@ -420,7 +448,7 @@ static Option invalid_classless_routes3[] = {
}; };
static void static void
test_invalid_classless_routes3 (void) test_invalid_classless_routes3 (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -432,7 +460,7 @@ test_invalid_classless_routes3 (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes3, options); options = fill_table (invalid_classless_routes3, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-3", "failed to parse DHCP4 options"); "dhcp-rfc3442-invalid-3", "failed to parse DHCP4 options");
@@ -469,7 +497,7 @@ static Option gw_in_classless_routes[] = {
}; };
static void static void
test_gateway_in_classless_routes (void) test_gateway_in_classless_routes (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -483,7 +511,7 @@ test_gateway_in_classless_routes (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (gw_in_classless_routes, options); options = fill_table (gw_in_classless_routes, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-rfc3442-gateway", "failed to parse DHCP4 options"); "dhcp-rfc3442-gateway", "failed to parse DHCP4 options");
@@ -526,7 +554,7 @@ static Option escaped_searches_options[] = {
}; };
static void static void
test_escaped_domain_searches (void) test_escaped_domain_searches (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -537,7 +565,7 @@ test_escaped_domain_searches (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (escaped_searches_options, options); options = fill_table (escaped_searches_options, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-escaped-domain-searches", "failed to parse DHCP4 options"); "dhcp-escaped-domain-searches", "failed to parse DHCP4 options");
@@ -560,7 +588,7 @@ static Option invalid_escaped_searches_options[] = {
}; };
static void static void
test_invalid_escaped_domain_searches (void) test_invalid_escaped_domain_searches (const char *client)
{ {
GHashTable *options; GHashTable *options;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
@@ -568,7 +596,7 @@ test_invalid_escaped_domain_searches (void)
options = fill_table (generic_options, NULL); options = fill_table (generic_options, NULL);
options = fill_table (invalid_escaped_searches_options, options); options = fill_table (invalid_escaped_searches_options, options);
ip4_config = nm_dhcp_manager_options_to_ip4_config ("eth0", options); ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL, ASSERT (ip4_config != NULL,
"dhcp-invalid-escaped-domain-searches", "failed to parse DHCP4 options"); "dhcp-invalid-escaped-domain-searches", "failed to parse DHCP4 options");
@@ -579,6 +607,9 @@ test_invalid_escaped_domain_searches (void)
g_hash_table_destroy (options); g_hash_table_destroy (options);
} }
#define DHCLIENT "dhclient"
#define DHCPCD "dhcpcd"
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
GError *error = NULL; GError *error = NULL;
@@ -592,15 +623,29 @@ int main (int argc, char **argv)
FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
/* The tests */ /* The tests */
test_generic_options (); if (strlen (DHCLIENT_PATH)) {
test_wins_options (); test_generic_options (DHCLIENT);
test_classless_static_routes (); test_wins_options (DHCLIENT);
test_invalid_classless_routes1 (); test_classless_static_routes (DHCLIENT);
test_invalid_classless_routes2 (); test_invalid_classless_routes1 (DHCLIENT);
test_invalid_classless_routes3 (); test_invalid_classless_routes2 (DHCLIENT);
test_gateway_in_classless_routes (); test_invalid_classless_routes3 (DHCLIENT);
test_escaped_domain_searches (); test_gateway_in_classless_routes (DHCLIENT);
test_invalid_escaped_domain_searches (); test_escaped_domain_searches (DHCLIENT);
test_invalid_escaped_domain_searches (DHCLIENT);
}
if (strlen (DHCPCD_PATH)) {
test_generic_options (DHCPCD);
test_wins_options (DHCPCD);
test_classless_static_routes (DHCPCD);
test_invalid_classless_routes1 (DHCPCD);
test_invalid_classless_routes2 (DHCPCD);
test_invalid_classless_routes3 (DHCPCD);
test_gateway_in_classless_routes (DHCPCD);
test_escaped_domain_searches (DHCPCD);
test_invalid_escaped_domain_searches (DHCPCD);
}
base = g_path_get_basename (argv[0]); base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base); fprintf (stdout, "%s: SUCCESS\n", base);

View File

@@ -1382,7 +1382,7 @@ make_ip6_setting (shvarFile *ifcfg,
char *value = NULL; char *value = NULL;
char *str_value; char *str_value;
char *route6_path = NULL; char *route6_path = NULL;
gboolean bool_value, ipv6forwarding, ipv6_autoconf; gboolean bool_value, ipv6forwarding, ipv6_autoconf, dhcp6 = FALSE;
char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
guint32 i; guint32 i;
shvarFile *network_ifcfg; shvarFile *network_ifcfg;
@@ -1459,9 +1459,12 @@ make_ip6_setting (shvarFile *ifcfg,
/* Find out method property */ /* Find out method property */
ipv6forwarding = svTrueValue (ifcfg, "IPV6FORWARDING", FALSE); ipv6forwarding = svTrueValue (ifcfg, "IPV6FORWARDING", FALSE);
ipv6_autoconf = svTrueValue (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding); ipv6_autoconf = svTrueValue (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding);
dhcp6 = svTrueValue (ifcfg, "DHCPV6C", FALSE);
if (ipv6_autoconf) if (ipv6_autoconf)
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
else if (dhcp6)
method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
else { else {
/* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */ /* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */
str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE); str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE);

View File

@@ -1205,18 +1205,27 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
g_assert (value); g_assert (value);
if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
svSetValue (ifcfg, "IPV6INIT", "no", FALSE); svSetValue (ifcfg, "IPV6INIT", "no", FALSE);
svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
return TRUE; return TRUE;
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
svSetValue (ifcfg, "IPV6_AUTOCONF", "yes", FALSE); svSetValue (ifcfg, "IPV6_AUTOCONF", "yes", FALSE);
svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
svSetValue (ifcfg, "DHCPV6C", "yes", FALSE);
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
} else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
/* TODO */ /* TODO */
} }