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
AC_SUBST(PPPD_PLUGIN_DIR)
# DHCP client
AC_ARG_WITH([dhcp-client], AS_HELP_STRING([--with-dhcp-client=dhcpcd|dhclient], [path to the chosen dhcp client]))
# dhclient support
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.
case "${with_dhcp_client}" in
case "${with_dhclient}" in
/*)
DHCP_CLIENT_PATH="${with_dhcp_client}"
AC_MSG_NOTICE(using the DHCP client ${DHCP_CLIENT_PATH})
DHCLIENT_PATH="${with_dhclient}"
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
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.
AC_MSG_CHECKING(for dhclient)
for client in "$with_dhcp_client" /sbin/dhclient /usr/pkg/sbin/dhclient /usr/local/sbin/dhclient; do
test -x "$client" || continue
case `"$client" --version 2>&1` in
"isc-dhclient-"*) 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 ISC dhclient])
# dhcpcd support
AC_ARG_WITH([dhcpcd], AS_HELP_STRING([--with-dhcpcd=yes|no|path], [Enable dhcpcd 4.x support]))
# If a full path is given, use that and do not test if it works or not.
case "${with_dhcpcd}" in
/*)
DHCPCD_PATH="${with_dhcpcd}"
AC_MSG_NOTICE(using dhcpcd at ${DHCPCD_PATH})
;;
no) AC_MSG_NOTICE(dhcpcd support disabled)
;;
*)
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
else
AC_MSG_RESULT($DHCP_CLIENT_PATH)
fi
fi
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
;;
esac
if test -z "$DHCPCD_PATH" -a -z "$DHCLIENT_PATH"; then
# DHCP clients are not a build time dependency, only runtime.
# dhclient has been the longtime default for NM and it's in /sbin
# in most distros, so use it.
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}])
fi
AC_SUBST(DHCP_CLIENT_PATH)
DHCP_CLIENT=`basename "$DHCP_CLIENT_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)
AC_SUBST(DHCLIENT_PATH)
AC_SUBST(DHCPCD_PATH)
# resolvconf support
AC_ARG_WITH([resolvconf],
@@ -500,12 +506,25 @@ examples/python/Makefile
AC_OUTPUT
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 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 Building documentation: ${with_docs}
echo
echo Building tests: ${with_tests}
echo

View File

@@ -42,6 +42,7 @@
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
#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"

View File

@@ -23,5 +23,6 @@ EXTRA_DIST = \
nm-vpn-connection.xml \
nm-ppp-manager.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-ip6-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-exported-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-ip4-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
@@ -52,6 +53,7 @@ libnminclude_HEADERS = \
nm-active-connection.h \
nm-dhcp4-config.h \
nm-ip6-config.h \
nm-dhcp6-config.h \
nm-remote-connection.h \
nm-settings-interface.h \
nm-settings-system-interface.h \
@@ -86,6 +88,7 @@ libnm_glib_la_SOURCES = \
nm-active-connection.c \
nm-dhcp4-config.c \
nm-ip6-config.c \
nm-dhcp6-config.c \
nm-remote-connection.c \
nm-remote-connection-private.h \
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
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
pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc

View File

@@ -59,6 +59,8 @@ typedef struct {
gboolean null_dhcp4_config;
NMIP6Config *ip6_config;
gboolean null_ip6_config;
NMDHCP6Config *dhcp6_config;
gboolean null_dhcp6_config;
NMDeviceState state;
GUdevClient *client;
@@ -79,6 +81,7 @@ enum {
PROP_STATE,
PROP_PRODUCT,
PROP_VENDOR,
PROP_DHCP6_CONFIG,
LAST_PROP
};
@@ -220,6 +223,46 @@ demarshal_ip6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
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
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_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities },
{ NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed },
{ NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
{ NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config },
{ NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config },
{ NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
{ NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config },
{ NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config },
{ NM_DEVICE_DHCP6_CONFIG, demarshal_dhcp6_config, &priv->dhcp6_config },
{ NULL },
};
@@ -318,6 +362,8 @@ dispose (GObject *object)
g_object_unref (priv->dhcp4_config);
if (priv->ip6_config)
g_object_unref (priv->ip6_config);
if (priv->dhcp6_config)
g_object_unref (priv->dhcp6_config);
if (priv->client)
g_object_unref (priv->client);
@@ -371,6 +417,9 @@ get_property (GObject *object,
case PROP_IP6_CONFIG:
g_value_set_object (value, nm_device_get_ip6_config (device));
break;
case PROP_DHCP6_CONFIG:
g_value_set_object (value, nm_device_get_dhcp6_config (device));
break;
case PROP_STATE:
g_value_set_uint (value, nm_device_get_state (device));
break;
@@ -505,6 +554,19 @@ nm_device_class_init (NMDeviceClass *device_class)
NM_TYPE_IP6_CONFIG,
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:
*
@@ -870,6 +932,41 @@ nm_device_get_ip6_config (NMDevice *device)
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:
* @device: a #NMDevice

View File

@@ -32,6 +32,7 @@
#include "nm-ip4-config.h"
#include "nm-dhcp4-config.h"
#include "nm-ip6-config.h"
#include "nm-dhcp6-config.h"
#include "nm-connection.h"
G_BEGIN_DECLS
@@ -51,6 +52,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_IP6_CONFIG "ip6-config"
#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config"
#define NM_DEVICE_STATE "state"
#define NM_DEVICE_VENDOR "vendor"
#define NM_DEVICE_PRODUCT "product"
@@ -89,6 +91,7 @@ gboolean nm_device_get_managed (NMDevice *device);
NMIP4Config * nm_device_get_ip4_config (NMDevice *device);
NMDHCP4Config * nm_device_get_dhcp4_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);
const char * nm_device_get_product (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,
* Boston, MA 02110-1301 USA.
*
* (C) Copyright 2007 - 2008 Red Hat, Inc.
* (C) Copyright 2007 - 2010 Red Hat, Inc.
*/
#include <string.h>
@@ -435,26 +435,23 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_IP6_CONFIG_ADDRESSES);
return FALSE;
}
} else if ( !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|| !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
} else if ( !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_SHARED)) {
if (!priv->ignore_auto_dns) {
if (priv->dns && g_slist_length (priv->dns)) {
g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_DNS);
return FALSE;
}
if (g_slist_length (priv->dns)) {
g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_DNS);
return FALSE;
}
if (g_slist_length (priv->dns_search)) {
g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
return FALSE;
}
if (g_slist_length (priv->dns_search)) {
g_set_error (error,
NM_SETTING_IP6_CONFIG_ERROR,
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD,
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
return FALSE;
}
if (g_slist_length (priv->addresses)) {
@@ -464,6 +461,9 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
NM_SETTING_IP6_CONFIG_ADDRESSES);
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 {
g_set_error (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
* automatic method (DHCP, PPP, advertisement, etc) is used for the
* interface and most other properties can be left unset. If 'link-local'
* is specified, then an IPv6 link-local address will be assigned to the
* interface. If 'manual' is specified, static IP addressing is used and
* at least one IP address must be given in the 'addresses' property. If
* 'ignored' is specified, IPv6 configuration is not done. This property
* must be set. NOTE: DHCP configuration and the 'shared' method are not
* yet supported.
* interface and 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
* address will be assigned to the interface. If 'manual' is specified,
* static IP addressing is used and at least one IP address must be given
* in the 'addresses' property. If 'ignored' is specified, IPv6
* configuration is not done. This property must be set. NOTE: the 'shared'
* method are not yet supported.
**/
g_object_class_install_property
(object_class, PROP_METHOD,
g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD,
"Method",
"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 "
"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 "
"address will be assigned to the interface. If "
"'manual' is specified, static IP addressing is "
"used and at least one IP address must be given in "
" the 'addresses' property. If 'ignored' is "
"specified, IPv6 configuration is not done. This "
"property must be set. NOTE: DHCP configuration "
"and the 'shared' method are not yet supported.",
"property must be set. NOTE: the 'shared' method"
"is not yet supported.",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
@@ -740,38 +743,39 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
/**
* NMSettingIP6Config:ignore-auto-routes:
*
* When the method is set to 'auto' and this property to TRUE, automatically
* configured routes are ignored and only routes specified in
* #NMSettingIP6Config:routes, if any, are used.
* When the method is set to 'auto' or 'dhcp' and this property is set to
* TRUE, automatically configured routes are ignored and only routes
* specified in #NMSettingIP6Config:routes, if any, are used.
**/
g_object_class_install_property
(object_class, PROP_IGNORE_AUTO_ROUTES,
g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES,
"Ignore automatic routes",
"When the method is set to 'auto' and this property "
"to TRUE, automatically configured routes are "
"ignored and only routes specified in the 'routes' "
"property, if any, are used.",
"When the method is set to 'auto' or 'dhcp' and this "
"property is set to TRUE, automatically configured "
"routes are ignored and only routes specified in the "
"'routes' property, if any, are used.",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
/**
* NMSettingIP6Config:ignore-auto-dns:
*
* When the method is set to 'auto' and this property to TRUE, automatically
* configured nameservers and search domains are ignored and only namservers
* and search domains specified in #NMSettingIP6Config:dns and
* #NMSettingIP6Config:dns-search, if any, are used.
* When the method is set to 'auto' or 'dhcp' and this property is set to
* TRUE, automatically configured nameservers and search domains are ignored
* and only namservers and search domains specified in
* #NMSettingIP6Config:dns and #NMSettingIP6Config:dns-search, if any, are
* used.
**/
g_object_class_install_property
(object_class, PROP_IGNORE_AUTO_DNS,
g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS,
"Ignore DHCPv6/RDNSS DNS",
"When the method is set to 'auto' and this property "
"to TRUE, automatically configured nameservers and "
"search domains are ignored and only namservers and "
"search domains specified in the 'dns' and 'dns-search' "
"properties, if any, are used.",
"When the method is set to 'auto' or 'dhcp' and this "
"property is set to TRUE, automatically configured "
"nameservers and search domains are ignored and only "
"namservers and search domains specified in the 'dns' "
"and 'dns-search' properties, if any, are used.",
FALSE,
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,
* 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
@@ -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_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_MANUAL "manual"
#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_GSM, NM_SETTING_GSM_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_PPPOE, NM_SETTING_PPPOE_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:STRING,INT
VOID:STRING,UINT
VOID:STRING,UINT,BOOLEAN
VOID:OBJECT,OBJECT,ENUM
VOID:POINTER,STRING
VOID:STRING,BOXED

View File

@@ -37,6 +37,7 @@ noinst_LTLIBRARIES = libtest-dhcp.la
libtest_dhcp_la_SOURCES = \
nm-ip4-config.c \
nm-ip6-config.c \
nm-hostname-provider.c \
nm-dbus-manager.c
@@ -46,6 +47,7 @@ libtest_dhcp_la_CPPFLAGS = \
$(LIBNL_CFLAGS)
libtest_dhcp_la_LIBADD = \
$(top_builddir)/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
@@ -113,6 +115,8 @@ NetworkManager_SOURCES = \
nm-netlink.h \
nm-dhcp4-config.c \
nm-dhcp4-config.h \
nm-dhcp6-config.c \
nm-dhcp6-config.h \
nm-rfkill.h
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
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 = \
nm-access-point-glue.h \
nm-manager-glue.h \
@@ -159,7 +166,8 @@ BUILT_SOURCES = \
nm-ip4-config-glue.h \
nm-ip6-config-glue.h \
nm-active-connection-glue.h \
nm-dhcp4-config-glue.h
nm-dhcp4-config-glue.h \
nm-dhcp6-config-glue.h
NetworkManager_CPPFLAGS = \
$(DBUS_CFLAGS) \

View File

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

View File

@@ -9,9 +9,14 @@ INCLUDES = \
noinst_LTLIBRARIES = libdhcp-manager.la
libdhcp_manager_la_SOURCES = \
nm-dhcp-client.c \
nm-dhcp-client.h \
nm-dhcp-manager.c \
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 = \
$(DBUS_CFLAGS) \
@@ -22,13 +27,11 @@ libdhcp_manager_la_CPPFLAGS = \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
-DLOCALSTATEDIR=\"$(localstatedir)\" \
-DDHCP_CLIENT_PATH=\"$(DHCP_CLIENT_PATH)\"
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
libdhcp_manager_la_LIBADD = \
$(top_builddir)/marshallers/libmarshallers.la \
$(DBUS_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.,
* 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
@@ -36,46 +36,38 @@
#include <config.h>
#include "nm-dhcp-manager.h"
#include "nm-dhcp-dhclient.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_MANAGER_PID_FILE_EXT "pid"
#define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientPrivate))
#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)
#define NM_DHCP_MANAGER_LEASE_DIR LOCALSTATEDIR "/lib/dhcp"
#define NM_DHCLIENT_LEASE_DIR LOCALSTATEDIR "/lib/dhcp"
#else
#define NM_DHCP_MANAGER_LEASE_DIR LOCALSTATEDIR "/lib/dhclient"
#define NM_DHCLIENT_LEASE_DIR LOCALSTATEDIR "/lib/dhclient"
#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"
static char *
get_pidfile_for_iface (const char * iface)
{
return g_strdup_printf ("%s/%s-%s.%s",
NM_DHCP_MANAGER_RUN_DIR,
NM_DHCP_MANAGER_PID_FILENAME,
iface,
NM_DHCP_MANAGER_PID_FILE_EXT);
}
typedef struct {
char *conf_file;
char *lease_file;
char *pid_file;
} NMDHCPDhclientPrivate;
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",
NM_DHCP_MANAGER_LEASE_DIR,
NM_DHCP_MANAGER_LEASE_FILENAME,
return g_strdup_printf ("%s/dhclient%s-%s-%s.lease",
NM_DHCLIENT_LEASE_DIR,
ipv6 ? "6" : "",
uuid,
iface,
NM_DHCP_MANAGER_LEASE_FILE_EXT);
iface);
}
static void
@@ -119,7 +111,7 @@ add_lease_option (GHashTable *hash, char *line)
}
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;
char *contents = NULL;
@@ -127,7 +119,7 @@ nm_dhcp_client_get_lease_ip4_config (const char *iface, const char *uuid)
char **line, **split = NULL;
GHashTable *hash = NULL;
leasefile = get_leasefile_for_iface (iface, uuid);
leasefile = get_leasefile_for_iface (iface, uuid, FALSE);
if (!leasefile)
return NULL;
@@ -288,28 +280,39 @@ out:
#define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager"
static gboolean
merge_dhclient_config (NMDHCPDevice *device,
merge_dhclient_config (const char *iface,
const char *conf_file,
NMSettingIP4Config *s_ip4,
guint8 *anycast_addr,
const char *contents,
const char *orig,
const char *orig_path,
GError **error)
{
GString *new_contents;
char *orig_contents = NULL;
gboolean success = FALSE;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (device->iface != NULL, FALSE);
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (conf_file != NULL, FALSE);
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. */
if (contents) {
if (orig_contents) {
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++) {
gboolean ignore = FALSE;
@@ -334,6 +337,7 @@ merge_dhclient_config (NMDHCPDevice *device,
if (lines)
g_strfreev (lines);
g_free (orig_contents);
} else
g_string_append_c (new_contents, '\n');
@@ -374,14 +378,13 @@ merge_dhclient_config (NMDHCPDevice *device,
" initial-interval 1; \n"
" anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n"
"}\n",
device->iface,
iface,
anycast_addr[0], anycast_addr[1],
anycast_addr[2], anycast_addr[3],
anycast_addr[4], anycast_addr[5]);
}
if (g_file_set_contents (device->conf_file, new_contents->str, -1, error))
success = TRUE;
success = g_file_set_contents (conf_file, new_contents->str, -1, error);
g_string_free (new_contents, TRUE);
return success;
@@ -393,17 +396,16 @@ merge_dhclient_config (NMDHCPDevice *device,
* read their single config file and merge that into a custom per-interface
* config file along with the NM options.
*/
static gboolean
create_dhclient_config (NMDHCPDevice *device,
static char *
create_dhclient_config (const char *iface,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
{
char *orig = NULL, *contents = NULL;
char *orig = NULL, *tmp, *conf_file = NULL;
GError *error = NULL;
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)
orig = g_strdup (SYSCONFDIR "/dhclient.conf");
@@ -412,41 +414,28 @@ create_dhclient_config (NMDHCPDevice *device,
#elif defined(TARGET_GENTOO)
orig = g_strdup (SYSCONFDIR "/dhcp/dhclient.conf");
#else
orig = g_strdup_printf (SYSCONFDIR "/dhclient-%s.conf", device->iface);
orig = g_strdup_printf (SYSCONFDIR "/dhclient-%s.conf", iface);
#endif
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;
}
tmp = g_strdup_printf ("nm-dhclient-%s.conf", device->iface);
device->conf_file = g_build_filename ("/var", "run", tmp, NULL);
tmp = g_strdup_printf ("nm-dhclient-%s.conf", iface);
conf_file = g_build_filename ("/var", "run", tmp, NULL);
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;
if (merge_dhclient_config (device, s_ip4, dhcp_anycast_addr, contents, orig, &error))
success = TRUE;
else {
success = merge_dhclient_config (iface, conf_file, s_ip4, dhcp_anycast_addr, orig, &error);
if (!success) {
nm_warning ("%s: error creating dhclient configuration: %s",
device->iface, error->message);
iface, error->message);
g_error_free (error);
}
g_free (contents);
g_free (orig);
return success;
return conf_file;
}
@@ -458,80 +447,129 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED)
setpgid (pid, pid);
}
GPid
nm_dhcp_client_start (NMDHCPDevice *device,
const char *uuid,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
static GPid
dhclient_start (NMDHCPClient *client,
const char *ip_opt,
const char *mode_opt)
{
GPtrArray *dhclient_argv = NULL;
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
GPtrArray *argv = NULL;
GPid pid = 0;
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)) {
nm_warning (DHCP_CLIENT_PATH " does not exist.");
goto out;
g_return_val_if_fail (priv->pid_file == NULL, -1);
g_return_val_if_fail (ip_opt != NULL, -1);
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 (!device->pid_file) {
nm_warning ("%s: not enough memory for dhclient options.", device->iface);
goto out;
if (!g_file_test (DHCLIENT_PATH, G_FILE_TEST_EXISTS)) {
nm_warning (DHCLIENT_PATH " does not exist.");
return -1;
}
device->lease_file = get_leasefile_for_iface (device->iface, uuid);
if (!device->lease_file) {
nm_warning ("%s: not enough memory for dhclient options.", device->iface);
goto out;
/* Kill any existing dhclient from the pidfile */
binary_name = g_path_get_basename (DHCLIENT_PATH);
nm_dhcp_client_stop_existing (priv->pid_file, binary_name);
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))
goto out;
argv = g_ptr_array_new ();
g_ptr_array_add (argv, (gpointer) DHCLIENT_PATH);
/* Kill any existing dhclient bound to this interface */
if (g_file_get_contents (device->pid_file, &pid_contents, NULL, NULL)) {
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
g_ptr_array_add (argv, (gpointer) "-d");
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
nm_dhcp_client_stop (device, (pid_t) tmp);
remove (device->pid_file);
g_ptr_array_add (argv, (gpointer) ip_opt);
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 (dhclient_argv, (gpointer) DHCP_CLIENT_PATH);
g_ptr_array_add (argv, (gpointer) iface);
g_ptr_array_add (argv, NULL);
g_ptr_array_add (dhclient_argv, (gpointer) "-d");
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,
if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
&dhclient_child_setup, NULL, &pid, &error)) {
nm_warning ("dhclient failed to start. error: '%s'", error->message);
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:
g_free (pid_contents);
g_ptr_array_free (dhclient_argv, TRUE);
return pid;
static GPid
real_ip6_start (NMDHCPClient *client,
NMSettingIP6Config *s_ip6,
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 **
@@ -595,10 +633,11 @@ error:
return o;
}
gboolean
nm_dhcp_client_process_classless_routes (GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
static gboolean
real_ip4_process_classless_routes (NMDHCPClient *client,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
const char *str;
char **octets, **o;
@@ -663,3 +702,39 @@ out:
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
*
* 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
* it under the terms of the GNU General Public License as published by
@@ -31,26 +32,22 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nm-dhcp-manager.h"
#include "nm-dhcp-dhcpcd.h"
#include "nm-utils.h"
#define NM_DHCP_MANAGER_PID_FILENAME "dhcpcd"
#define NM_DHCP_MANAGER_PID_FILE_EXT "pid"
G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_DHCPCD)
#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"
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 *
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;
}
@@ -63,40 +60,41 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED)
setpgid (pid, pid);
}
GPid
nm_dhcp_client_start (NMDHCPDevice *device,
const char *uuid,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
static GPid
real_ip4_start (NMDHCPClient *client,
NMSettingIP4Config *s_ip4,
guint8 *dhcp_anycast_addr)
{
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
GPtrArray *argv = NULL;
GPid pid = 0;
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)) {
nm_warning (DHCP_CLIENT_PATH " does not exist.");
goto out;
g_return_val_if_fail (priv->pid_file == NULL, -1);
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 (!device->pid_file) {
nm_warning ("%s: not enough memory for dhcpcd options.", device->iface);
goto out;
if (!g_file_test (DHCPCD_PATH, G_FILE_TEST_EXISTS)) {
nm_warning (DHCPCD_PATH " does not exist.");
return -1;
}
/* Kill any existing dhcpcd bound to this interface */
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)))
nm_dhcp_client_stop (device, (pid_t) tmp);
remove (device->pid_file);
}
/* Kill any existing dhclient from the pidfile */
binary_name = g_path_get_basename (DHCPCD_PATH);
nm_dhcp_client_stop_existing (priv->pid_file, binary_name);
g_free (binary_name);
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()) */
@@ -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) ACTION_SCRIPT_PATH );
g_ptr_array_add (argv, (gpointer) device->iface);
g_ptr_array_add (argv, (gpointer) iface);
g_ptr_array_add (argv, NULL);
if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
&dhcpcd_child_setup, NULL, &pid, &error)) {
nm_warning ("dhcpcd failed to start. error: '%s'", error->message);
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_ptr_array_free (argv, TRUE);
return pid;
}
gboolean
nm_dhcp_client_process_classless_routes (GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
static GPid
real_ip6_start (NMDHCPClient *client,
NMSettingIP6Config *s_ip6,
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;
char **routes, **r;
@@ -201,3 +219,37 @@ out:
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.,
* 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.
*/
@@ -26,13 +26,13 @@
#include <glib-object.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-dhcp4-config.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_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))
@@ -40,93 +40,47 @@
#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))
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 {
GObject parent;
} NMDHCPManager;
typedef struct {
GObjectClass parent;
/* Signals */
void (*state_changed) (NMDHCPManager *manager, char *iface, NMDHCPState state);
void (*timeout) (NMDHCPManager *manager, char *iface);
} 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);
NMDHCPManager *nm_dhcp_manager_get (void);
void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager,
NMHostnameProvider *provider);
gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
const char *iface,
const char *uuid,
NMSettingIP4Config *s_ip4,
guint32 timeout,
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);
NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager,
const char *iface,
const char *uuid,
NMSettingIP4Config *s_ip4,
guint32 timeout,
guint8 *dhcp_anycast_addr);
gboolean nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self,
const char *iface,
GHFunc func,
gpointer user_data);
NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager,
const char *iface,
const char *uuid,
NMSettingIP6Config *s_ip6,
guint32 timeout,
guint8 *dhcp_anycast_addr,
gboolean info_only);
GSList * nm_dhcp_manager_get_lease_ip4_config (NMDHCPManager *self,
const char *iface,
const char *uuid);
GSList * nm_dhcp_manager_get_lease_config (NMDHCPManager *self,
const char *iface,
const char *uuid);
/* The following are implemented by the DHCP client backends */
GPid nm_dhcp_client_start (NMDHCPDevice *device,
const char *uuid,
NMSettingIP4Config *s_ip4,
guint8 *anycast_addr);
void nm_dhcp_client_stop (NMDHCPDevice *device, pid_t pid);
/* For testing only */
NMIP4Config *nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client,
const char *iface,
GHashTable *options,
const char *reason);
gboolean nm_dhcp_client_process_classless_routes (GHashTable *options,
NMIP4Config *ip4_config,
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);
/* Only for NetworkManager.c */
NMDHCPManager *nm_dhcp_manager_new (const char *client, GError **error);
#endif /* NM_DHCP_MANAGER_H */

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
* Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <errno.h>
@@ -165,10 +165,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete),
NULL, NULL,
_nm_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_BOOLEAN);
_nm_marshal_VOID__STRING_UINT_BOOLEAN,
G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
signals[CONFIG_CHANGED] =
g_signal_new ("config-changed",
@@ -176,9 +174,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING);
_nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
}
static void
@@ -233,10 +230,16 @@ nm_ip6_manager_get_device (NMIP6Manager *manager, int ifindex)
GINT_TO_POINTER (ifindex));
}
typedef struct {
NMIP6Device *device;
guint dhcp_opts;
} CallbackInfo;
static gboolean
finish_addrconf (gpointer user_data)
{
NMIP6Device *device = user_data;
CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager;
char *iface_copy;
@@ -245,7 +248,7 @@ finish_addrconf (gpointer user_data)
if (device->state >= device->target_state) {
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
device->iface, TRUE);
device->iface, info->dhcp_opts, TRUE);
} else {
nm_info ("Device '%s' IP6 addrconf timed out or failed.",
device->iface);
@@ -254,7 +257,7 @@ finish_addrconf (gpointer user_data)
nm_ip6_manager_cancel_addrconf (manager, device->iface);
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
iface_copy, FALSE);
iface_copy, info->dhcp_opts, FALSE);
g_free (iface_copy);
}
@@ -265,11 +268,12 @@ finish_addrconf (gpointer user_data)
static gboolean
emit_config_changed (gpointer user_data)
{
NMIP6Device *device = user_data;
CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager;
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;
}
@@ -279,9 +283,10 @@ static gboolean
rdnss_expired (gpointer user_data)
{
NMIP6Device *device = user_data;
CallbackInfo info = { device, IP6_DHCP_OPT_NONE };
set_rdnss_timeout (device);
emit_config_changed (device);
emit_config_changed (&info);
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
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 rtnl_link *link;
guint flags;
CallbackInfo *info;
guint dhcp_opts = IP6_DHCP_OPT_NONE;
for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache);
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)
device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;
// if (flags & (IF_RA_MANAGED | IF_RA_OTHERCONF))
// device->need_dhcp = TRUE;
if (flags & IF_RA_MANAGED)
dhcp_opts = IP6_DHCP_OPT_MANAGED;
else if (flags & IF_RA_OTHERCONF)
dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
if (!device->addrconf_complete) {
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)
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) {
if (!device->config_changed_id) {
device->config_changed_id = g_idle_add (emit_config_changed,
device);
info = callback_info_new (device, dhcp_opts);
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;
NMIP6Device *device;
CallbackInfo *info;
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
g_return_if_fail (iface != NULL);
@@ -731,9 +760,12 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
device->addrconf_complete = FALSE;
/* Set up a timeout on the transaction to kill it after the timeout */
device->finish_addrconf_id = g_timeout_add_seconds (NM_IP6_TIMEOUT,
finish_addrconf,
device);
info = callback_info_new (device, 0);
device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
NM_IP6_TIMEOUT,
finish_addrconf,
info,
(GDestroyNotify) g_free);
/* Sync flags, etc, from netlink; this will also notice if 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_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 {
GObject parent;
} NMIP6Manager;
@@ -47,13 +53,18 @@ typedef struct {
/* addrconf_complete is emitted only during initial configuration to indicate
* 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
* complete; it's like DHCP renew and indicates that the existing config
* of the interface has changed.
*/
void (*config_changed) (NMIP6Manager *manager, char *iface);
void (*config_changed) (NMIP6Manager *manager,
char *iface,
guint dhcp_opts);
} NMIP6ManagerClass;
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.,
* 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.
*/
@@ -1608,9 +1608,9 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
/* Get any saved leases that apply to this connection */
dhcp_mgr = nm_dhcp_manager_get ();
leases = nm_dhcp_manager_get_lease_ip4_config (dhcp_mgr,
nm_device_get_iface (self),
nm_setting_connection_get_uuid (s_con));
leases = nm_dhcp_manager_get_lease_config (dhcp_mgr,
nm_device_get_iface (self),
nm_setting_connection_get_uuid (s_con));
g_object_unref (dhcp_mgr);
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,
G_PARAM_READWRITE));
g_object_interface_install_property
(g_iface,
g_param_spec_boxed (NM_DEVICE_INTERFACE_DHCP6_CONFIG,
"DHCP6 Config",
"DHCP6 Config",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READWRITE));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (NM_DEVICE_INTERFACE_STATE,

View File

@@ -53,6 +53,7 @@ typedef enum
#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-config"
#define NM_DEVICE_INTERFACE_DHCP6_CONFIG "dhcp6-config"
#define NM_DEVICE_INTERFACE_STATE "state"
#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
#define NM_DEVICE_INTERFACE_MANAGED "managed"
@@ -69,6 +70,7 @@ typedef enum {
NM_DEVICE_INTERFACE_PROP_IP4_CONFIG,
NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG,
NM_DEVICE_INTERFACE_PROP_IP6_CONFIG,
NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG,
NM_DEVICE_INTERFACE_PROP_STATE,
NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
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-ip6-config.h"
#include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
#include "nm-connection.h"
typedef enum NMActStageReturn
@@ -140,10 +141,8 @@ int nm_device_get_priority (NMDevice *dev);
guint32 nm_device_get_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);
NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *dev);
NMIP4Config * nm_device_get_ip4_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 = \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS)
$(DBUS_CFLAGS) \
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\"
test_dhcp_options_LDADD = \
$(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.,
* 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;
} 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 *
fill_table (Option *test_options, GHashTable *table)
{
Option *opt;
if (!table)
table = g_hash_table_new (g_str_hash, g_str_equal);
for (opt = test_options; opt->name; opt++)
g_hash_table_insert (table, (gpointer) opt->name, (gpointer) opt->value);
table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue);
for (opt = test_options; opt->name; opt++) {
g_hash_table_insert (table,
(gpointer) opt->name,
string_to_byte_array_gvalue (opt->value));
}
return table;
}
@@ -69,7 +97,7 @@ static Option generic_options[] = {
};
static void
test_generic_options (void)
test_generic_options (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -88,7 +116,7 @@ test_generic_options (void)
const char *expected_route2_gw = "10.1.1.1";
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,
"dhcp-generic", "failed to parse DHCP4 options");
@@ -187,7 +215,7 @@ static Option wins_options[] = {
};
static void
test_wins_options (void)
test_wins_options (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -199,7 +227,7 @@ test_wins_options (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-wins", "failed to parse DHCP4 options");
@@ -231,7 +259,7 @@ static Option classless_routes_options[] = {
};
static void
test_classless_static_routes (void)
test_classless_static_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -245,7 +273,7 @@ test_classless_static_routes (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-rfc3442", "failed to parse DHCP4 options");
@@ -299,7 +327,7 @@ static Option invalid_classless_routes1[] = {
};
static void
test_invalid_classless_routes1 (void)
test_invalid_classless_routes1 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -311,7 +339,7 @@ test_invalid_classless_routes1 (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-rfc3442-invalid-1", "failed to parse DHCP4 options");
@@ -348,7 +376,7 @@ static Option invalid_classless_routes2[] = {
};
static void
test_invalid_classless_routes2 (void)
test_invalid_classless_routes2 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -362,7 +390,7 @@ test_invalid_classless_routes2 (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-rfc3442-invalid-2", "failed to parse DHCP4 options");
@@ -420,7 +448,7 @@ static Option invalid_classless_routes3[] = {
};
static void
test_invalid_classless_routes3 (void)
test_invalid_classless_routes3 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -432,7 +460,7 @@ test_invalid_classless_routes3 (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-rfc3442-invalid-3", "failed to parse DHCP4 options");
@@ -469,7 +497,7 @@ static Option gw_in_classless_routes[] = {
};
static void
test_gateway_in_classless_routes (void)
test_gateway_in_classless_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -483,7 +511,7 @@ test_gateway_in_classless_routes (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-rfc3442-gateway", "failed to parse DHCP4 options");
@@ -526,7 +554,7 @@ static Option escaped_searches_options[] = {
};
static void
test_escaped_domain_searches (void)
test_escaped_domain_searches (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -537,7 +565,7 @@ test_escaped_domain_searches (void)
options = fill_table (generic_options, NULL);
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,
"dhcp-escaped-domain-searches", "failed to parse DHCP4 options");
@@ -560,7 +588,7 @@ static Option invalid_escaped_searches_options[] = {
};
static void
test_invalid_escaped_domain_searches (void)
test_invalid_escaped_domain_searches (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
@@ -568,7 +596,7 @@ test_invalid_escaped_domain_searches (void)
options = fill_table (generic_options, NULL);
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,
"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);
}
#define DHCLIENT "dhclient"
#define DHCPCD "dhcpcd"
int main (int argc, char **argv)
{
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);
/* The tests */
test_generic_options ();
test_wins_options ();
test_classless_static_routes ();
test_invalid_classless_routes1 ();
test_invalid_classless_routes2 ();
test_invalid_classless_routes3 ();
test_gateway_in_classless_routes ();
test_escaped_domain_searches ();
test_invalid_escaped_domain_searches ();
if (strlen (DHCLIENT_PATH)) {
test_generic_options (DHCLIENT);
test_wins_options (DHCLIENT);
test_classless_static_routes (DHCLIENT);
test_invalid_classless_routes1 (DHCLIENT);
test_invalid_classless_routes2 (DHCLIENT);
test_invalid_classless_routes3 (DHCLIENT);
test_gateway_in_classless_routes (DHCLIENT);
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]);
fprintf (stdout, "%s: SUCCESS\n", base);

View File

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

View File

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