diff options
Diffstat (limited to 'src/dhcp/nm-dhcp-manager.c')
| -rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 120 |
1 files changed, 42 insertions, 78 deletions
diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index f5c7c84b..aa40e803 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -43,8 +43,8 @@ typedef struct { const NMDhcpClientFactory *client_factory; - GHashTable * clients; - char * default_hostname; + char *default_hostname; + CList dhcp_client_lst_head; } NMDhcpManagerPrivate; struct _NMDhcpManager { @@ -98,21 +98,17 @@ static NMDhcpClient * get_client_for_ifindex (NMDhcpManager *manager, int addr_family, int ifindex) { NMDhcpManagerPrivate *priv; - GHashTableIter iter; - gpointer value; + NMDhcpClient *client; g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); g_return_val_if_fail (ifindex > 0, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); - g_hash_table_iter_init (&iter, priv->clients); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - NMDhcpClient *candidate = NM_DHCP_CLIENT (value); - - if ( nm_dhcp_client_get_ifindex (candidate) == ifindex - && nm_dhcp_client_get_addr_family (candidate) == addr_family) - return candidate; + c_list_for_each_entry (client, &priv->dhcp_client_lst_head, dhcp_client_lst) { + if ( nm_dhcp_client_get_ifindex (client) == ifindex + && nm_dhcp_client_get_addr_family (client) == addr_family) + return client; } return NULL; @@ -129,13 +125,19 @@ static void remove_client (NMDhcpManager *self, NMDhcpClient *client) { g_signal_handlers_disconnect_by_func (client, client_state_changed, self); + c_list_unlink (&client->dhcp_client_lst); /* Stopping the client is left up to the controlling device * explicitly since we may want to quit NetworkManager but not terminate * the DHCP client. */ +} - g_hash_table_remove (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client); +static void +remove_client_unref (NMDhcpManager *self, NMDhcpClient *client) +{ + remove_client (self, client); + g_object_unref (client); } static void @@ -147,7 +149,7 @@ client_state_changed (NMDhcpClient *client, NMDhcpManager *self) { if (state >= NM_DHCP_STATE_TIMEOUT) - remove_client (self, client); + remove_client_unref (self, client); } static NMDhcpClient * @@ -156,12 +158,12 @@ client_start (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - const GByteArray *hwaddr, + GBytes *hwaddr, const char *uuid, guint32 route_table, guint32 route_metric, const struct in6_addr *ipv6_ll_addr, - const char *dhcp_client_id, + GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, const char *hostname, @@ -179,23 +181,21 @@ client_start (NMDhcpManager *self, g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (uuid != NULL, NULL); + g_return_val_if_fail (!dhcp_client_id || g_bytes_get_size (dhcp_client_id) >= 2, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - /* Ensure we have a usable DHCP client */ if (!priv->client_factory) return NULL; /* Kill any old client instance */ client = get_client_for_ifindex (self, addr_family, ifindex); if (client) { - g_object_ref (client); remove_client (self, client); nm_dhcp_client_stop (client, FALSE); g_object_unref (client); } - /* And make a new one */ client = g_object_new (priv->client_factory->get_type (), NM_DHCP_CLIENT_MULTI_IDX, multi_idx, NM_DHCP_CLIENT_ADDR_FAMILY, addr_family, @@ -206,21 +206,26 @@ client_start (NMDhcpManager *self, NM_DHCP_CLIENT_ROUTE_TABLE, (guint) route_table, NM_DHCP_CLIENT_ROUTE_METRIC, (guint) route_metric, NM_DHCP_CLIENT_TIMEOUT, (guint) timeout, + NM_DHCP_CLIENT_FLAGS, (guint) (0 + | (hostname_use_fqdn ? NM_DHCP_CLIENT_FLAGS_USE_FQDN : 0) + | (info_only ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY : 0) + ), NULL); - g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client)); + nm_assert (client && c_list_is_empty (&client->dhcp_client_lst)); + c_list_link_tail (&priv->dhcp_client_lst_head, &client->dhcp_client_lst); g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); if (addr_family == AF_INET) - success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, hostname_use_fqdn, last_ip4_address); + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address); else - success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy, needed_prefixes); + success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, privacy, needed_prefixes); if (!success) { - remove_client (self, client); - client = NULL; + remove_client_unref (self, client); + return NULL; } - return client; + return g_object_ref (client); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -229,14 +234,14 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - const GByteArray *hwaddr, + GBytes *hwaddr, const char *uuid, guint32 route_table, guint32 route_metric, gboolean send_hostname, const char *dhcp_hostname, const char *dhcp_fqdn, - const char *dhcp_client_id, + GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, const char *last_ip_address) @@ -285,7 +290,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - const GByteArray *hwaddr, + GBytes *hwaddr, const struct in6_addr *ll_addr, const char *uuid, guint32 route_table, @@ -306,7 +311,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, if (send_hostname) { /* Always prefer the explicit dhcp-hostname if given */ - hostname = dhcp_hostname ? dhcp_hostname : priv->default_hostname; + hostname = dhcp_hostname ?: priv->default_hostname; } return client_start (self, AF_INET6, multi_idx, iface, ifindex, hwaddr, uuid, route_table, route_metric, ll_addr, @@ -328,31 +333,6 @@ nm_dhcp_manager_set_default_hostname (NMDhcpManager *manager, const char *hostna priv->default_hostname = g_strdup (hostname); } -GSList * -nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, - NMDedupMultiIndex *multi_idx, - int addr_family, - const char *iface, - int ifindex, - const char *uuid, - guint32 route_table, - guint32 route_metric) -{ - NMDhcpManagerPrivate *priv; - - g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (ifindex >= -1, NULL); - g_return_val_if_fail (uuid != NULL, NULL); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NULL); - - priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - if ( priv->client_factory - && priv->client_factory->get_lease_ip_configs) - return priv->client_factory->get_lease_ip_configs (multi_idx, addr_family, iface, ifindex, uuid, route_table, route_metric); - return NULL; -} - const char * nm_dhcp_manager_get_config (NMDhcpManager *self) { @@ -378,6 +358,8 @@ nm_dhcp_manager_init (NMDhcpManager *self) int i; const NMDhcpClientFactory *client_factory = NULL; + c_list_init (&priv->dhcp_client_lst_head); + for (i = 0; i < G_N_ELEMENTS (_nm_dhcp_manager_factories); i++) { const NMDhcpClientFactory *f = _nm_dhcp_manager_factories[i]; @@ -429,38 +411,21 @@ nm_dhcp_manager_init (NMDhcpManager *self) nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", client_factory->name); priv->client_factory = client_factory; - priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify) g_object_unref); } static void dispose (GObject *object) { - NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE ((NMDhcpManager *) object); - GList *values, *iter; - - if (priv->clients) { - values = g_hash_table_get_values (priv->clients); - for (iter = values; iter; iter = g_list_next (iter)) - remove_client (NM_DHCP_MANAGER (object), NM_DHCP_CLIENT (iter->data)); - g_list_free (values); - } - - G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object); -} - -static void -finalize (GObject *object) -{ - NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE ((NMDhcpManager *) object); + NMDhcpManager *self = NM_DHCP_MANAGER (object); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + NMDhcpClient *client, *client_safe; - g_free (priv->default_hostname); + c_list_for_each_entry_safe (client, client_safe, &priv->dhcp_client_lst_head, dhcp_client_lst) + remove_client_unref (self, client); - if (priv->clients) - g_hash_table_destroy (priv->clients); + G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object); - G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object); + nm_clear_g_free (&priv->default_hostname); } static void @@ -468,6 +433,5 @@ nm_dhcp_manager_class_init (NMDhcpManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - object_class->finalize = finalize; object_class->dispose = dispose; } |