mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-06 09:04:55 +00:00
merge: branch 'bg/hostname-setting-rh1766944'
https://bugzilla.redhat.com/show_bug.cgi?id=1766944 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/669
This commit is contained in:
commit
090c360ca4
|
@ -66,9 +66,12 @@ SpacesInContainerLiterals: false
|
|||
SpacesInParentheses: false
|
||||
|
||||
ForEachMacros: ['c_list_for_each',
|
||||
'c_list_for_each_prev',
|
||||
'c_list_for_each_prev_safe',
|
||||
'c_list_for_each_continue',
|
||||
'c_list_for_each_entry',
|
||||
'c_list_for_each_entry_continue',
|
||||
'c_list_for_each_entry_prev',
|
||||
'c_list_for_each_entry_safe',
|
||||
'c_list_for_each_entry_safe_continue',
|
||||
'c_list_for_each_entry_safe_unlink',
|
||||
|
@ -93,7 +96,6 @@ ForEachMacros: ['c_list_for_each',
|
|||
'ndp_msg_opt_rdnss_for_each_addr',
|
||||
'nla_for_each_attr',
|
||||
'nla_for_each_nested',
|
||||
'nm_c_list_for_each_entry_prev',
|
||||
'nm_dedup_multi_iter_for_each',
|
||||
'nm_ip_config_iter_ip4_address_for_each',
|
||||
'nm_ip_config_iter_ip4_route_for_each',
|
||||
|
@ -107,6 +109,7 @@ ForEachMacros: ['c_list_for_each',
|
|||
'nm_l3_config_data_iter_ip6_route_for_each',
|
||||
'nm_l3_config_data_iter_obj_for_each',
|
||||
'nm_manager_for_each_active_connection',
|
||||
'nm_manager_for_each_active_connection_prev',
|
||||
'nm_manager_for_each_active_connection_safe',
|
||||
'nm_manager_for_each_device',
|
||||
'nm_manager_for_each_device_safe',
|
||||
|
|
|
@ -943,6 +943,7 @@ libnm_core_lib_h_pub_real = \
|
|||
libnm-core/nm-setting-ethtool.h \
|
||||
libnm-core/nm-setting-generic.h \
|
||||
libnm-core/nm-setting-gsm.h \
|
||||
libnm-core/nm-setting-hostname.h \
|
||||
libnm-core/nm-setting-infiniband.h \
|
||||
libnm-core/nm-setting-ip-config.h \
|
||||
libnm-core/nm-setting-ip-tunnel.h \
|
||||
|
@ -1017,6 +1018,7 @@ libnm_core_lib_c_settings_real = \
|
|||
libnm-core/nm-setting-ethtool.c \
|
||||
libnm-core/nm-setting-generic.c \
|
||||
libnm-core/nm-setting-gsm.c \
|
||||
libnm-core/nm-setting-hostname.c \
|
||||
libnm-core/nm-setting-infiniband.c \
|
||||
libnm-core/nm-setting-ip-config.c \
|
||||
libnm-core/nm-setting-ip-tunnel.c \
|
||||
|
|
|
@ -881,7 +881,8 @@ const NmcMetaGenericInfo
|
|||
"," NM_SETTING_6LOWPAN_SETTING_NAME "," NM_SETTING_WIREGUARD_SETTING_NAME \
|
||||
"," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \
|
||||
"," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \
|
||||
"," NM_SETTING_OVS_DPDK_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
|
||||
"," NM_SETTING_OVS_DPDK_SETTING_NAME \
|
||||
"," NM_SETTING_HOSTNAME_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
|
||||
|
||||
const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = {
|
||||
NMC_META_GENERIC_WITH_NESTED("GENERAL", metagen_con_active_general), /* 0 */
|
||||
|
|
|
@ -564,6 +564,16 @@
|
|||
<property name="mtu"
|
||||
description="If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames." />
|
||||
</setting>
|
||||
<setting name="hostname" >
|
||||
<property name="priority"
|
||||
description="The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname." />
|
||||
<property name="from-dhcp"
|
||||
description="Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1)." />
|
||||
<property name="from-dns-lookup"
|
||||
description="Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1)." />
|
||||
<property name="only-from-default"
|
||||
description="If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1)." />
|
||||
</setting>
|
||||
<setting name="infiniband" >
|
||||
<property name="mac-address"
|
||||
alias="mac"
|
||||
|
|
|
@ -5633,6 +5633,24 @@ static const NMMetaPropertyInfo *const property_infos_GSM[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
#undef _CURRENT_NM_META_SETTING_TYPE
|
||||
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_HOSTNAME
|
||||
static const NMMetaPropertyInfo *const property_infos_HOSTNAME[] = {
|
||||
PROPERTY_INFO (NM_SETTING_HOSTNAME_PRIORITY, DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY,
|
||||
.property_type = &_pt_gobject_int,
|
||||
),
|
||||
PROPERTY_INFO (NM_SETTING_HOSTNAME_FROM_DHCP, DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DHCP,
|
||||
.property_type = &_pt_gobject_enum,
|
||||
),
|
||||
PROPERTY_INFO (NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP, DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
|
||||
.property_type = &_pt_gobject_enum,
|
||||
),
|
||||
PROPERTY_INFO (NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT, DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT,
|
||||
.property_type = &_pt_gobject_enum,
|
||||
),
|
||||
NULL
|
||||
};
|
||||
|
||||
#undef _CURRENT_NM_META_SETTING_TYPE
|
||||
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_INFINIBAND
|
||||
static const NMMetaPropertyInfo *const property_infos_INFINIBAND[] = {
|
||||
|
@ -7936,6 +7954,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
|
|||
#define SETTING_PRETTY_NAME_ETHTOOL N_("Ethtool settings")
|
||||
#define SETTING_PRETTY_NAME_GENERIC N_("Generic settings")
|
||||
#define SETTING_PRETTY_NAME_GSM N_("GSM mobile broadband connection")
|
||||
#define SETTING_PRETTY_NAME_HOSTNAME N_("Hostname settings")
|
||||
#define SETTING_PRETTY_NAME_INFINIBAND N_("InfiniBand connection")
|
||||
#define SETTING_PRETTY_NAME_IP4_CONFIG N_("IPv4 protocol")
|
||||
#define SETTING_PRETTY_NAME_IP6_CONFIG N_("IPv6 protocol")
|
||||
|
@ -8073,6 +8092,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
|
|||
),
|
||||
.setting_init_fcn = _setting_init_fcn_gsm,
|
||||
),
|
||||
SETTING_INFO (HOSTNAME),
|
||||
SETTING_INFO (INFINIBAND,
|
||||
.valid_parts = NM_META_SETTING_VALID_PARTS (
|
||||
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
|
||||
|
@ -8284,6 +8304,7 @@ static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = {
|
|||
NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM(IP4_CONFIG, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM(IP6_CONFIG, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM(HOSTNAME, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM(TC_CONFIG, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM(PROXY, FALSE),
|
||||
NULL,
|
||||
|
|
|
@ -203,6 +203,10 @@
|
|||
#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_ID N_("The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" which contains a SIM card matching the given identifier.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_OPERATOR_ID N_("A MCC/MNC string like \"310260\" or \"21601\" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" and \"sim-id\" which contains a SIM card provisioned by the given operator.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_GSM_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DHCP N_("Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
|
||||
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP N_("Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
|
||||
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT N_("If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
|
||||
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY N_("The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MAC_ADDRESS N_("If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
|
||||
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_P_KEY N_("The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka \"the P_Key at index 0\"). Otherwise, it is a 16-bit unsigned integer, whose high bit is set if it is a \"full membership\" P_Key.")
|
||||
|
|
|
@ -324,6 +324,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
|
|||
<xi:include href="xml/nm-setting-ethtool.xml"/>
|
||||
<xi:include href="xml/nm-setting-generic.xml"/>
|
||||
<xi:include href="xml/nm-setting-gsm.xml"/>
|
||||
<xi:include href="xml/nm-setting-hostname.xml"/>
|
||||
<xi:include href="xml/nm-setting-infiniband.xml"/>
|
||||
<xi:include href="xml/nm-setting-ip4-config.xml"/>
|
||||
<xi:include href="xml/nm-setting-ip6-config.xml"/>
|
||||
|
|
|
@ -33,6 +33,7 @@ libnm_core_headers = files(
|
|||
'nm-setting-ethtool.h',
|
||||
'nm-setting-generic.h',
|
||||
'nm-setting-gsm.h',
|
||||
'nm-setting-hostname.h',
|
||||
'nm-setting-infiniband.h',
|
||||
'nm-setting-ip-config.h',
|
||||
'nm-setting-ip-tunnel.h',
|
||||
|
@ -134,6 +135,7 @@ libnm_core_settings_sources = files(
|
|||
'nm-setting-ethtool.c',
|
||||
'nm-setting-generic.c',
|
||||
'nm-setting-gsm.c',
|
||||
'nm-setting-hostname.c',
|
||||
'nm-setting-infiniband.c',
|
||||
'nm-setting-ip-config.c',
|
||||
'nm-setting-ip-tunnel.c',
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "nm-setting-dummy.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-hostname.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
#include "nm-setting-ip-tunnel.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef struct _NMSettingDummy NMSettingDummy;
|
|||
typedef struct _NMSettingEthtool NMSettingEthtool;
|
||||
typedef struct _NMSettingGeneric NMSettingGeneric;
|
||||
typedef struct _NMSettingGsm NMSettingGsm;
|
||||
typedef struct _NMSettingHostname NMSettingHostname;
|
||||
typedef struct _NMSettingIP4Config NMSettingIP4Config;
|
||||
typedef struct _NMSettingIP6Config NMSettingIP6Config;
|
||||
typedef struct _NMSettingIPConfig NMSettingIPConfig;
|
||||
|
|
339
libnm-core/nm-setting-hostname.c
Normal file
339
libnm-core/nm-setting-hostname.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-setting-hostname.h"
|
||||
|
||||
#include "nm-setting-private.h"
|
||||
#include "nm-utils-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:nm-setting-hostname
|
||||
* @short_description: Contains properties related to the hostname
|
||||
* @include: nm-setting-hostname.h
|
||||
**/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHostname,
|
||||
PROP_PRIORITY,
|
||||
PROP_FROM_DHCP,
|
||||
PROP_FROM_DNS_LOOKUP,
|
||||
PROP_ONLY_FROM_DEFAULT, );
|
||||
|
||||
/**
|
||||
* NMSettingHostname:
|
||||
*
|
||||
* Hostname settings
|
||||
*
|
||||
* Since: 1.30
|
||||
*/
|
||||
struct _NMSettingHostname {
|
||||
NMSetting parent;
|
||||
int priority;
|
||||
NMTernary from_dhcp;
|
||||
NMTernary from_dns_lookup;
|
||||
NMTernary only_from_default;
|
||||
};
|
||||
|
||||
struct _NMSettingHostnameClass {
|
||||
NMSettingClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(NMSettingHostname, nm_setting_hostname, NM_TYPE_SETTING)
|
||||
|
||||
/**
|
||||
* nm_setting_hostname_get_priority:
|
||||
* @setting: the #NMSettingHostname
|
||||
*
|
||||
* Returns the value contained in the #NMSettingHostname:priority
|
||||
* property.
|
||||
*
|
||||
* Returns: the 'priority' property value
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
int
|
||||
nm_setting_hostname_get_priority(NMSettingHostname *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), 0);
|
||||
|
||||
return setting->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hostname_get_from_dhcp:
|
||||
* @setting: the #NMSettingHostname
|
||||
*
|
||||
* Returns the value contained in the #NMSettingHostname:from-dhcp
|
||||
* property.
|
||||
*
|
||||
* Returns: the 'from-dhcp' property value
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
NMTernary
|
||||
nm_setting_hostname_get_from_dhcp(NMSettingHostname *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT);
|
||||
|
||||
return setting->from_dhcp;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hostname_get_from_dns_lookup:
|
||||
* @setting: the #NMSettingHostname
|
||||
*
|
||||
* Returns the value contained in the #NMSettingHostname:from-dns-lookup
|
||||
* property.
|
||||
*
|
||||
* Returns: the 'from-dns-lookup' property value
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
NMTernary
|
||||
nm_setting_hostname_get_from_dns_lookup(NMSettingHostname *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT);
|
||||
|
||||
return setting->from_dns_lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hostname_get_only_from_default:
|
||||
* @setting: the #NMSettingHostname
|
||||
*
|
||||
* Returns the value contained in the #NMSettingHostname:only-from-default
|
||||
* property.
|
||||
*
|
||||
* Returns: the 'only-from-default' property value
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
NMTernary
|
||||
nm_setting_hostname_get_only_from_default(NMSettingHostname *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT);
|
||||
|
||||
return setting->only_from_default;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingHostname *self = NM_SETTING_HOSTNAME(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PRIORITY:
|
||||
g_value_set_int(value, self->priority);
|
||||
break;
|
||||
case PROP_FROM_DHCP:
|
||||
g_value_set_enum(value, self->from_dhcp);
|
||||
break;
|
||||
case PROP_FROM_DNS_LOOKUP:
|
||||
g_value_set_enum(value, self->from_dns_lookup);
|
||||
break;
|
||||
case PROP_ONLY_FROM_DEFAULT:
|
||||
g_value_set_enum(value, self->only_from_default);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingHostname *self = NM_SETTING_HOSTNAME(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PRIORITY:
|
||||
self->priority = g_value_get_int(value);
|
||||
break;
|
||||
case PROP_FROM_DHCP:
|
||||
self->from_dhcp = g_value_get_enum(value);
|
||||
break;
|
||||
case PROP_FROM_DNS_LOOKUP:
|
||||
self->from_dns_lookup = g_value_get_enum(value);
|
||||
break;
|
||||
case PROP_ONLY_FROM_DEFAULT:
|
||||
self->only_from_default = g_value_get_enum(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_setting_hostname_init(NMSettingHostname *setting)
|
||||
{
|
||||
setting->from_dhcp = NM_TERNARY_DEFAULT;
|
||||
setting->from_dns_lookup = NM_TERNARY_DEFAULT;
|
||||
setting->only_from_default = NM_TERNARY_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hostname_new:
|
||||
*
|
||||
* Creates a new #NMSettingHostname object with default values.
|
||||
*
|
||||
* Returns: (transfer full): the new empty #NMSettingHostname object
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
NMSetting *
|
||||
nm_setting_hostname_new(void)
|
||||
{
|
||||
return g_object_new(NM_TYPE_SETTING_HOSTNAME, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_hostname_class_init(NMSettingHostnameClass *klass)
|
||||
{
|
||||
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
||||
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
|
||||
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
/**
|
||||
* NMSettingHostname:priority
|
||||
*
|
||||
* The relative priority of this connection to determine the
|
||||
* system hostname. A lower numerical value is better (higher
|
||||
* priority). A connection with higher priority is considered
|
||||
* before connections with lower priority.
|
||||
*
|
||||
* If the value is zero, it can be overridden by a global value
|
||||
* from NetworkManager configuration. If the property doesn't have
|
||||
* a value in the global configuration, the value is assumed to be
|
||||
* 100.
|
||||
*
|
||||
* Negative values have the special effect of excluding other
|
||||
* connections with a greater numerical priority value; so in
|
||||
* presence of at least one negative priority, only connections
|
||||
* with the lowest priority value will be used to determine the
|
||||
* hostname.
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: priority
|
||||
* variable: HOSTNAME_PRIORITY(+)
|
||||
* default: missing variable means global value or 100
|
||||
* description: hostname priority
|
||||
* example: HOSTNAME_PRIORITY=50
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_PRIORITY] = g_param_spec_int(NM_SETTING_HOSTNAME_PRIORITY,
|
||||
"",
|
||||
"",
|
||||
G_MININT32,
|
||||
G_MAXINT32,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingHostname:from-dhcp
|
||||
*
|
||||
* Whether the system hostname can be determined from DHCP on
|
||||
* this connection.
|
||||
*
|
||||
* When set to %NM_TERNARY_DEFAULT, the value from global configuration
|
||||
* is used. If the property doesn't have a value in the global
|
||||
* configuration, NetworkManager assumes the value to be %NM_TERNARY_TRUE.
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: from-dhcp
|
||||
* variable: HOSTNAME_FROM_DHCP(+)
|
||||
* default: missing variable means global default or 1
|
||||
* description: whether the system hostname can be determined from DHCP
|
||||
* example: HOSTNAME_FROM_DHCP=0,1
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_FROM_DHCP] = g_param_spec_enum(
|
||||
NM_SETTING_HOSTNAME_FROM_DHCP,
|
||||
"",
|
||||
"",
|
||||
NM_TYPE_TERNARY,
|
||||
NM_TERNARY_DEFAULT,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingHostname:from-dns-lookup
|
||||
*
|
||||
* Whether the system hostname can be determined from reverse
|
||||
* DNS lookup of addresses on this device.
|
||||
*
|
||||
* When set to %NM_TERNARY_DEFAULT, the value from global configuration
|
||||
* is used. If the property doesn't have a value in the global
|
||||
* configuration, NetworkManager assumes the value to be %NM_TERNARY_TRUE.
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: from-dhcp
|
||||
* variable: HOSTNAME_FROM_DNS_LOOKUP(+)
|
||||
* default: missing variable means global default or 1
|
||||
* description: whether the system hostname can be determined from reverse
|
||||
* DNS lookup
|
||||
* example: HOSTNAME_FROM_DNS_LOOKUP=0,1
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_FROM_DNS_LOOKUP] = g_param_spec_enum(
|
||||
NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
|
||||
"",
|
||||
"",
|
||||
NM_TYPE_TERNARY,
|
||||
NM_TERNARY_DEFAULT,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingHostname:only-from-default
|
||||
*
|
||||
* If set to %NM_TERNARY_TRUE, NetworkManager attempts to get
|
||||
* the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this
|
||||
* device only when the device has the default route for the given
|
||||
* address family (IPv4/IPv6).
|
||||
*
|
||||
* If set to %NM_TERNARY_FALSE, the hostname can be set from this
|
||||
* device even if it doesn't have the default route.
|
||||
*
|
||||
* When set to %NM_TERNARY_DEFAULT, the value from global configuration
|
||||
* is used. If the property doesn't have a value in the global
|
||||
* configuration, NetworkManager assumes the value to be %NM_TERNARY_TRUE.
|
||||
*
|
||||
* Since: 1.30
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: only-best-device
|
||||
* variable: HOSTNAME_ONLY_FROM_DEFAULT(+)
|
||||
* default: missing variable means global default or 1
|
||||
* description: whether the hostname can be determined only from
|
||||
* devices with the default route
|
||||
* example: HOSTNAME_ONLY_FROM_DEFAULT=0,1
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_ONLY_FROM_DEFAULT] = g_param_spec_enum(
|
||||
NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT,
|
||||
"",
|
||||
"",
|
||||
NM_TYPE_TERNARY,
|
||||
NM_TERNARY_DEFAULT,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
_nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HOSTNAME);
|
||||
}
|
53
libnm-core/nm-setting-hostname.h
Normal file
53
libnm-core/nm-setting-hostname.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_SETTING_HOSTNAME_H
|
||||
#define NM_SETTING_HOSTNAME_H
|
||||
|
||||
#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
|
||||
#error "Only <NetworkManager.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "nm-setting.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_SETTING_HOSTNAME (nm_setting_hostname_get_type())
|
||||
#define NM_SETTING_HOSTNAME(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_HOSTNAME, NMSettingHostname))
|
||||
#define NM_SETTING_HOSTNAME_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_HOSTNAME, NMSettingHostnameClass))
|
||||
#define NM_IS_SETTING_HOSTNAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_HOSTNAME))
|
||||
#define NM_IS_SETTING_HOSTNAME_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_HOSTNAME))
|
||||
#define NM_SETTING_HOSTNAME_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_HOSTNAME, NMSettingHostnameClass))
|
||||
|
||||
#define NM_SETTING_HOSTNAME_SETTING_NAME "hostname"
|
||||
|
||||
#define NM_SETTING_HOSTNAME_PRIORITY "priority"
|
||||
#define NM_SETTING_HOSTNAME_FROM_DHCP "from-dhcp"
|
||||
#define NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP "from-dns-lookup"
|
||||
#define NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT "only-from-default"
|
||||
|
||||
typedef struct _NMSettingHostnameClass NMSettingHostnameClass;
|
||||
|
||||
NM_AVAILABLE_IN_1_30
|
||||
GType nm_setting_hostname_get_type(void);
|
||||
NM_AVAILABLE_IN_1_30
|
||||
NMSetting *nm_setting_hostname_new(void);
|
||||
|
||||
NM_AVAILABLE_IN_1_30
|
||||
int nm_setting_hostname_get_priority(NMSettingHostname *setting);
|
||||
NM_AVAILABLE_IN_1_30
|
||||
NMTernary nm_setting_hostname_get_from_dhcp(NMSettingHostname *setting);
|
||||
NM_AVAILABLE_IN_1_30
|
||||
NMTernary nm_setting_hostname_get_from_dns_lookup(NMSettingHostname *setting);
|
||||
NM_AVAILABLE_IN_1_30
|
||||
NMTernary nm_setting_hostname_get_only_from_default(NMSettingHostname *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_SETTING_HOSTNAME_H */
|
|
@ -62,6 +62,7 @@
|
|||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-hostname.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
|
|
|
@ -1766,6 +1766,11 @@ global:
|
|||
nm_keyfile_read;
|
||||
nm_keyfile_warn_severity_get_type;
|
||||
nm_keyfile_write;
|
||||
nm_setting_hostname_get_from_dhcp;
|
||||
nm_setting_hostname_get_from_dns_lookup;
|
||||
nm_setting_hostname_get_only_from_default;
|
||||
nm_setting_hostname_get_priority;
|
||||
nm_setting_hostname_get_type;
|
||||
nm_setting_ovs_external_ids_check_key;
|
||||
nm_setting_ovs_external_ids_check_val;
|
||||
nm_setting_ovs_external_ids_get_data;
|
||||
|
|
|
@ -1166,7 +1166,7 @@ nml_dbus_object_iface_data_get(NMLDBusObject *dbobj,
|
|||
count++;
|
||||
}
|
||||
} else {
|
||||
nm_c_list_for_each_entry_prev (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
|
||||
c_list_for_each_entry_prev (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
|
||||
if (db_iface_data->dbus_iface_is_wellknown)
|
||||
break;
|
||||
if (db_iface_data->iface_removed)
|
||||
|
|
|
@ -278,18 +278,24 @@ no-auto-default=*
|
|||
this option. An hostname empty or equal to 'localhost', 'localhost6',
|
||||
'localhost.localdomain' or 'localhost6.localdomain' is considered invalid.
|
||||
</para>
|
||||
<para><literal>default</literal>: NetworkManager will update the hostname
|
||||
with the one provided via DHCP on the main connection (the one with a default
|
||||
route). If not present, the hostname will be updated to the last one set
|
||||
outside NetworkManager. If it is not valid, NetworkManager will try to recover
|
||||
the hostname from the reverse lookup of the IP address of the main connection.
|
||||
If this fails too, the hostname will be set to 'localhost.localdomain'.
|
||||
<para><literal>default</literal>: NetworkManager will update the
|
||||
hostname with the one provided via DHCP or reverse DNS lookup of the
|
||||
IP address on the connection with the default route or on any
|
||||
connection with the property hostname.only-from-default set to
|
||||
'<literal>false</literal>'. Connections are considered in order of
|
||||
increasing value of the <literal>hostname.priority</literal>
|
||||
property. In case multiple connections have the same priority,
|
||||
connections activated earlier are considered first. If no hostname can
|
||||
be determined in such way, the hostname will be updated to the last
|
||||
one set outside NetworkManager or to 'localhost.localdomain'.
|
||||
</para>
|
||||
<para><literal>dhcp</literal>: NetworkManager will update the transient hostname
|
||||
only with information coming from DHCP. No fallback nor reverse lookup will be
|
||||
performed, but when the dhcp connection providing the hostname is deactivated,
|
||||
the hostname is reset to the last hostname set outside NetworkManager or
|
||||
'localhost' if none valid is there.
|
||||
<para><literal>dhcp</literal>: this is similar to
|
||||
'<literal>default</literal>', with the difference that after trying to
|
||||
get the DHCP hostname, reverse DNS lookup is not done. Note that
|
||||
selecting this option is equivalent to setting the property
|
||||
'<literal>hostname.from-dns-lookup</literal>' to
|
||||
'<literal>false</literal>' globally for all connections in
|
||||
NetworkManager.conf.
|
||||
</para>
|
||||
<para><literal>none</literal>: NetworkManager will not manage the transient
|
||||
hostname and will never set it.
|
||||
|
@ -734,6 +740,18 @@ ipv6.ip6-privacy=0
|
|||
<varlistentry>
|
||||
<term><varname>gsm.mtu</varname></term>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>hostname.from-dhcp</varname></term>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>hostname.from-dns-lookup</varname></term>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>hostname.only-from-default</varname></term>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>hostname.priority</varname></term>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>infiniband.mtu</varname></term>
|
||||
<listitem><para>If configured explicitly to 0, the MTU is not reconfigured during device activation unless it is required due to IPv6 constraints. If left unspecified, a DHCP/IPv6 SLAAC provided value is used or the MTU is left unspecified on activation.</para></listitem>
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
_what &&c_list_contains(list, &_what->member); \
|
||||
})
|
||||
|
||||
/* iterate over the list backwards. */
|
||||
#define nm_c_list_for_each_entry_prev(_iter, _list, _m) \
|
||||
for (_iter = c_list_entry((_list)->prev, __typeof__(*_iter), _m); &(_iter)->_m != (_list); \
|
||||
_iter = c_list_entry((_iter)->_m.prev, __typeof__(*_iter), _m))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-hostname.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
#include "nm-setting-ip-config.h"
|
||||
#include "nm-setting-ip-tunnel.h"
|
||||
|
@ -243,6 +244,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
|
|||
.setting_name = NM_SETTING_GSM_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_gsm_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_HOSTNAME] =
|
||||
{
|
||||
.meta_type = NM_META_SETTING_TYPE_HOSTNAME,
|
||||
.setting_priority = NM_SETTING_PRIORITY_IP,
|
||||
.setting_name = NM_SETTING_HOSTNAME_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_hostname_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_INFINIBAND] =
|
||||
{
|
||||
.meta_type = NM_META_SETTING_TYPE_INFINIBAND,
|
||||
|
|
|
@ -119,6 +119,7 @@ typedef enum {
|
|||
NM_META_SETTING_TYPE_ETHTOOL,
|
||||
NM_META_SETTING_TYPE_GENERIC,
|
||||
NM_META_SETTING_TYPE_GSM,
|
||||
NM_META_SETTING_TYPE_HOSTNAME,
|
||||
NM_META_SETTING_TYPE_INFINIBAND,
|
||||
NM_META_SETTING_TYPE_IP_TUNNEL,
|
||||
NM_META_SETTING_TYPE_IP4_CONFIG,
|
||||
|
|
|
@ -42,4 +42,15 @@ c_list_length_is(const CList *list, unsigned long check_len)
|
|||
return n == check_len;
|
||||
}
|
||||
|
||||
#define c_list_for_each_prev(_iter, _list) \
|
||||
for (_iter = (_list)->prev; (_iter) != (_list); _iter = (_iter)->prev)
|
||||
|
||||
#define c_list_for_each_prev_safe(_iter, _safe, _list) \
|
||||
for (_iter = (_list)->prev, _safe = (_iter)->prev; (_iter) != (_list); \
|
||||
_iter = (_safe), _safe = (_safe)->prev)
|
||||
|
||||
#define c_list_for_each_entry_prev(_iter, _list, _m) \
|
||||
for (_iter = c_list_entry((_list)->prev, __typeof__(*_iter), _m); &(_iter)->_m != (_list); \
|
||||
_iter = c_list_entry((_iter)->_m.prev, __typeof__(*_iter), _m))
|
||||
|
||||
#endif /* __C_LIST_UTIL_H__ */
|
||||
|
|
|
@ -206,6 +206,23 @@ typedef struct {
|
|||
NMEthtoolRingState * ring;
|
||||
} EthtoolState;
|
||||
|
||||
typedef enum {
|
||||
RESOLVER_WAIT_ADDRESS = 0,
|
||||
RESOLVER_IN_PROGRESS,
|
||||
RESOLVER_DONE,
|
||||
} ResolverState;
|
||||
|
||||
typedef struct {
|
||||
ResolverState state;
|
||||
GResolver * resolver;
|
||||
GInetAddress *address;
|
||||
GCancellable *cancellable;
|
||||
char * hostname;
|
||||
NMDevice * device;
|
||||
guint timeout_id; /* Used when waiting for the address */
|
||||
int addr_family;
|
||||
} HostnameResolver;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
|
@ -218,6 +235,7 @@ enum {
|
|||
REMOVED,
|
||||
RECHECK_AUTO_ACTIVATE,
|
||||
RECHECK_ASSUME,
|
||||
DNS_LOOKUP_DONE,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
@ -324,6 +342,14 @@ typedef struct _NMDevicePrivate {
|
|||
|
||||
int auth_retries;
|
||||
|
||||
union {
|
||||
struct {
|
||||
HostnameResolver *hostname_resolver_6;
|
||||
HostnameResolver *hostname_resolver_4;
|
||||
};
|
||||
HostnameResolver *hostname_resolver_x[2];
|
||||
};
|
||||
|
||||
union {
|
||||
const guint8 hw_addr_len; /* read-only */
|
||||
guint8 hw_addr_len_;
|
||||
|
@ -866,6 +892,22 @@ static NM_UTILS_LOOKUP_STR_DEFINE(mtu_source_to_str,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_hostname_resolver_free(HostnameResolver *resolver)
|
||||
{
|
||||
if (!resolver)
|
||||
return;
|
||||
|
||||
nm_clear_g_source(&resolver->timeout_id);
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
nm_g_object_unref(resolver->resolver);
|
||||
nm_g_object_unref(resolver->address);
|
||||
g_free(resolver->hostname);
|
||||
nm_g_slice_free(resolver);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMSettingIP6ConfigPrivacy
|
||||
_ip6_privacy_clamp(NMSettingIP6ConfigPrivacy use_tempaddr)
|
||||
{
|
||||
|
@ -15618,6 +15660,7 @@ static void
|
|||
_cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
guint i;
|
||||
|
||||
_cancel_activation(self);
|
||||
|
||||
|
@ -15642,6 +15685,9 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
|
|||
|
||||
nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[i], _hostname_resolver_free);
|
||||
|
||||
_cleanup_ip_pre(self, AF_INET, cleanup_type);
|
||||
_cleanup_ip_pre(self, AF_INET6, cleanup_type);
|
||||
}
|
||||
|
@ -17467,6 +17513,178 @@ nm_device_auth_retries_try_next(NMDevice *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
HostnameResolver *resolver;
|
||||
NMDevice * self;
|
||||
gs_free char * hostname = NULL;
|
||||
gs_free char * addr_str = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
hostname = g_resolver_lookup_by_address_finish(G_RESOLVER(source), result, &error);
|
||||
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
resolver = user_data;
|
||||
self = resolver->device;
|
||||
resolver->state = RESOLVER_DONE;
|
||||
resolver->hostname = g_strdup(hostname);
|
||||
|
||||
_LOGD(LOGD_DNS,
|
||||
"hostname-from-dns: lookup done for %s, result %s%s%s",
|
||||
(addr_str = g_inet_address_to_string(resolver->address)),
|
||||
NM_PRINT_FMT_QUOTE_STRING(hostname));
|
||||
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
hostname_dns_address_timeout(gpointer user_data)
|
||||
{
|
||||
HostnameResolver *resolver = user_data;
|
||||
NMDevice * self = resolver->device;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE);
|
||||
|
||||
nm_assert(resolver->state == RESOLVER_WAIT_ADDRESS);
|
||||
nm_assert(!resolver->address);
|
||||
nm_assert(!resolver->cancellable);
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: timed out while waiting IPv%c address",
|
||||
nm_utils_addr_family_to_char(resolver->addr_family));
|
||||
|
||||
resolver->timeout_id = 0;
|
||||
resolver->state = RESOLVER_DONE;
|
||||
g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* return value is valid only immediately */
|
||||
const char *
|
||||
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_wait)
|
||||
{
|
||||
NMDevicePrivate * priv;
|
||||
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||||
HostnameResolver *resolver;
|
||||
NMIPConfig * ip_config;
|
||||
const char * method;
|
||||
gboolean address_changed = FALSE;
|
||||
gs_unref_object GInetAddress *new_address = NULL;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
|
||||
priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
/* If the device is not supposed to have addresses,
|
||||
* return an immediate empty result.*/
|
||||
method = nm_device_get_effective_ip_config_method(self, addr_family);
|
||||
if (IS_IPv4) {
|
||||
if (NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (NM_IN_STRSET(method,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
||||
nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
resolver = priv->hostname_resolver_x[IS_IPv4];
|
||||
if (!resolver) {
|
||||
resolver = g_slice_new(HostnameResolver);
|
||||
*resolver = (HostnameResolver){
|
||||
.resolver = g_resolver_get_default(),
|
||||
.device = self,
|
||||
.addr_family = addr_family,
|
||||
.state = RESOLVER_WAIT_ADDRESS,
|
||||
};
|
||||
priv->hostname_resolver_x[IS_IPv4] = resolver;
|
||||
}
|
||||
|
||||
/* Determine the first address of the interface and
|
||||
* whether it changed from the previous lookup */
|
||||
ip_config = priv->ip_config_x[IS_IPv4];
|
||||
if (ip_config) {
|
||||
const NMPlatformIPAddress *addr;
|
||||
|
||||
addr = nm_ip_config_get_first_address(ip_config);
|
||||
if (addr) {
|
||||
new_address = g_inet_address_new_from_bytes(addr->address_ptr,
|
||||
IS_IPv4 ? G_SOCKET_FAMILY_IPV4
|
||||
: G_SOCKET_FAMILY_IPV6);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_address && resolver->address) {
|
||||
if (!g_inet_address_equal(new_address, resolver->address))
|
||||
address_changed = TRUE;
|
||||
} else if (new_address != resolver->address)
|
||||
address_changed = TRUE;
|
||||
|
||||
{
|
||||
gs_free char *old_str = NULL;
|
||||
gs_free char *new_str = NULL;
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: ipv%c resolver state %d, old address %s, new address %s",
|
||||
nm_utils_addr_family_to_char(resolver->addr_family),
|
||||
resolver->state,
|
||||
resolver->address ? (old_str = g_inet_address_to_string(resolver->address))
|
||||
: "(null)",
|
||||
new_address ? (new_str = g_inet_address_to_string(new_address)) : "(null)");
|
||||
}
|
||||
|
||||
/* In every state, if the address changed, we restart
|
||||
* the resolution with the new address */
|
||||
if (address_changed) {
|
||||
nm_clear_g_cancellable(&resolver->cancellable);
|
||||
nm_g_object_unref(resolver->address);
|
||||
resolver->state = RESOLVER_WAIT_ADDRESS;
|
||||
}
|
||||
|
||||
if (address_changed && new_address) {
|
||||
gs_free char *str = NULL;
|
||||
|
||||
_LOGT(LOGD_DNS,
|
||||
"hostname-from-dns: starting lookup for address %s",
|
||||
(str = g_inet_address_to_string(new_address)));
|
||||
|
||||
resolver->state = RESOLVER_IN_PROGRESS;
|
||||
resolver->cancellable = g_cancellable_new();
|
||||
resolver->address = g_steal_pointer(&new_address);
|
||||
g_resolver_lookup_by_address_async(resolver->resolver,
|
||||
resolver->address,
|
||||
resolver->cancellable,
|
||||
hostname_dns_lookup_callback,
|
||||
resolver);
|
||||
nm_clear_g_source(&resolver->timeout_id);
|
||||
}
|
||||
|
||||
switch (resolver->state) {
|
||||
case RESOLVER_WAIT_ADDRESS:
|
||||
if (!resolver->timeout_id)
|
||||
resolver->timeout_id = g_timeout_add(30000, hostname_dns_address_timeout, resolver);
|
||||
NM_SET_OUT(out_wait, TRUE);
|
||||
return NULL;
|
||||
case RESOLVER_IN_PROGRESS:
|
||||
NM_SET_OUT(out_wait, TRUE);
|
||||
return NULL;
|
||||
case RESOLVER_DONE:
|
||||
NM_SET_OUT(out_wait, FALSE);
|
||||
return resolver->hostname;
|
||||
}
|
||||
|
||||
return nm_assert_unreachable_val(NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
|
@ -18644,6 +18862,16 @@ nm_device_class_init(NMDeviceClass *klass)
|
|||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
signals[DNS_LOOKUP_DONE] = g_signal_new(NM_DEVICE_DNS_LOOKUP_DONE,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
/* Connection defaults from plugins */
|
||||
|
|
|
@ -116,6 +116,7 @@ nm_device_state_reason_check(NMDeviceStateReason reason)
|
|||
#define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */
|
||||
|
||||
/* Internal signals */
|
||||
#define NM_DEVICE_DNS_LOOKUP_DONE "dns-lookup-done"
|
||||
#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed"
|
||||
#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed"
|
||||
#define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated"
|
||||
|
@ -863,4 +864,7 @@ const char *nm_device_state_reason_to_str(NMDeviceStateReason reason);
|
|||
|
||||
gboolean nm_device_is_vpn(NMDevice *self);
|
||||
|
||||
const char *
|
||||
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_pending);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||||
|
|
|
@ -369,6 +369,12 @@ nm_ip_config_hash(const NMIPConfig *self, GChecksum *sum, gboolean dns_only)
|
|||
_NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_hash, nm_ip6_config_hash, sum, dns_only);
|
||||
}
|
||||
|
||||
static inline gconstpointer
|
||||
nm_ip_config_get_first_address(NMIPConfig *self)
|
||||
{
|
||||
_NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_first_address, nm_ip6_config_get_first_address);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nm_ip_config_add_address(NMIPConfig *self, const NMPlatformIPAddress *address)
|
||||
{
|
||||
|
|
|
@ -142,7 +142,7 @@ typedef struct {
|
|||
|
||||
GArray *capabilities;
|
||||
|
||||
CList active_connections_lst_head;
|
||||
CList active_connections_lst_head; /* Oldest ACs at the beginning */
|
||||
CList async_op_lst_head;
|
||||
guint ac_cleanup_id;
|
||||
NMActiveConnection *primary_connection;
|
||||
|
@ -941,7 +941,7 @@ active_connection_add(NMManager *self, NMActiveConnection *active)
|
|||
nm_assert(NM_IS_ACTIVE_CONNECTION(active));
|
||||
nm_assert(!c_list_is_linked(&active->active_connections_lst));
|
||||
|
||||
c_list_link_front(&priv->active_connections_lst_head, &active->active_connections_lst);
|
||||
c_list_link_tail(&priv->active_connections_lst_head, &active->active_connections_lst);
|
||||
g_object_ref(active);
|
||||
|
||||
g_signal_connect(active,
|
||||
|
@ -7867,7 +7867,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|||
break;
|
||||
case PROP_ACTIVE_CONNECTIONS:
|
||||
ptrarr = g_ptr_array_new();
|
||||
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
|
||||
c_list_for_each_entry_prev (ac,
|
||||
&priv->active_connections_lst_head,
|
||||
active_connections_lst) {
|
||||
path = nm_dbus_object_get_path(NM_DBUS_OBJECT(ac));
|
||||
if (path)
|
||||
g_ptr_array_add(ptrarr, g_strdup(path));
|
||||
|
|
|
@ -72,6 +72,7 @@ NMState nm_manager_get_state(NMManager *manager);
|
|||
|
||||
const CList *nm_manager_get_active_connections(NMManager *manager);
|
||||
|
||||
/* From least recently activated */
|
||||
#define nm_manager_for_each_active_connection(manager, iter, tmp_list) \
|
||||
for (tmp_list = nm_manager_get_active_connections(manager), \
|
||||
iter = c_list_entry(tmp_list->next, NMActiveConnection, active_connections_lst); \
|
||||
|
@ -86,6 +87,22 @@ const CList *nm_manager_get_active_connections(NMManager *manager);
|
|||
NMActiveConnection, \
|
||||
active_connections_lst))
|
||||
|
||||
/* From most recently activated */
|
||||
#define nm_manager_for_each_active_connection_prev(manager, iter, tmp_list) \
|
||||
for (tmp_list = nm_manager_get_active_connections(manager), \
|
||||
iter = c_list_entry(tmp_list->prev, NMActiveConnection, active_connections_lst); \
|
||||
({ \
|
||||
const gboolean _has_prev = (&iter->active_connections_lst != tmp_list); \
|
||||
\
|
||||
if (!_has_prev) \
|
||||
iter = NULL; \
|
||||
_has_prev; \
|
||||
}); \
|
||||
iter = c_list_entry(iter->active_connections_lst.prev, \
|
||||
NMActiveConnection, \
|
||||
active_connections_lst))
|
||||
|
||||
/* From least recently activated */
|
||||
#define nm_manager_for_each_active_connection_safe(manager, iter, tmp_list, iter_safe) \
|
||||
for (tmp_list = nm_manager_get_active_connections(manager), iter_safe = tmp_list->next; ({ \
|
||||
if (iter_safe != tmp_list) { \
|
||||
|
|
316
src/nm-policy.c
316
src/nm-policy.c
|
@ -117,6 +117,8 @@ _PRIV_TO_SELF(NMPolicyPrivate *priv)
|
|||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "policy"
|
||||
#undef _NMLOG_ENABLED
|
||||
#define _NMLOG_ENABLED(level, domain) (nm_logging_enabled((level), (domain)))
|
||||
#define _NMLOG(level, domain, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
|
@ -131,6 +133,7 @@ _PRIV_TO_SELF(NMPolicyPrivate *priv)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void update_system_hostname(NMPolicy *self, const char *msg);
|
||||
static void schedule_activate_all(NMPolicy *self);
|
||||
static void schedule_activate_check(NMPolicy *self, NMDevice *device);
|
||||
static NMDevice *get_default_device(NMPolicy *self, int addr_family);
|
||||
|
@ -354,11 +357,11 @@ device_ip6_prefix_delegated(NMDevice *device, NMPlatformIP6Address *prefix, gpoi
|
|||
delegation->device = device;
|
||||
delegation->prefix = *prefix;
|
||||
|
||||
/* The newly activated connections are added to the list beginning,
|
||||
* so traversing it from the beginning makes it likely for newly
|
||||
/* The newly activated connections are added to the end of the list,
|
||||
* so traversing it from the end makes it likely for newly
|
||||
* activated connections that have no subnet assigned to be served
|
||||
* first. That is a simple yet fair policy, which is good. */
|
||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
||||
nm_manager_for_each_active_connection_prev (priv->manager, ac, tmp_list) {
|
||||
NMDevice *to_device;
|
||||
|
||||
to_device = nm_active_connection_get_device(ac);
|
||||
|
@ -671,20 +674,168 @@ lookup_by_address(NMPolicy *self)
|
|||
self);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMDevice *device;
|
||||
int priority;
|
||||
bool from_dhcp : 1;
|
||||
bool from_dns : 1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
bool ip_6;
|
||||
bool ip_4;
|
||||
};
|
||||
bool ip_x[2];
|
||||
};
|
||||
} DeviceHostnameInfo;
|
||||
|
||||
static int
|
||||
device_hostname_info_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const DeviceHostnameInfo *info1 = a;
|
||||
const DeviceHostnameInfo *info2 = b;
|
||||
|
||||
NM_CMP_FIELD(info1, info2, priority);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NM_CON_DEFAULT_NOP("hostname.from-dhcp");
|
||||
NM_CON_DEFAULT_NOP("hostname.from-dns-lookup");
|
||||
NM_CON_DEFAULT_NOP("hostname.only-from-default");
|
||||
|
||||
static gboolean
|
||||
device_get_hostname_property_boolean(NMDevice *device, const char *name)
|
||||
{
|
||||
NMSettingHostname *s_hostname;
|
||||
char buf[128];
|
||||
int value;
|
||||
|
||||
nm_assert(NM_IN_STRSET(name,
|
||||
NM_SETTING_HOSTNAME_FROM_DHCP,
|
||||
NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
|
||||
NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT));
|
||||
|
||||
s_hostname = nm_device_get_applied_setting(device, NM_TYPE_SETTING_HOSTNAME);
|
||||
|
||||
if (s_hostname) {
|
||||
g_object_get(s_hostname, name, &value, NULL);
|
||||
if (NM_IN_SET(value, NM_TERNARY_FALSE, NM_TERNARY_TRUE))
|
||||
return value;
|
||||
}
|
||||
|
||||
return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
||||
nm_sprintf_buf(buf, "hostname.%s", name),
|
||||
device,
|
||||
NM_TERNARY_FALSE,
|
||||
NM_TERNARY_TRUE,
|
||||
NM_TERNARY_TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
device_get_hostname_priority(NMDevice *device)
|
||||
{
|
||||
NMSettingHostname *s_hostname;
|
||||
int priority;
|
||||
|
||||
s_hostname = nm_device_get_applied_setting(device, NM_TYPE_SETTING_HOSTNAME);
|
||||
if (s_hostname) {
|
||||
priority = nm_setting_hostname_get_priority(s_hostname);
|
||||
if (priority != 0)
|
||||
return priority;
|
||||
}
|
||||
|
||||
return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
||||
NM_CON_DEFAULT("hostname.priority"),
|
||||
device,
|
||||
G_MININT,
|
||||
G_MAXINT,
|
||||
100);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
build_device_hostname_infos(NMPolicy *self)
|
||||
{
|
||||
NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const CList * tmp_clist;
|
||||
NMActiveConnection *ac;
|
||||
GArray * array = NULL;
|
||||
|
||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_clist) {
|
||||
DeviceHostnameInfo *info;
|
||||
NMDevice * device;
|
||||
gboolean only_from_default;
|
||||
|
||||
device = nm_active_connection_get_device(ac);
|
||||
if (!device)
|
||||
continue;
|
||||
|
||||
only_from_default =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT);
|
||||
if (only_from_default && ac != priv->default_ac4 && ac != priv->default_ac6)
|
||||
continue;
|
||||
|
||||
if (!array)
|
||||
array = g_array_sized_new(FALSE, FALSE, sizeof(DeviceHostnameInfo), 4);
|
||||
|
||||
info = nm_g_array_append_new(array, DeviceHostnameInfo);
|
||||
*info = (DeviceHostnameInfo){
|
||||
.device = device,
|
||||
.priority = device_get_hostname_priority(device),
|
||||
.from_dhcp =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_FROM_DHCP),
|
||||
.from_dns =
|
||||
device_get_hostname_property_boolean(device, NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP),
|
||||
.ip_4 = priv->default_ac4 || !only_from_default,
|
||||
.ip_6 = priv->default_ac6 || !only_from_default,
|
||||
};
|
||||
}
|
||||
|
||||
if (array && array->len > 1) {
|
||||
const DeviceHostnameInfo *info0;
|
||||
guint i;
|
||||
|
||||
g_array_sort(array, device_hostname_info_compare);
|
||||
|
||||
info0 = &g_array_index(array, DeviceHostnameInfo, 0);
|
||||
if (info0->priority < 0) {
|
||||
for (i = 1; i < array->len; i++) {
|
||||
const DeviceHostnameInfo *info = &g_array_index(array, DeviceHostnameInfo, i);
|
||||
|
||||
if (info->priority > info0->priority) {
|
||||
g_array_set_size(array, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static void
|
||||
device_dns_lookup_done(NMDevice *device, gpointer user_data)
|
||||
{
|
||||
NMPolicy *self = user_data;
|
||||
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
update_system_hostname(self, "lookup finished");
|
||||
}
|
||||
|
||||
static void
|
||||
update_system_hostname(NMPolicy *self, const char *msg)
|
||||
{
|
||||
NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const char * configured_hostname;
|
||||
gs_free char * temp_hostname = NULL;
|
||||
const char * dhcp_hostname, *p;
|
||||
NMIP4Config * ip4_config;
|
||||
NMIP6Config * ip6_config;
|
||||
gboolean external_hostname = FALSE;
|
||||
const NMPlatformIP4Address *addr4;
|
||||
const NMPlatformIP6Address *addr6;
|
||||
NMDevice * device;
|
||||
NMDhcpConfig * dhcp_config;
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const char * configured_hostname;
|
||||
gs_free char * temp_hostname = NULL;
|
||||
const char * dhcp_hostname, *p;
|
||||
gboolean external_hostname = FALSE;
|
||||
NMDhcpConfig * dhcp_config;
|
||||
gs_unref_array GArray *infos = NULL;
|
||||
DeviceHostnameInfo * info;
|
||||
guint i;
|
||||
int IS_IPv4;
|
||||
|
||||
g_return_if_fail(self != NULL);
|
||||
|
||||
|
@ -724,10 +875,9 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
/* Hostname precedence order:
|
||||
*
|
||||
* 1) a configured hostname (from settings)
|
||||
* 2) automatic hostname from the default device's config (DHCP, VPN, etc)
|
||||
* 3) the last hostname set outside NM
|
||||
* 4) reverse-DNS of the best device's IPv4 address
|
||||
*
|
||||
* 2) automatic hostname from DHCP of eligible interfaces
|
||||
* 3) reverse-DNS lookup of the first address on eligible interfaces
|
||||
* 4) the last hostname set outside NM
|
||||
*/
|
||||
|
||||
/* Try a persistent hostname first */
|
||||
|
@ -738,40 +888,73 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->default_ac4) {
|
||||
/* Grab a hostname out of the device's DHCP4 config */
|
||||
dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET), AF_INET);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "host_name");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, "from DHCPv4");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it",
|
||||
dhcp_hostname);
|
||||
}
|
||||
infos = build_device_hostname_infos(self);
|
||||
|
||||
if (infos && _LOGT_ENABLED(LOGD_DNS)) {
|
||||
_LOGT(LOGD_DNS, "device hostname info:");
|
||||
for (i = 0; i < infos->len; i++) {
|
||||
info = &g_array_index(infos, DeviceHostnameInfo, i);
|
||||
_LOGT(LOGD_DNS,
|
||||
" - prio:%4d ipv:%c%c dhcp:%d dns:%d dev:%s",
|
||||
info->priority,
|
||||
info->ip_4 ? '4' : '-',
|
||||
info->ip_6 ? '6' : '-',
|
||||
info->from_dhcp,
|
||||
info->from_dns,
|
||||
nm_device_get_iface(info->device));
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->default_ac6) {
|
||||
/* Grab a hostname out of the device's DHCP6 config */
|
||||
dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET6), AF_INET6);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "fqdn_fqdn");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, "from DHCPv6");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
for (i = 0; infos && i < infos->len; i++) {
|
||||
info = &g_array_index(infos, DeviceHostnameInfo, i);
|
||||
g_signal_handlers_disconnect_by_func(info->device, device_dns_lookup_done, self);
|
||||
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
||||
const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
|
||||
|
||||
if (info->from_dhcp && info->ip_x[IS_IPv4]) {
|
||||
dhcp_config = nm_device_get_dhcp_config(info->device, addr_family);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname =
|
||||
nm_dhcp_config_get_option(dhcp_config, IS_IPv4 ? "host_name" : "fqdn_fqdn");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces(dhcp_hostname);
|
||||
if (p[0]) {
|
||||
_set_hostname(self, p, IS_IPv4 ? "from DHCPv4" : "from DHCPv6");
|
||||
priv->dhcp_hostname = TRUE;
|
||||
return;
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv%c-provided hostname '%s' looks invalid; "
|
||||
"ignoring it",
|
||||
nm_utils_addr_family_to_char(addr_family),
|
||||
dhcp_hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->hostname_mode != NM_POLICY_HOSTNAME_MODE_DHCP) {
|
||||
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
||||
const int addr_family = IS_IPv4 ? AF_INET6 : AF_INET;
|
||||
|
||||
if (info->from_dns && info->ip_x[IS_IPv4]) {
|
||||
const char *result;
|
||||
gboolean wait;
|
||||
|
||||
result =
|
||||
nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait);
|
||||
if (result) {
|
||||
_set_hostname(self, result, "from address lookup");
|
||||
return;
|
||||
}
|
||||
if (wait) {
|
||||
g_signal_connect(info->device,
|
||||
NM_DEVICE_DNS_LOOKUP_DONE,
|
||||
(GCallback) device_dns_lookup_done,
|
||||
self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_LOGW(LOGD_DNS,
|
||||
"set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it",
|
||||
dhcp_hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -795,14 +978,6 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
|
||||
priv->dhcp_hostname = FALSE;
|
||||
|
||||
if (!priv->default_ac4 && !priv->default_ac6) {
|
||||
/* No best device; fall back to the last hostname set externally
|
||||
* to NM or if there wasn't one, 'localhost.localdomain'
|
||||
*/
|
||||
_set_hostname(self, priv->orig_hostname, "no default device");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no automatically-configured hostname, try using the last hostname
|
||||
* set externally to NM
|
||||
*/
|
||||
|
@ -811,30 +986,7 @@ update_system_hostname(NMPolicy *self, const char *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
/* No configured hostname, no automatically determined hostname, and no
|
||||
* bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
|
||||
*/
|
||||
device = get_default_device(self, AF_INET);
|
||||
ip4_config = device ? nm_device_get_ip4_config(device) : NULL;
|
||||
|
||||
device = get_default_device(self, AF_INET6);
|
||||
ip6_config = device ? nm_device_get_ip6_config(device) : NULL;
|
||||
|
||||
if (ip4_config && (addr4 = nm_ip4_config_get_first_address(ip4_config))) {
|
||||
g_clear_object(&priv->lookup.addr);
|
||||
priv->lookup.addr =
|
||||
g_inet_address_new_from_bytes((guint8 *) &addr4->address, G_SOCKET_FAMILY_IPV4);
|
||||
} else if (ip6_config && (addr6 = nm_ip6_config_get_first_address(ip6_config))) {
|
||||
g_clear_object(&priv->lookup.addr);
|
||||
priv->lookup.addr =
|
||||
g_inet_address_new_from_bytes((guint8 *) &addr6->address, G_SOCKET_FAMILY_IPV6);
|
||||
} else {
|
||||
/* No valid IP config; fall back to localhost.localdomain */
|
||||
_set_hostname(self, NULL, "no IP config");
|
||||
return;
|
||||
}
|
||||
|
||||
lookup_by_address(self);
|
||||
_set_hostname(self, NULL, "no hostname found");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1796,6 +1948,8 @@ device_state_changed(NMDevice * device,
|
|||
|
||||
switch (new_state) {
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
/* Mark the connection invalid if it failed during activation so that
|
||||
* it doesn't get automatically chosen over and over and over again.
|
||||
*/
|
||||
|
@ -1934,6 +2088,8 @@ device_state_changed(NMDevice * device,
|
|||
ip6_remove_device_prefix_delegations(self, device);
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
||||
/* Reset retry counts for a device's connections when carrier on; if cable
|
||||
* was unplugged and plugged in again, we should try to reconnect.
|
||||
*/
|
||||
|
|
|
@ -2546,6 +2546,42 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea
|
|||
return NM_SETTING(g_steal_pointer(&s_ip6));
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_hostname_setting(shvarFile *ifcfg)
|
||||
{
|
||||
NMSetting *setting;
|
||||
NMTernary from_dhcp;
|
||||
NMTernary from_dns_lookup;
|
||||
NMTernary only_from_default;
|
||||
int priority;
|
||||
|
||||
priority = svGetValueInt64(ifcfg, "HOSTNAME_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
|
||||
|
||||
from_dhcp = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DHCP");
|
||||
from_dns_lookup = svGetValueTernary(ifcfg, "HOSTNAME_FROM_DNS_LOOKUP");
|
||||
only_from_default = svGetValueTernary(ifcfg, "HOSTNAME_ONLY_FROM_DEFAULT");
|
||||
|
||||
/* Create the setting when at least one key is not default*/
|
||||
if (priority == 0 && from_dhcp == NM_TERNARY_DEFAULT && from_dns_lookup == NM_TERNARY_DEFAULT
|
||||
&& only_from_default == NM_TERNARY_DEFAULT)
|
||||
return NULL;
|
||||
|
||||
setting = nm_setting_hostname_new();
|
||||
|
||||
g_object_set(setting,
|
||||
NM_SETTING_HOSTNAME_PRIORITY,
|
||||
priority,
|
||||
NM_SETTING_HOSTNAME_FROM_DHCP,
|
||||
from_dhcp,
|
||||
NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
|
||||
from_dns_lookup,
|
||||
NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT,
|
||||
only_from_default,
|
||||
NULL);
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_sriov_setting(shvarFile *ifcfg)
|
||||
{
|
||||
|
@ -2951,7 +2987,8 @@ make_dcb_setting(shvarFile *ifcfg, NMSetting **out_setting, GError **error)
|
|||
gboolean dcb_on;
|
||||
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
||||
|
||||
g_return_val_if_fail(out_setting != NULL, FALSE);
|
||||
g_return_val_if_fail(out_setting, FALSE);
|
||||
*out_setting = NULL;
|
||||
|
||||
dcb_on = !!svGetValueBoolean(ifcfg, "DCB", FALSE);
|
||||
if (!dcb_on)
|
||||
|
@ -6243,8 +6280,9 @@ connection_from_file_full(const char *filename,
|
|||
gs_unref_object NMConnection *connection = NULL;
|
||||
gs_free char * type = NULL;
|
||||
char * devtype, *bootproto;
|
||||
NMSetting * s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user;
|
||||
NMSetting * s_sriov, *s_match;
|
||||
NMSetting * setting;
|
||||
NMSetting * s_ip4;
|
||||
NMSetting * s_ip6;
|
||||
const char * ifcfg_name = NULL;
|
||||
gboolean has_ip4_defroute = FALSE;
|
||||
gboolean has_complex_routes_v4;
|
||||
|
@ -6532,13 +6570,13 @@ connection_from_file_full(const char *filename,
|
|||
NM_SETTING_IP_CONFIG(s_ip4),
|
||||
NM_SETTING_IP_CONFIG(s_ip6));
|
||||
|
||||
s_sriov = make_sriov_setting(main_ifcfg);
|
||||
if (s_sriov)
|
||||
nm_connection_add_setting(connection, s_sriov);
|
||||
setting = make_sriov_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
s_tc = make_tc_setting(main_ifcfg);
|
||||
if (s_tc)
|
||||
nm_connection_add_setting(connection, s_tc);
|
||||
setting = make_tc_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
/* For backwards compatibility, if IPv4 is disabled or the
|
||||
* config fails for some reason, we read DOMAIN and put the
|
||||
|
@ -6546,30 +6584,34 @@ connection_from_file_full(const char *filename,
|
|||
*/
|
||||
check_dns_search_domains(main_ifcfg, s_ip4, s_ip6);
|
||||
|
||||
s_proxy = make_proxy_setting(main_ifcfg);
|
||||
if (s_proxy)
|
||||
nm_connection_add_setting(connection, s_proxy);
|
||||
setting = make_proxy_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
s_user = make_user_setting(main_ifcfg);
|
||||
if (s_user)
|
||||
nm_connection_add_setting(connection, s_user);
|
||||
setting = make_hostname_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
s_match = make_match_setting(main_ifcfg);
|
||||
if (s_match)
|
||||
nm_connection_add_setting(connection, s_match);
|
||||
setting = make_user_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
s_port = make_bridge_port_setting(main_ifcfg);
|
||||
if (s_port)
|
||||
nm_connection_add_setting(connection, s_port);
|
||||
setting = make_match_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
s_port = make_team_port_setting(main_ifcfg);
|
||||
if (s_port)
|
||||
nm_connection_add_setting(connection, s_port);
|
||||
setting = make_bridge_port_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
if (!make_dcb_setting(main_ifcfg, &s_dcb, error))
|
||||
setting = make_team_port_setting(main_ifcfg);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
if (!make_dcb_setting(main_ifcfg, &setting, error))
|
||||
return NULL;
|
||||
if (s_dcb)
|
||||
nm_connection_add_setting(connection, s_dcb);
|
||||
if (setting)
|
||||
nm_connection_add_setting(connection, setting);
|
||||
|
||||
if (!nm_connection_normalize(connection, NULL, NULL, error))
|
||||
return NULL;
|
||||
|
|
|
@ -873,6 +873,10 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
|
|||
_KEY_TYPE("GATEWAY_PING_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("GENERATE_MAC_ADDRESS_MASK", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("GVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HOSTNAME_FROM_DHCP", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HOSTNAME_FROM_DNS_LOOKUP", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HOSTNAME_ONLY_FROM_DEFAULT", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HOSTNAME_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HWADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("HWADDR_BLACKLIST", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
_KEY_TYPE("IEEE_8021X_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct {
|
|||
NMSIfcfgKeyTypeFlags key_flags;
|
||||
} NMSIfcfgKeyTypeInfo;
|
||||
|
||||
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[243];
|
||||
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[247];
|
||||
|
||||
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx);
|
||||
|
||||
|
|
|
@ -1051,6 +1051,28 @@ write_infiniband_setting(NMConnection *connection, shvarFile *ifcfg, GError **er
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_hostname_setting(NMConnection *connection, shvarFile *ifcfg)
|
||||
{
|
||||
NMSettingHostname *s_hostname;
|
||||
NMTernary t;
|
||||
|
||||
s_hostname = _nm_connection_get_setting(connection, NM_TYPE_SETTING_HOSTNAME);
|
||||
if (!s_hostname)
|
||||
return;
|
||||
|
||||
svSetValueInt64(ifcfg, "HOSTNAME_PRIORITY", nm_setting_hostname_get_priority(s_hostname));
|
||||
|
||||
t = nm_setting_hostname_get_from_dhcp(s_hostname);
|
||||
svSetValueInt64_cond(ifcfg, "HOSTNAME_FROM_DHCP", t != NM_TERNARY_DEFAULT, t);
|
||||
|
||||
t = nm_setting_hostname_get_from_dns_lookup(s_hostname);
|
||||
svSetValueInt64_cond(ifcfg, "HOSTNAME_FROM_DNS_LOOKUP", t != NM_TERNARY_DEFAULT, t);
|
||||
|
||||
t = nm_setting_hostname_get_only_from_default(s_hostname);
|
||||
svSetValueInt64_cond(ifcfg, "HOSTNAME_ONLY_FROM_DEFAULT", t != NM_TERNARY_DEFAULT, t);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_wired_setting(NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||
{
|
||||
|
@ -3347,7 +3369,7 @@ do_write_construct(NMConnection * connection,
|
|||
return FALSE;
|
||||
|
||||
write_match_setting(connection, ifcfg);
|
||||
|
||||
write_hostname_setting(connection, ifcfg);
|
||||
write_sriov_setting(connection, ifcfg);
|
||||
|
||||
if (!write_tc_setting(connection, ifcfg, error))
|
||||
|
|
Loading…
Reference in a new issue