merge: branch 'bg/dhcp-send-fqdn-rh1255507'

https://bugzilla.redhat.com/show_bug.cgi?id=1255507
This commit is contained in:
Beniamino Galvani 2015-11-23 22:11:42 +01:00
commit 9b1d195600
20 changed files with 260 additions and 41 deletions

View file

@ -285,8 +285,9 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT), /* 12 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 13 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 14 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 15 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 16 */
SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_FQDN), /* 15 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 16 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 17 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP4_CONFIG_ALL "name"","\
@ -304,6 +305,7 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT","\
NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME","\
NM_SETTING_IP_CONFIG_DHCP_HOSTNAME","\
NM_SETTING_IP4_CONFIG_DHCP_FQDN","\
NM_SETTING_IP_CONFIG_NEVER_DEFAULT","\
NM_SETTING_IP_CONFIG_MAY_FAIL
#define NMC_FIELDS_SETTING_IP4_CONFIG_COMMON NMC_FIELDS_SETTING_IP4_CONFIG_ALL
@ -1406,6 +1408,7 @@ DEFINE_GETTER (nmc_property_ipv4_get_dhcp_client_id, NM_SETTING_IP4_CONFIG_DHCP_
DEFINE_GETTER (nmc_property_ipv4_get_dhcp_timeout, NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT)
DEFINE_GETTER (nmc_property_ipv4_get_dhcp_send_hostname, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME)
DEFINE_GETTER (nmc_property_ipv4_get_dhcp_hostname, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME)
DEFINE_GETTER (nmc_property_ipv4_get_dhcp_fqdn, NM_SETTING_IP4_CONFIG_DHCP_FQDN)
DEFINE_GETTER (nmc_property_ipv4_get_never_default, NM_SETTING_IP_CONFIG_NEVER_DEFAULT)
DEFINE_GETTER (nmc_property_ipv4_get_may_fail, NM_SETTING_IP_CONFIG_MAY_FAIL)
@ -6137,6 +6140,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (IP4_CONFIG, DHCP_FQDN),
nmc_property_ipv4_get_dhcp_fqdn,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE_IP (4, NEVER_DEFAULT),
nmc_property_ipv4_get_never_default,
nmc_property_set_bool,
@ -7470,8 +7480,9 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 12, nmc_property_ipv4_get_dhcp_timeout (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 13, nmc_property_ipv4_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 14, nmc_property_ipv4_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 15, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 16, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 15, nmc_property_ipv4_get_dhcp_fqdn (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 16, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 17, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */

View file

@ -2595,6 +2595,8 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
*
* If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the
* specified name will be sent to the DHCP server when acquiring a lease.
* This property and #NMSettingIP4Config:dhcp-fqdn are mutually exclusive and
* cannot be set at the same time.
**/
g_object_class_install_property
(object_class, PROP_DHCP_HOSTNAME,

View file

@ -59,12 +59,14 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP4_CONFIG)
typedef struct {
char *dhcp_client_id;
int dhcp_timeout;
char *dhcp_fqdn;
} NMSettingIP4ConfigPrivate;
enum {
PROP_0,
PROP_DHCP_CLIENT_ID,
PROP_DHCP_TIMEOUT,
PROP_DHCP_FQDN,
LAST_PROP
};
@ -120,6 +122,25 @@ nm_setting_ip4_config_get_dhcp_timeout (NMSettingIP4Config *setting)
return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_timeout;
}
/**
* nm_setting_ip4_config_get_dhcp_fqdn:
* @setting: the #NMSettingIP4Config
*
* Returns the value contained in the #NMSettingIP4Config:dhcp-fqdn
* property.
*
* Returns: the configured FQDN to send to the DHCP server
*
* Since: 1.2
**/
const char *
nm_setting_ip4_config_get_dhcp_fqdn (NMSettingIP4Config *setting)
{
g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL);
return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_fqdn;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@ -201,6 +222,31 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if (priv->dhcp_fqdn && !*priv->dhcp_fqdn) {
g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN);
return FALSE;
}
if (priv->dhcp_fqdn && !strchr (priv->dhcp_fqdn, '.')) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid FQDN"), priv->dhcp_fqdn);
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN);
return FALSE;
}
if (priv->dhcp_fqdn && nm_setting_ip_config_get_dhcp_hostname (s_ip)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property cannot be set when dhcp-hostname is also set"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_FQDN);
return FALSE;
}
return TRUE;
}
@ -215,6 +261,7 @@ finalize (GObject *object)
NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (object);
g_free (priv->dhcp_client_id);
g_free (priv->dhcp_fqdn);
G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object);
}
@ -233,6 +280,10 @@ set_property (GObject *object, guint prop_id,
case PROP_DHCP_TIMEOUT:
priv->dhcp_timeout = g_value_get_uint (value);
break;
case PROP_DHCP_FQDN:
g_free (priv->dhcp_fqdn);
priv->dhcp_fqdn = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -252,6 +303,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DHCP_TIMEOUT:
g_value_set_uint (value, nm_setting_ip4_config_get_dhcp_timeout (s_ip4));
break;
case PROP_DHCP_FQDN:
g_value_set_string (value, nm_setting_ip4_config_get_dhcp_fqdn (s_ip4));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -576,7 +630,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class)
/* ---ifcfg-rh---
* property: dhcp-hostname
* variable: DHCP_HOSTNAME
* description: Hostname to send to the DHCP server.
* description: Hostname to send to the DHCP server. When both DHCP_HOSTNAME and
* DHCP_FQDN are specified only the latter is used.
* ---end---
*/
@ -647,6 +702,31 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class)
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingIP4Config:dhcp-fqdn:
*
* If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the
* specified FQDN will be sent to the DHCP server when acquiring a lease. This
* property and #NMSettingIPConfig:dhcp-hostname are mutually exclusive and
* cannot be set at the same time.
*
* Since: 1.2
*/
/* ---ifcfg-rh---
* property: dhcp-fqdn
* variable: DHCP_FQDN
* description: FQDN to send to the DHCP server. When both DHCP_HOSTNAME and
* DHCP_FQDN are specified only the latter is used.
* example: DHCP_FQDN=foo.bar.com
* ---end---
*/
g_object_class_install_property
(object_class, PROP_DHCP_FQDN,
g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_FQDN, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/* IP4-specific property overrides */
/* ---dbus---

View file

@ -41,8 +41,8 @@ G_BEGIN_DECLS
#define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4"
#define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id"
#define NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT "dhcp-timeout"
#define NM_SETTING_IP4_CONFIG_DHCP_FQDN "dhcp-fqdn"
/**
* NM_SETTING_IP4_CONFIG_METHOD_AUTO:
@ -106,6 +106,8 @@ NMSetting *nm_setting_ip4_config_new (void);
const char *nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting);
NM_AVAILABLE_IN_1_2
int nm_setting_ip4_config_get_dhcp_timeout (NMSettingIP4Config *setting);
NM_AVAILABLE_IN_1_2
const char *nm_setting_ip4_config_get_dhcp_fqdn (NMSettingIP4Config *setting);
G_END_DECLS

View file

@ -2043,6 +2043,7 @@ test_connection_diff_a_only (void)
{ NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP4_CONFIG_DHCP_FQDN, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A },
{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },

View file

@ -885,6 +885,7 @@ global:
nm_setting_gsm_get_device_id;
nm_setting_gsm_get_sim_id;
nm_setting_gsm_get_sim_operator_id;
nm_setting_ip4_config_get_dhcp_fqdn;
nm_setting_ip4_config_get_dhcp_timeout;
nm_setting_ip6_config_addr_gen_mode_get_type;
nm_setting_ip6_config_get_addr_gen_mode;

View file

@ -3961,6 +3961,7 @@ dhcp4_start (NMDevice *self,
nm_device_get_ip4_route_metric (self),
nm_setting_ip_config_get_dhcp_send_hostname (s_ip4),
nm_setting_ip_config_get_dhcp_hostname (s_ip4),
nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)),
nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)),
dhcp4_get_timeout (self, NM_SETTING_IP4_CONFIG (s_ip4)),
priv->dhcp_anycast_address,
@ -8908,7 +8909,7 @@ nm_device_spawn_iface_helper (NMDevice *self)
g_ptr_array_add (argv, g_strdup ("--dhcp4-required"));
if (priv->dhcp4_client) {
const char *hostname;
const char *hostname, *fqdn;
GBytes *client_id;
client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client);
@ -8924,6 +8925,12 @@ nm_device_spawn_iface_helper (NMDevice *self)
g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname"));
g_ptr_array_add (argv, g_strdup (hostname));
}
fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4_client);
if (fqdn) {
g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn"));
g_ptr_array_add (argv, g_strdup (fqdn));
}
}
configured = TRUE;

View file

@ -47,6 +47,7 @@ typedef struct {
GByteArray * duid;
GBytes * client_id;
char * hostname;
char * fqdn;
NMDhcpState state;
pid_t pid;
@ -176,6 +177,14 @@ nm_dhcp_client_get_hostname (NMDhcpClient *self)
return NM_DHCP_CLIENT_GET_PRIVATE (self)->hostname;
}
const char *
nm_dhcp_client_get_fqdn (NMDhcpClient *self)
{
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL);
return NM_DHCP_CLIENT_GET_PRIVATE (self)->fqdn;
}
/********************************************/
static const char *state_table[NM_DHCP_STATE_MAX + 1] = {
@ -408,6 +417,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
const char *dhcp_client_id,
const char *dhcp_anycast_addr,
const char *hostname,
const char *fqdn,
const char *last_ip4_address)
{
NMDhcpClientPrivate *priv;
@ -426,6 +436,8 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
g_clear_pointer (&priv->hostname, g_free);
priv->hostname = g_strdup (hostname);
g_free (priv->fqdn);
priv->fqdn = g_strdup (fqdn);
return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address);
}

View file

@ -131,10 +131,13 @@ GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self);
const char *nm_dhcp_client_get_hostname (NMDhcpClient *self);
const char *nm_dhcp_client_get_fqdn (NMDhcpClient *self);
gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self,
const char *dhcp_client_id,
const char *dhcp_anycast_addr,
const char *hostname,
const char *fqdn,
const char *last_ip4_address);
gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self,

View file

@ -55,24 +55,29 @@ add_also_request (GPtrArray *array, const char *item)
}
static void
add_hostname4 (GString *str, const char *format, const char *hostname)
add_hostname4 (GString *str, const char *hostname, const char *fqdn)
{
char *plain_hostname, *dot;
if (hostname) {
if (fqdn) {
g_string_append_printf (str, FQDN_FORMAT "\n", fqdn);
g_string_append (str,
"send fqdn.encoded on;\n"
"send fqdn.server-update on;\n");
} else if (hostname) {
plain_hostname = g_strdup (hostname);
dot = strchr (plain_hostname, '.');
/* get rid of the domain */
if (dot)
*dot = '\0';
g_string_append_printf (str, format, plain_hostname);
g_string_append_printf (str, HOSTNAME4_FORMAT "\n", plain_hostname);
g_free (plain_hostname);
}
}
static void
add_ip4_config (GString *str, GBytes *client_id, const char *hostname)
add_ip4_config (GString *str, GBytes *client_id, const char *hostname, const char *fqdn)
{
if (client_id) {
const char *p;
@ -107,7 +112,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname)
g_string_append (str, "; # added by NetworkManager\n");
}
add_hostname4 (str, HOSTNAME4_FORMAT "\n", hostname);
add_hostname4 (str, hostname, fqdn);
g_string_append_c (str, '\n');
@ -195,6 +200,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
GBytes *client_id,
const char *anycast_addr,
const char *hostname,
const char *fqdn,
const char *orig_path,
const char *orig_contents,
GBytes **out_new_client_id)
@ -232,7 +238,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
}
/* Override config file hostname and use one from the connection */
if (hostname) {
if (hostname || fqdn) {
if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0)
continue;
if (strncmp (p, FQDN_TAG, strlen (FQDN_TAG)) == 0)
@ -298,7 +304,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
add_also_request (alsoreq, "dhcp6.domain-search");
add_also_request (alsoreq, "dhcp6.client-id");
} else {
add_ip4_config (new_contents, client_id, hostname);
add_ip4_config (new_contents, client_id, hostname, fqdn);
add_also_request (alsoreq, "rfc3442-classless-static-routes");
add_also_request (alsoreq, "ms-classless-static-routes");
add_also_request (alsoreq, "static-routes");

View file

@ -29,6 +29,7 @@ char *nm_dhcp_dhclient_create_config (const char *interface,
GBytes *client_id,
const char *anycast_addr,
const char *hostname,
const char *fqdn,
const char *orig_path,
const char *orig_contents,
GBytes **out_new_client_id);

View file

@ -153,6 +153,7 @@ merge_dhclient_config (const char *iface,
GBytes *client_id,
const char *anycast_addr,
const char *hostname,
const char *fqdn,
const char *orig_path,
GBytes **out_new_client_id,
GError **error)
@ -173,7 +174,7 @@ merge_dhclient_config (const char *iface,
}
}
new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, orig_path, orig, out_new_client_id);
new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, fqdn, orig_path, orig, out_new_client_id);
g_assert (new);
success = g_file_set_contents (conf_file, new, -1, error);
g_free (new);
@ -260,6 +261,7 @@ create_dhclient_config (const char *iface,
GBytes *client_id,
const char *dhcp_anycast_addr,
const char *hostname,
const char *fqdn,
GBytes **out_new_client_id)
{
char *orig = NULL, *new = NULL;
@ -285,7 +287,7 @@ create_dhclient_config (const char *iface,
}
error = NULL;
success = merge_dhclient_config (iface, new, is_ip6, client_id, dhcp_anycast_addr, hostname, orig, out_new_client_id, &error);
success = merge_dhclient_config (iface, new, is_ip6, client_id, dhcp_anycast_addr, hostname, fqdn, 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);
@ -465,15 +467,17 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
GBytes *client_id;
gs_unref_bytes GBytes *new_client_id = NULL;
const char *iface, *uuid, *hostname;
const char *iface, *uuid, *hostname, *fqdn;
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);
fqdn = nm_dhcp_client_get_fqdn (client);
priv->conf_file = create_dhclient_config (iface, FALSE, uuid, client_id, dhcp_anycast_addr, hostname, &new_client_id);
priv->conf_file = create_dhclient_config (iface, FALSE, uuid, client_id, dhcp_anycast_addr,
hostname, fqdn, &new_client_id);
if (priv->conf_file) {
if (new_client_id)
nm_dhcp_client_set_client_id (client, new_client_id);
@ -499,7 +503,7 @@ ip6_start (NMDhcpClient *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, NULL);
priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname, NULL, NULL);
if (!priv->conf_file) {
nm_log_warn (LOGD_DHCP6, "(%s): error creating dhclient6 configuration file.", iface);
return FALSE;

View file

@ -63,8 +63,9 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
GPtrArray *argv = NULL;
pid_t pid = -1;
GError *error = NULL;
char *pid_contents = NULL, *binary_name, *cmd_str;
const char *iface, *dhcpcd_path, *hostname;
char *pid_contents = NULL, *binary_name, *cmd_str, *dot;
const char *iface, *dhcpcd_path, *hostname, *fqdn;
gs_free char *prefix = NULL;
g_return_val_if_fail (priv->pid_file == NULL, FALSE);
@ -112,9 +113,22 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
#endif
hostname = nm_dhcp_client_get_hostname (client);
if (hostname) {
fqdn = nm_dhcp_client_get_fqdn (client);
if (fqdn) {
g_ptr_array_add (argv, (gpointer) "-h");
g_ptr_array_add (argv, (gpointer) fqdn);
g_ptr_array_add (argv, (gpointer) "-F");
g_ptr_array_add (argv, (gpointer) "both");
} else if (hostname) {
prefix = strdup (hostname);
dot = strchr (prefix, '.');
/* get rid of the domain */
if (dot)
*dot = '\0';
g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */
g_ptr_array_add (argv, (gpointer) hostname );
g_ptr_array_add (argv, (gpointer) prefix);
}
g_ptr_array_add (argv, (gpointer) iface);

View file

@ -221,6 +221,7 @@ client_start (NMDhcpManager *self,
guint32 timeout,
const char *dhcp_anycast_addr,
const char *hostname,
const char *fqdn,
gboolean info_only,
NMSettingIP6ConfigPrivacy privacy,
const char *last_ip4_address)
@ -264,7 +265,7 @@ client_start (NMDhcpManager *self,
if (ipv6)
success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy);
else
success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address);
success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, fqdn, last_ip4_address);
if (!success) {
remove_client (self, client);
@ -293,20 +294,24 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
guint32 priority,
gboolean send_hostname,
const char *dhcp_hostname,
const char *dhcp_fqdn,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr,
const char *last_ip_address)
{
const char *hostname = NULL;
const char *fqdn = NULL;
g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL);
if (send_hostname)
if (send_hostname) {
hostname = get_send_hostname (self, dhcp_hostname);
fqdn = dhcp_fqdn;
}
return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, NULL,
dhcp_client_id, timeout, dhcp_anycast_addr, hostname,
FALSE, 0, last_ip_address);
fqdn, FALSE, 0, last_ip_address);
}
/* Caller owns a reference to the NMDhcpClient on return */
@ -332,7 +337,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
if (send_hostname)
hostname = get_send_hostname (self, dhcp_hostname);
return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE,
ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, info_only,
ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, NULL, info_only,
privacy, NULL);
}

View file

@ -58,6 +58,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager,
guint32 priority,
gboolean send_hostname,
const char *dhcp_hostname,
const char *dhcp_fqdn,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr,

View file

@ -531,7 +531,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
const uint8_t *client_id = NULL;
size_t client_id_len = 0;
struct in_addr last_addr = { 0 };
const char *hostname;
const char *hostname, *fqdn;
int r, i;
gboolean success = FALSE;
@ -629,13 +629,32 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
hostname = nm_dhcp_client_get_hostname (client);
if (hostname) {
r = sd_dhcp_client_set_hostname (priv->client4, hostname);
char *prefix, *dot;
prefix = strdup (hostname);
dot = strchr (prefix, '.');
/* get rid of the domain */
if (dot)
*dot = '\0';
r = sd_dhcp_client_set_hostname (priv->client4, prefix);
free (prefix);
if (r < 0) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP hostname (%d)", iface, r);
goto error;
}
}
fqdn = nm_dhcp_client_get_fqdn (client);
if (fqdn) {
r = sd_dhcp_client_set_hostname (priv->client4, fqdn);
if (r < 0) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP FQDN (%d)", iface, r);
goto error;
}
}
r = sd_dhcp_client_start (priv->client4);
if (r < 0) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to start DHCP (%d)", iface, r);

View file

@ -42,6 +42,7 @@ test_config (const char *orig,
const char *expected,
gboolean ipv6,
const char *hostname,
const char *fqdn,
const char *dhcp_client_id,
GBytes *expected_new_client_id,
const char *iface,
@ -61,6 +62,7 @@ test_config (const char *orig,
client_id,
anycast_addr,
hostname,
fqdn,
"/path/to/dhclient.conf",
orig,
&new_client_id);
@ -105,7 +107,7 @@ static const char *orig_missing_expected = \
static void
test_orig_missing (void)
{
test_config (NULL, orig_missing_expected, FALSE, NULL, NULL, NULL, "eth0", NULL);
test_config (NULL, orig_missing_expected, FALSE, NULL, NULL, NULL, NULL, "eth0", NULL);
}
/*******************************************/
@ -134,7 +136,7 @@ static void
test_override_client_id (void)
{
test_config (override_client_id_orig, override_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
"11:22:33:44:55:66",
NULL,
"eth0",
@ -163,7 +165,7 @@ static void
test_quote_client_id (void)
{
test_config (NULL, quote_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
"1234",
NULL,
"eth0",
@ -192,7 +194,7 @@ static void
test_ascii_client_id (void)
{
test_config (NULL, ascii_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
"qb:cd:ef:12:34:56",
NULL,
"eth0",
@ -221,7 +223,7 @@ static void
test_hex_single_client_id (void)
{
test_config (NULL, hex_single_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
"ab:cd:e:12:34:56",
NULL,
"eth0",
@ -258,7 +260,7 @@ test_existing_hex_client_id (void)
new_client_id = g_bytes_new (bytes, sizeof (bytes));
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
NULL,
new_client_id,
"eth0",
@ -298,12 +300,41 @@ test_existing_ascii_client_id (void)
memcpy (buf + 1, EACID, STRLEN (EACID));
new_client_id = g_bytes_new (buf, sizeof (buf));
test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected,
FALSE, NULL,
FALSE, NULL, NULL,
NULL,
new_client_id,
"eth0",
NULL);
}
/*******************************************/
static const char *fqdn_expected = \
"# Created by NetworkManager\n"
"\n"
"send fqdn.fqdn \"foo.bar.com\"; # added by NetworkManager\n"
"send fqdn.encoded on;\n"
"send fqdn.server-update on;\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
"option wpad code 252 = string;\n"
"\n"
"also request rfc3442-classless-static-routes;\n"
"also request ms-classless-static-routes;\n"
"also request static-routes;\n"
"also request wpad;\n"
"also request ntp-servers;\n\n";
static void
test_fqdn (void)
{
test_config (NULL, fqdn_expected,
FALSE, NULL,
"foo.bar.com", NULL,
NULL,
"eth0",
NULL);
}
/*******************************************/
@ -331,7 +362,7 @@ static void
test_override_hostname (void)
{
test_config (override_hostname_orig, override_hostname_expected,
FALSE, "blahblah",
FALSE, "blahblah", NULL,
NULL,
NULL,
"eth0",
@ -360,7 +391,7 @@ static void
test_override_hostname6 (void)
{
test_config (override_hostname6_orig, override_hostname6_expected,
TRUE, "blahblah.local",
TRUE, "blahblah.local", NULL,
NULL,
NULL,
"eth0",
@ -383,7 +414,7 @@ test_nonfqdn_hostname6 (void)
/* Non-FQDN hostname can't be used with dhclient */
test_config (NULL, nonfqdn_hostname6_expected,
TRUE, "blahblah",
NULL,
NULL, NULL,
NULL,
"eth0",
NULL);
@ -420,6 +451,7 @@ test_existing_alsoreq (void)
FALSE, NULL,
NULL,
NULL,
NULL,
"eth0",
NULL);
}
@ -456,7 +488,7 @@ static void
test_existing_multiline_alsoreq (void)
{
test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected,
FALSE, NULL,
FALSE, NULL, NULL,
NULL,
NULL,
"eth0",
@ -773,6 +805,7 @@ main (int argc, char **argv)
g_test_add_func ("/dhcp/dhclient/hex_single_client_id", test_hex_single_client_id);
g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
g_test_add_func ("/dhcp/dhclient/fqdn", test_fqdn);
g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname);
g_test_add_func ("/dhcp/dhclient/override_hostname6", test_override_hostname6);
g_test_add_func ("/dhcp/dhclient/nonfqdn_hostname6", test_nonfqdn_hostname6);

View file

@ -69,6 +69,7 @@ static struct {
char *dhcp4_address;
char *dhcp4_clientid;
char *dhcp4_hostname;
char *dhcp4_fqdn;
char *iid_str;
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
char *logging_backend;
@ -291,6 +292,7 @@ do_early_setup (int *argc, char **argv[])
{ "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &global_opt.dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL },
{ "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL },
{ "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") },
{ "dhcp4-fqdn", 'F', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_fqdn, N_("FQDN to send to DHCP server"), N_("host.domain.org") },
{ "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") },
{ "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") },
{ "iid", 'e', 0, G_OPTION_ARG_STRING, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), "" },
@ -459,6 +461,7 @@ main (int argc, char *argv[])
global_opt.priority_v4,
!!global_opt.dhcp4_hostname,
global_opt.dhcp4_hostname,
global_opt.dhcp4_fqdn,
global_opt.dhcp4_clientid,
45,
NULL,

View file

@ -1021,10 +1021,19 @@ make_ip4_setting (shvarFile *ifcfg,
/* Handle DHCP settings */
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE);
if (value && strlen (value))
if (value && *value)
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, value, NULL);
g_free (value);
value = svGetValue (ifcfg, "DHCP_FQDN", FALSE);
if (value && *value) {
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NULL,
NM_SETTING_IP4_CONFIG_DHCP_FQDN, value,
NULL);
}
g_free (value);
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCP_SEND_HOSTNAME", TRUE),
NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT, svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXUINT32, 0),

View file

@ -2141,6 +2141,10 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
if (value)
svSetValue (ifcfg, "DHCP_HOSTNAME", value, FALSE);
value = nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4));
if (value)
svSetValue (ifcfg, "DHCP_FQDN", value, FALSE);
/* Missing DHCP_SEND_HOSTNAME means TRUE, and we prefer not write it explicitly
* in that case, because it is NM-specific variable
*/
@ -2784,6 +2788,7 @@ write_connection (NMConnection *connection,
if (!utils_ignore_ip_config (connection)) {
svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE);
svSetValue (ifcfg, "DHCP_FQDN", NULL, FALSE);
if (!write_ip4_setting (connection, ifcfg, error))
goto out;