diff options
Diffstat (limited to 'src/dhcp/nm-dhcp-dhclient.c')
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index f20158c6..74d920a8 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -38,6 +38,8 @@ #include <arpa/inet.h> #include <ctype.h> +#include "nm-utils/nm-dedup-multi.h" + #include "nm-utils.h" #include "nm-dhcp-dhclient-utils.h" #include "nm-dhcp-manager.h" @@ -47,6 +49,15 @@ /*****************************************************************************/ +static const char * +_addr_family_to_path_part (int addr_family) +{ + nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + return (addr_family == AF_INET6) ? "6" : ""; +} + +/*****************************************************************************/ + #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)) @@ -92,9 +103,9 @@ nm_dhcp_dhclient_get_path (void) /** * get_dhclient_leasefile(): + * @addr_family: AF_INET or AF_INET6 * @iface: the interface name of the device on which DHCP will be done * @uuid: the connection UUID to which the returned lease should belong - * @ipv6: %TRUE for IPv6, %FALSE for IPv4 * @out_preferred_path: on return, the "most preferred" leasefile path * * Returns the path of an existing leasefile (if any) for this interface and @@ -104,16 +115,16 @@ nm_dhcp_dhclient_get_path (void) * Returns: an existing leasefile, or %NULL if no matching leasefile could be found */ static char * -get_dhclient_leasefile (const char *iface, +get_dhclient_leasefile (int addr_family, + const char *iface, const char *uuid, - gboolean ipv6, char **out_preferred_path) { char *path; /* /var/lib/NetworkManager is the preferred leasefile path */ path = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s-%s.lease", - ipv6 ? "6" : "", + _addr_family_to_path_part (addr_family), uuid, iface); if (out_preferred_path) @@ -131,14 +142,14 @@ get_dhclient_leasefile (const char *iface, /* Old Debian, SUSE, and Mandriva location */ g_free (path); path = g_strdup_printf (LOCALSTATEDIR "/lib/dhcp/dhclient%s-%s-%s.lease", - ipv6 ? "6" : "", uuid, iface); + _addr_family_to_path_part (addr_family), uuid, iface); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; /* Old Red Hat and Fedora location */ g_free (path); path = g_strdup_printf (LOCALSTATEDIR "/lib/dhclient/dhclient%s-%s-%s.lease", - ipv6 ? "6" : "", uuid, iface); + _addr_family_to_path_part (addr_family), uuid, iface); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; @@ -148,37 +159,36 @@ get_dhclient_leasefile (const char *iface, } static GSList * -nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, +nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, int ifindex, const char *uuid, - gboolean ipv6, - guint32 default_route_metric) + guint32 route_table, + guint32 route_metric) { - char *contents = NULL; - char *leasefile; - GSList *leases = NULL; + gs_free char *contents = NULL; + gs_free char *leasefile = NULL; - leasefile = get_dhclient_leasefile (iface, uuid, FALSE, NULL); + leasefile = get_dhclient_leasefile (addr_family, iface, uuid, NULL); if (!leasefile) return NULL; if ( g_file_test (leasefile, G_FILE_TEST_EXISTS) && g_file_get_contents (leasefile, &contents, NULL, NULL) && contents - && contents[0]) - leases = nm_dhcp_dhclient_read_lease_ip_configs (iface, ifindex, contents, ipv6, NULL); - - g_free (leasefile); - g_free (contents); - - return leases; + && contents[0]) { + return nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, addr_family, iface, ifindex, + route_table, route_metric, contents, NULL); + } + return NULL; } static gboolean merge_dhclient_config (NMDhcpDhclient *self, + int addr_family, const char *iface, const char *conf_file, - gboolean is_ip6, GBytes *client_id, const char *anycast_addr, const char *hostname, @@ -204,10 +214,7 @@ merge_dhclient_config (NMDhcpDhclient *self, } } - if (is_ip6 && hostname && !strchr (hostname, '.')) - _LOGW ("hostname is not a FQDN, it will be ignored"); - - new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, timeout, + new = nm_dhcp_dhclient_create_config (iface, addr_family, client_id, anycast_addr, hostname, timeout, use_fqdn, orig_path, orig, out_new_client_id); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); @@ -218,7 +225,7 @@ merge_dhclient_config (NMDhcpDhclient *self, } static char * -find_existing_config (NMDhcpDhclient *self, const char *iface, const char *uuid, gboolean ipv6) +find_existing_config (NMDhcpDhclient *self, int addr_family, const char *iface, const char *uuid) { char *path; @@ -227,20 +234,20 @@ find_existing_config (NMDhcpDhclient *self, const char *iface, const char *uuid, * or generic. */ if (uuid) { - path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", uuid); + path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), uuid); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); } - path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); - path = g_strdup_printf (NMCONFDIR "/dhclient%s.conf", ipv6 ? "6" : ""); + path = g_strdup_printf (NMCONFDIR "/dhclient%s.conf", _addr_family_to_path_part (addr_family)); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; @@ -254,25 +261,25 @@ find_existing_config (NMDhcpDhclient *self, const char *iface, const char *uuid, * which is then used by many other distributions. Some distributions * (including Fedora) don't even provide a default configuration file. */ - path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); - path = g_strdup_printf (SYSCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + path = g_strdup_printf (SYSCONFDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); - path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s.conf", ipv6 ? "6" : ""); + path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s.conf", _addr_family_to_path_part (addr_family)); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); - path = g_strdup_printf (SYSCONFDIR "/dhclient%s.conf", ipv6 ? "6" : ""); + path = g_strdup_printf (SYSCONFDIR "/dhclient%s.conf", _addr_family_to_path_part (addr_family)); _LOGD ("looking for existing config %s", path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; @@ -290,8 +297,8 @@ find_existing_config (NMDhcpDhclient *self, const char *iface, const char *uuid, */ static char * create_dhclient_config (NMDhcpDhclient *self, + int addr_family, const char *iface, - gboolean is_ip6, const char *uuid, GBytes *client_id, const char *dhcp_anycast_addr, @@ -306,17 +313,17 @@ create_dhclient_config (NMDhcpDhclient *self, g_return_val_if_fail (iface != NULL, NULL); - new = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s.conf", is_ip6 ? "6" : "", iface); + new = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface); _LOGD ("creating composite dhclient config %s", new); - orig = find_existing_config (self, iface, uuid, is_ip6); + orig = find_existing_config (self, addr_family, iface, uuid); if (orig) _LOGD ("merging existing dhclient config %s", orig); else _LOGD ("no existing dhclient configuration to merge"); error = NULL; - success = merge_dhclient_config (self, iface, new, is_ip6, client_id, dhcp_anycast_addr, + success = merge_dhclient_config (self, addr_family, iface, new, client_id, dhcp_anycast_addr, hostname, timeout, use_fqdn, orig, out_new_client_id, &error); if (!success) { _LOGW ("error creating dhclient configuration: %s", error->message); @@ -343,14 +350,15 @@ dhclient_start (NMDhcpClient *client, GError *error = NULL; const char *iface, *uuid, *system_bus_address, *dhclient_path = NULL; char *binary_name, *cmd_str, *pid_file = NULL, *system_bus_address_env = NULL; - gboolean ipv6, success; + int addr_family; + gboolean success; char *escaped, *preferred_leasefile_path = NULL; g_return_val_if_fail (priv->pid_file == NULL, FALSE); iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); - ipv6 = nm_dhcp_client_get_ipv6 (client); + addr_family = nm_dhcp_client_get_addr_family (client); dhclient_path = nm_dhcp_dhclient_get_path (); if (!dhclient_path) { @@ -359,8 +367,8 @@ dhclient_start (NMDhcpClient *client, } pid_file = g_strdup_printf (RUNSTATEDIR "/dhclient%s-%s.pid", - ipv6 ? "6" : "", - iface); + _addr_family_to_path_part (addr_family), + iface); /* Kill any existing dhclient from the pidfile */ binary_name = g_path_get_basename (dhclient_path); @@ -374,7 +382,7 @@ dhclient_start (NMDhcpClient *client, } g_free (priv->lease_file); - priv->lease_file = get_dhclient_leasefile (iface, uuid, ipv6, &preferred_leasefile_path); + priv->lease_file = get_dhclient_leasefile (addr_family, iface, uuid, &preferred_leasefile_path); if (!priv->lease_file) { /* No existing leasefile, dhclient will create one at the preferred path */ priv->lease_file = g_strdup (preferred_leasefile_path); @@ -400,7 +408,7 @@ dhclient_start (NMDhcpClient *client, g_free (preferred_leasefile_path); /* Save the DUID to the leasefile dhclient will actually use */ - if (ipv6) { + if (addr_family == AF_INET6) { escaped = nm_dhcp_dhclient_escape_duid (duid); success = nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &error); g_free (escaped); @@ -424,7 +432,7 @@ dhclient_start (NMDhcpClient *client, if (release) g_ptr_array_add (argv, (gpointer) "-r"); - if (ipv6) { + if (addr_family == AF_INET6) { g_ptr_array_add (argv, (gpointer) "-6"); if (mode_opt) g_ptr_array_add (argv, (gpointer) mode_opt); @@ -507,7 +515,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last timeout = nm_dhcp_client_get_timeout (client); use_fqdn = nm_dhcp_client_get_use_fqdn (client); - priv->conf_file = create_dhclient_config (self, iface, FALSE, uuid, client_id, dhcp_anycast_addr, + priv->conf_file = create_dhclient_config (self, AF_INET, iface, uuid, client_id, dhcp_anycast_addr, hostname, timeout, use_fqdn, &new_client_id); if (priv->conf_file) { if (new_client_id) @@ -538,7 +546,7 @@ ip6_start (NMDhcpClient *client, hostname = nm_dhcp_client_get_hostname (client); timeout = nm_dhcp_client_get_timeout (client); - priv->conf_file = create_dhclient_config (self, iface, TRUE, uuid, NULL, dhcp_anycast_addr, + priv->conf_file = create_dhclient_config (self, AF_INET6, iface, uuid, NULL, dhcp_anycast_addr, hostname, timeout, TRUE, NULL); if (!priv->conf_file) { _LOGW ("error creating dhclient configuration file"); @@ -605,9 +613,9 @@ get_duid (NMDhcpClient *client) GError *error = NULL; /* Look in interface-specific leasefile first for backwards compat */ - leasefile = get_dhclient_leasefile (nm_dhcp_client_get_iface (client), + leasefile = get_dhclient_leasefile (AF_INET6, + nm_dhcp_client_get_iface (client), nm_dhcp_client_get_uuid (client), - TRUE, NULL); if (leasefile) { _LOGD ("looking for DUID in '%s'", leasefile); |