diff options
Diffstat (limited to 'src/dhcp-manager/nm-dhcp-dhclient.c')
-rw-r--r-- | src/dhcp-manager/nm-dhcp-dhclient.c | 86 |
1 files changed, 66 insertions, 20 deletions
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index e4b37377bc..4cabb2257b 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -43,6 +43,8 @@ #include "nm-dhcp-manager.h" #include "nm-posix-signals.h" #include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" +#include "gsystem-local-alloc.h" G_DEFINE_TYPE (NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) @@ -55,7 +57,7 @@ typedef struct { char *pid_file; } NMDhcpDhclientPrivate; -const char * +static const char * nm_dhcp_dhclient_get_path (void) { const char *path = NULL; @@ -122,7 +124,7 @@ get_dhclient_leasefile (const char *iface, return NULL; } -GSList * +static GSList * nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, const char *uuid, gboolean ipv6) @@ -151,10 +153,11 @@ static gboolean merge_dhclient_config (const char *iface, const char *conf_file, gboolean is_ip6, - const char *dhcp_client_id, + GBytes *client_id, const char *anycast_addr, const char *hostname, const char *orig_path, + GBytes **out_new_client_id, GError **error) { char *orig = NULL, *new; @@ -173,7 +176,7 @@ merge_dhclient_config (const char *iface, } } - new = nm_dhcp_dhclient_create_config (iface, is_ip6, dhcp_client_id, anycast_addr, hostname, orig_path, orig); + new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, orig_path, orig, out_new_client_id); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); g_free (new); @@ -257,9 +260,10 @@ static char * create_dhclient_config (const char *iface, gboolean is_ip6, const char *uuid, - const char *dhcp_client_id, + GBytes *client_id, const char *dhcp_anycast_addr, - const char *hostname) + const char *hostname, + GBytes **out_new_client_id) { char *orig = NULL, *new = NULL; GError *error = NULL; @@ -284,7 +288,7 @@ create_dhclient_config (const char *iface, } error = NULL; - success = merge_dhclient_config (iface, new, is_ip6, dhcp_client_id, dhcp_anycast_addr, hostname, orig, &error); + success = merge_dhclient_config (iface, new, is_ip6, client_id, dhcp_anycast_addr, hostname, orig, out_new_client_id, &error); if (!success) { nm_log_warn (LOGD_DHCP, "(%s): error creating dhclient%s configuration: %s", iface, is_ip6 ? "6" : "", error->message); @@ -473,41 +477,45 @@ dhclient_start (NMDhcpClient *client, } static gboolean -ip4_start (NMDhcpClient *client, - const char *dhcp_client_id, - const char *dhcp_anycast_addr, - const char *hostname) +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface, *uuid; + GBytes *client_id; + gs_unref_bytes GBytes *new_client_id = NULL; + const char *iface, *uuid, *hostname; + gboolean success = FALSE; iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); + client_id = nm_dhcp_client_get_client_id (client); + hostname = nm_dhcp_client_get_hostname (client); - priv->conf_file = create_dhclient_config (iface, FALSE, uuid, dhcp_client_id, dhcp_anycast_addr, hostname); - if (!priv->conf_file) { + priv->conf_file = create_dhclient_config (iface, FALSE, uuid, client_id, dhcp_anycast_addr, hostname, &new_client_id); + if (priv->conf_file) { + if (new_client_id) + nm_dhcp_client_set_client_id (client, new_client_id); + success = dhclient_start (client, NULL, NULL, FALSE, NULL); + } else nm_log_warn (LOGD_DHCP4, "(%s): error creating dhclient configuration file.", iface); - return FALSE; - } - return dhclient_start (client, NULL, NULL, FALSE, NULL); + return success; } static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, - const char *hostname, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const GByteArray *duid) { NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface, *uuid; + const char *iface, *uuid, *hostname; iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); + hostname = nm_dhcp_client_get_hostname (client); - priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname); + priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname, NULL); if (!priv->conf_file) { nm_log_warn (LOGD_DHCP6, "(%s): error creating dhclient6 configuration file.", iface); return FALSE; @@ -544,6 +552,24 @@ stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) } } +static void +state_changed (NMDhcpClient *client, + NMDhcpState state, + GObject *ip_config, + GHashTable *options) +{ + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + gs_unref_bytes GBytes *client_id = NULL; + + if (nm_dhcp_client_get_client_id (client)) + return; + if (state != NM_DHCP_STATE_BOUND) + return; + + client_id = nm_dhcp_dhclient_get_client_id_from_config_file (priv->conf_file); + nm_dhcp_client_set_client_id (client, client_id); +} + static GByteArray * get_duid (NMDhcpClient *client) { @@ -612,6 +638,11 @@ nm_dhcp_dhclient_init (NMDhcpDhclient *self) /* Fallback option */ if (!priv->def_leasefile) priv->def_leasefile = SYSCONFDIR "/dhclient6.leases"; + + g_signal_connect (nm_dhcp_listener_get (), + NM_DHCP_LISTENER_EVENT, + G_CALLBACK (nm_dhcp_client_handle_event), + self); } static void @@ -619,6 +650,10 @@ dispose (GObject *object) { NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (object); + g_signal_handlers_disconnect_by_func (nm_dhcp_listener_get (), + G_CALLBACK (nm_dhcp_client_handle_event), + NM_DHCP_DHCLIENT (object)); + g_free (priv->pid_file); g_free (priv->conf_file); g_free (priv->lease_file); @@ -641,5 +676,16 @@ nm_dhcp_dhclient_class_init (NMDhcpDhclientClass *dhclient_class) client_class->ip6_start = ip6_start; client_class->stop = stop; client_class->get_duid = get_duid; + client_class->state_changed = state_changed; +} + +static void __attribute__((constructor)) +register_dhcp_dhclient (void) +{ + g_type_init (); + _nm_dhcp_client_register (NM_TYPE_DHCP_DHCLIENT, + "dhclient", + nm_dhcp_dhclient_get_path, + nm_dhcp_dhclient_get_lease_ip_configs); } |