From fe62e59c7e0ac04c05123dd18e19ccc04a289152 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Jan 2010 16:51:20 -0800 Subject: [PATCH] dhcp: add DHCPv6 functionality --- src/dhcp-manager/nm-dhcp-client.c | 145 +++++++++++++++++++++++----- src/dhcp-manager/nm-dhcp-client.h | 30 ++++-- src/dhcp-manager/nm-dhcp-dhclient.c | 46 ++++++--- src/dhcp-manager/nm-dhcp-dhcpcd.c | 14 ++- src/dhcp-manager/nm-dhcp-manager.c | 110 +++++++++++++++------ src/dhcp-manager/nm-dhcp-manager.h | 20 ++-- src/nm-device.c | 12 +-- 7 files changed, 288 insertions(+), 89 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index e39c9bf312..382b7d4a91 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -32,10 +32,12 @@ #include "nm-dbus-glib-types.h" #include "nm-dhcp-client.h" -#define NM_DHCP_TIMEOUT 45 /* DHCP timeout, in seconds */ - typedef struct { char * iface; + gboolean ipv6; + char * uuid; + guint32 timeout; + guchar state; GPid pid; guint timeout_id; @@ -58,6 +60,9 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, PROP_IFACE, + PROP_IPV6, + PROP_UUID, + PROP_TIMEOUT, LAST_PROP }; @@ -81,6 +86,24 @@ nm_dhcp_client_get_iface (NMDHCPClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->iface; } +gboolean +nm_dhcp_client_get_ipv6 (NMDHCPClient *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->ipv6; +} + +const char * +nm_dhcp_client_get_uuid (NMDHCPClient *self) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->uuid; +} + /********************************************/ static void @@ -193,12 +216,26 @@ daemon_watch_cb (GPid pid, gint status, gpointer user_data) g_signal_emit (G_OBJECT (self), signals[STATE_CHANGED], 0, priv->state); } +static void +start_monitor (NMDHCPClient *self) +{ + NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + + g_return_if_fail (priv->pid > 0); + + /* Set up a timeout on the transaction to kill it after the timeout */ + priv->timeout_id = g_timeout_add_seconds (priv->timeout, + daemon_timeout, + self); + priv->watch_id = g_child_watch_add (priv->pid, + (GChildWatchFunc) daemon_watch_cb, + self); +} + gboolean -nm_dhcp_client_start (NMDHCPClient *self, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint32 timeout_secs, - guint8 *dhcp_anycast_addr) +nm_dhcp_client_start_ip4 (NMDHCPClient *self, + NMSettingIP4Config *s_ip4, + guint8 *dhcp_anycast_addr) { NMDHCPClientPrivate *priv; @@ -207,28 +244,42 @@ nm_dhcp_client_start (NMDHCPClient *self, priv = NM_DHCP_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->pid == -1, FALSE); + g_return_val_if_fail (priv->ipv6 == FALSE, FALSE); + g_return_val_if_fail (priv->uuid != NULL, FALSE); - if (timeout_secs == 0) - timeout_secs = NM_DHCP_TIMEOUT; + g_message ("Activation (%s) Beginning DHCPv4 transaction (timeout in %d seconds)", + priv->iface, priv->timeout); - g_message ("Activation (%s) Beginning DHCP transaction (timeout in %d seconds)", - priv->iface, timeout_secs); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, - uuid, - s_ip4, - dhcp_anycast_addr); - if (priv->pid <= 0) - return FALSE; + priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, s_ip4, dhcp_anycast_addr); + if (priv->pid) + start_monitor (self); - /* Set up a timeout on the transaction to kill it after the timeout */ - priv->timeout_id = g_timeout_add_seconds (timeout_secs, - daemon_timeout, - self); - priv->watch_id = g_child_watch_add (priv->pid, - (GChildWatchFunc) daemon_watch_cb, - self); + return priv->pid ? TRUE : FALSE; +} - return TRUE; +gboolean +nm_dhcp_client_start_ip6 (NMDHCPClient *self, + NMSettingIP6Config *s_ip6, + guint8 *dhcp_anycast_addr) +{ + NMDHCPClientPrivate *priv; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); + + priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + g_return_val_if_fail (priv->pid == -1, FALSE); + g_return_val_if_fail (priv->ipv6 == TRUE, FALSE); + g_return_val_if_fail (priv->uuid != NULL, FALSE); + + g_message ("Activation (%s) Beginning DHCPv6 transaction (timeout in %d seconds)", + priv->iface, priv->timeout); + + priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, s_ip6, dhcp_anycast_addr); + if (priv->pid > 0) + start_monitor (self); + + return priv->pid ? TRUE : FALSE; } void @@ -816,6 +867,15 @@ get_property (GObject *object, guint prop_id, case PROP_IFACE: g_value_set_string (value, priv->iface); break; + case PROP_IPV6: + g_value_set_boolean (value, priv->ipv6); + break; + case PROP_UUID: + g_value_set_string (value, priv->uuid); + break; + case PROP_TIMEOUT: + g_value_set_uint (value, priv->timeout); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -833,6 +893,17 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->iface = g_strdup (g_value_get_string (value)); break; + case PROP_IPV6: + /* construct-only */ + priv->ipv6 = g_value_get_boolean (value); + break; + case PROP_UUID: + /* construct-only */ + priv->uuid = g_value_dup_string (value); + break; + case PROP_TIMEOUT: + priv->timeout = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -878,6 +949,30 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, PROP_IPV6, + g_param_spec_boolean (NM_DHCP_CLIENT_IPV6, + "ipv6", + "IPv6", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_UUID, + g_param_spec_string (NM_DHCP_CLIENT_UUID, + "uuid", + "UUID", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_TIMEOUT, + g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, + "timeout", + "Timeout", + 0, G_MAXUINT, 45, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* signals */ signals[STATE_CHANGED] = g_signal_new ("state-changed", diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 5cf77737e1..8b5804f418 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -22,6 +22,8 @@ #include #include +#include +#include #include #define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ()) @@ -32,6 +34,9 @@ #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 */ @@ -76,9 +81,12 @@ typedef struct { guint32 *out_gwaddr); GPid (*ip4_start) (NMDHCPClient *self, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint8 *anycast_addr); + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr); + + GPid (*ip6_start) (NMDHCPClient *self, + NMSettingIP6Config *s_ip6, + guint8 *anycast_addr); void (*stop) (NMDHCPClient *self); @@ -93,11 +101,17 @@ GPid nm_dhcp_client_get_pid (NMDHCPClient *self); const char *nm_dhcp_client_get_iface (NMDHCPClient *self); -gboolean nm_dhcp_client_start (NMDHCPClient *self, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint32 timeout_secs, - guint8 *dhcp_anycast_addr); +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); void nm_dhcp_client_stop (NMDHCPClient *self); diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index 7eec31d312..899410211f 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -447,21 +447,21 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED) } static GPid -real_ip4_start (NMDHCPClient *client, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr) +dhclient_start (NMDHCPClient *client, + const char *ip_opt) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GPtrArray *argv = NULL; GPid pid = 0; GError *error = NULL; - const char *iface; + const char *iface, *uuid; char *binary_name; 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); priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient-%s.pid", iface); if (!priv->pid_file) { @@ -479,12 +479,6 @@ real_ip4_start (NMDHCPClient *client, nm_dhcp_client_stop_existing (priv->pid_file, binary_name); g_free (binary_name); - 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; - } - priv->lease_file = get_leasefile_for_iface (iface, uuid); if (!priv->lease_file) { nm_warning ("%s: not enough memory for dhclient options.", iface); @@ -496,6 +490,8 @@ real_ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-d"); + g_ptr_array_add (argv, (gpointer) ip_opt); + g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); @@ -523,6 +519,33 @@ real_ip4_start (NMDHCPClient *client, 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; + } + + return dhclient_start (client, "-4"); +} + +static GPid +real_ip6_start (NMDHCPClient *client, + NMSettingIP6Config *s_ip6, + guint8 *dhcp_anycast_addr) +{ + return dhclient_start (client, "-6"); +} + static void real_stop (NMDHCPClient *client) { @@ -698,6 +721,7 @@ nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class) 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; } diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index fb1fd1bf1c..741fe7f76b 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -62,7 +62,6 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid real_ip4_start (NMDHCPClient *client, - const char *uuid, NMSettingIP4Config *s_ip4, guint8 *dhcp_anycast_addr) { @@ -71,11 +70,12 @@ real_ip4_start (NMDHCPClient *client, GPid pid = 0; GError *error = NULL; char *pid_contents = NULL, *binary_name; - const char *iface; + const char *iface, *uuid; 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) { @@ -120,6 +120,15 @@ real_ip4_start (NMDHCPClient *client, return pid; } +static GPid +real_ip6_start (NMDHCPClient *client, + NMSettingIP6Config *s_ip6, + guint8 *dhcp_anycast_addr) +{ + g_warning ("The dhcpcd backend does not support IPv6."); + return -1; +} + static void real_stop (NMDHCPClient *client) { @@ -238,6 +247,7 @@ nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class) 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; } diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 6da14ed145..7d9cca5707 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -47,6 +47,8 @@ #define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client" #define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" +#define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */ + static NMDHCPManager *singleton = NULL; typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid); @@ -124,7 +126,8 @@ get_client_for_pid (NMDHCPManager *manager, GPid pid) static NMDHCPClient * get_client_for_iface (NMDHCPManager *manager, - const char *iface) + const char *iface, + gboolean ip6) { NMDHCPManagerPrivate *priv; GHashTableIter iter; @@ -140,7 +143,8 @@ get_client_for_iface (NMDHCPManager *manager, while (g_hash_table_iter_next (&iter, NULL, &value)) { NMDHCPClient *candidate = NM_DHCP_CLIENT (value); - if (!strcmp (iface, nm_dhcp_client_get_iface (candidate))) + if ( !strcmp (iface, nm_dhcp_client_get_iface (candidate)) + && (nm_dhcp_client_get_ipv6 (candidate) == ip6)) return candidate; } @@ -355,28 +359,29 @@ add_client (NMDHCPManager *self, NMDHCPClient *client) g_hash_table_insert (priv->clients, client, g_object_ref (client)); } -/* Caller owns a reference to the NMDHCPClient on return */ -NMDHCPClient * -nm_dhcp_manager_start_client (NMDHCPManager *self, - const char *iface, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint32 timeout, - guint8 *dhcp_anycast_addr) +static NMDHCPClient * +client_start (NMDHCPManager *self, + const char *iface, + const char *uuid, + gboolean ipv6, + NMSettingIP4Config *s_ip4, + NMSettingIP6Config *s_ip6, + guint32 timeout, + guint8 *dhcp_anycast_addr) { NMDHCPManagerPrivate *priv; NMDHCPClient *client; - NMSettingIP4Config *setting = NULL; gboolean success = FALSE; g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (uuid != NULL, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (self); /* Kill any old client instance */ - client = get_client_for_iface (self, iface); + client = get_client_for_iface (self, iface, ipv6); if (client) { nm_dhcp_client_stop (client); remove_client (self, client); @@ -385,29 +390,17 @@ nm_dhcp_manager_start_client (NMDHCPManager *self, /* And make a new one */ client = g_object_new (priv->client_type, NM_DHCP_CLIENT_INTERFACE, iface, + NM_DHCP_CLIENT_IPV6, ipv6, + NM_DHCP_CLIENT_UUID, uuid, + NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT, NULL); g_return_val_if_fail (client != NULL, NULL); add_client (self, client); - if ( s_ip4 - && nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) - && (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL) - && priv->hostname_provider != NULL) { - - /* We're asked to send the hostname to DHCP server, the hostname - * isn't specified, and a hostname provider is registered: use that - */ - setting = NM_SETTING_IP4_CONFIG (nm_setting_duplicate (NM_SETTING (s_ip4))); - g_object_set (G_OBJECT (setting), - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, - nm_hostname_provider_get_hostname (priv->hostname_provider), - NULL); - } - - success = nm_dhcp_client_start (client, uuid, setting, timeout, dhcp_anycast_addr); - - if (setting) - g_object_unref (setting); + if (ipv6) + success = nm_dhcp_client_start_ip4 (client, s_ip4, dhcp_anycast_addr); + else + success = nm_dhcp_client_start_ip6 (client, s_ip6, dhcp_anycast_addr); if (!success) { remove_client (self, client); @@ -418,6 +411,61 @@ nm_dhcp_manager_start_client (NMDHCPManager *self, return client; } +/* Caller owns a reference to the NMDHCPClient on return */ +NMDHCPClient * +nm_dhcp_manager_start_ip4 (NMDHCPManager *self, + const char *iface, + const char *uuid, + NMSettingIP4Config *s_ip4, + guint32 timeout, + guint8 *dhcp_anycast_addr) +{ + NMDHCPManagerPrivate *priv; + NMDHCPClient *client = NULL; + + g_return_val_if_fail (self, NULL); + g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); + + priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + + if (s_ip4) { + if ( nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) + && (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL) + && priv->hostname_provider != NULL) { + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_duplicate (NM_SETTING (s_ip4))); + + /* We're asked to send the hostname to DHCP server, the hostname + * isn't specified, and a hostname provider is registered: use that + */ + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, + nm_hostname_provider_get_hostname (priv->hostname_provider), + NULL); + } else + g_object_ref (s_ip4); + } + + client = client_start (self, iface, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr); + + if (s_ip4) + g_object_unref (s_ip4); + + return client; +} + +/* Caller owns a reference to the NMDHCPClient on return */ +NMDHCPClient * +nm_dhcp_manager_start_ip6 (NMDHCPManager *self, + const char *iface, + const char *uuid, + NMSettingIP6Config *s_ip6, + guint32 timeout, + guint8 *dhcp_anycast_addr) +{ + return client_start (self, iface, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr); +} + static void hostname_provider_destroyed (gpointer data, GObject *destroyed_object) { diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index dab33601ae..690241482b 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -26,6 +26,7 @@ #include #include +#include #include "nm-dhcp-client.h" #include "nm-ip4-config.h" @@ -54,12 +55,19 @@ NMDHCPManager *nm_dhcp_manager_get (void); void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager, NMHostnameProvider *provider); -NMDHCPClient * nm_dhcp_manager_start_client (NMDHCPManager *manager, - const char *iface, - const char *uuid, - NMSettingIP4Config *s_ip4, - guint32 timeout, - guint8 *dhcp_anycast_addr); +NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager, + const char *iface, + const char *uuid, + NMSettingIP4Config *s_ip4, + guint32 timeout, + guint8 *dhcp_anycast_addr); + +NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager, + const char *iface, + const char *uuid, + NMSettingIP6Config *s_ip6, + guint32 timeout, + guint8 *dhcp_anycast_addr); GSList * nm_dhcp_manager_get_lease_config (NMDHCPManager *self, const char *iface, diff --git a/src/nm-device.c b/src/nm-device.c index 586c93949c..2b809470b2 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -1215,12 +1215,12 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) /* DHCP manager will cancel any transaction already in progress and we do not want to cancel this activation if we get "down" state from that. */ - priv->dhcp4_client = nm_dhcp_manager_start_client (priv->dhcp_manager, - ip_iface, - uuid, - s_ip4, - priv->dhcp_timeout, - anycast); + priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, + ip_iface, + uuid, + s_ip4, + priv->dhcp_timeout, + anycast); if (priv->dhcp4_client) { priv->dhcp_state_sigid = g_signal_connect (priv->dhcp4_client, "state-changed",