Commit 7a0b6b17 authored by Francesco Giudici's avatar Francesco Giudici

libnm-core: add ipv6.dhcp-duid property

allow to specify the DUID to be used int the DHCPv6 client identifier
option: the dhcp-duid property accepts either a hex string or the
special values "lease", "llt", "ll", "stable-llt", "stable-ll" and
"stable-uuid".

"lease": give priority to the DUID available in the lease file if any,
         otherwise fallback to a global default dependant on the dhcp
         client used. This is the default and reflects how the DUID
         was managed previously.
"ll": enforce generation and use of LL type DUID based on the current
      hardware address.
"llt": enforce generation and use of LLT type DUID based on the current
       hardware address and a stable time field.
"stable-ll": enforce generation and use of LL type DUID based on a
             link layer address derived from the stable id.
"stable-llt": enforce generation and use of LLT type DUID based on
              a link layer address and a timestamp both derived from the
              stable id.
"stable-uuid": enforce generation and use of a UUID type DUID based on a
               uuid generated from the stable id.
parent fcc6bf71
This diff is collapsed.
......@@ -508,4 +508,7 @@ _nm_connection_type_is_master (const char *type)
/*****************************************************************************/
gboolean _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin);
/*****************************************************************************/
#endif
......@@ -1544,7 +1544,8 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
* with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the
* generated cloned MAC address for ethernet.cloned-mac-address=stable
* and wifi.cloned-mac-address=stable. It is also used as DHCP client
* identifier with ipv4.dhcp-client-id=stable.
* identifier with ipv4.dhcp-client-id=stable and to derive the DHCP
* DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid].
*
* Note that depending on the context where it is used, other parameters are
* also seeded into the generation algorithm. For example, a per-host key
......
......@@ -28,6 +28,7 @@
#include "nm-setting-private.h"
#include "nm-core-enum-types.h"
#include "nm-core-internal.h"
/**
* SECTION:nm-setting-ip6-config
......@@ -61,6 +62,7 @@ typedef struct {
NMSettingIP6ConfigPrivacy ip6_privacy;
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
char *token;
char *dhcp_duid;
} NMSettingIP6ConfigPrivate;
enum {
......@@ -68,6 +70,7 @@ enum {
PROP_IP6_PRIVACY,
PROP_ADDR_GEN_MODE,
PROP_TOKEN,
PROP_DHCP_DUID,
LAST_PROP
};
......@@ -141,6 +144,26 @@ nm_setting_ip6_config_get_token (NMSettingIP6Config *setting)
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->token;
}
/**
* nm_setting_ip6_config_get_dhcp_duid:
* @setting: the #NMSettingIP6Config
*
* Returns the value contained in the #NMSettingIP6Config:dhcp-duid
* property.
*
* Returns: The configured DUID value to be included in the DHCPv6 requests
* sent to the DHCPv6 servers.
*
* Since: 1.12
**/
const char *
nm_setting_ip6_config_get_dhcp_duid (NMSettingIP6Config *setting)
{
g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL);
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dhcp_duid;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
......@@ -254,6 +277,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (priv->dhcp_duid) {
if (!_nm_utils_dhcp_duid_valid (priv->dhcp_duid, NULL)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("invalid DUID"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_DHCP_DUID);
return FALSE;
}
}
/* Failures from here on, are NORMALIZABLE_ERROR... */
if (token_needs_normalization) {
......@@ -467,6 +501,10 @@ set_property (GObject *object, guint prop_id,
g_free (priv->token);
priv->token = g_value_dup_string (value);
break;
case PROP_DHCP_DUID:
g_free (priv->dhcp_duid);
priv->dhcp_duid = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -489,6 +527,9 @@ get_property (GObject *object, guint prop_id,
case PROP_TOKEN:
g_value_set_string (value, priv->token);
break;
case PROP_DHCP_DUID:
g_value_set_string (value, priv->dhcp_duid);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -502,6 +543,7 @@ finalize (GObject *object)
NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (self);
g_free (priv->token);
g_free (priv->dhcp_duid);
G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object);
}
......@@ -790,6 +832,47 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingIP6Config:dhcp-duid:
*
* A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp
* client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried
* in the Client Identifier option.
* If the property is a hex string ('aa:bb:cc') it is interpreted as a binary
* DUID and filled as an opaque value in the Client Identifier option.
*
* The special value "lease" will retrieve the DUID previously used from the
* lease file belonging to the connection. If no DUID is found and "dhclient"
* is the configured dhcp client, the DUID is searched in the system-wide
* dhclient lease file. If still no DUID is found, or another dhcp client is
* used, a global and permanent DUID-UUID (RFC 6355) will be generated based
* on the machine-id.
*
* The special values "llt" and "ll" will generate a DUID of type LLT or LL
* (see RFC 3315) based on the current MAC address of the device. In order to
* try providing a stable DUID-LLT, the time field will contain a constant
* timestamp that is used globally (for all profiles) and persisted to disk.
*
* The special values "stable-llt", "stable-ll" and "stable-uuid" will generate
* a DUID of the corresponding type, derived from the connection's stable-id and
* a per-host unique key.
* So, the link-layer address of "stable-ll" and "stable-llt" will be a generated
* address derived from the stable id. The DUID-LLT time value in the "stable-llt"
* option will be picked among a static timespan of three years (the upper bound
* of the interval is the same constant timestamp used in "llt").
*
* When the property is unset, the global value provided for "ipv6.dhcp-duid" is
* used. If no global value is provided, the default "lease" value is assumed.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_DHCP_DUID,
g_param_spec_string (NM_SETTING_IP6_CONFIG_DHCP_DUID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/* IP6-specific property overrides */
/* ---dbus---
......
......@@ -45,6 +45,8 @@ G_BEGIN_DECLS
#define NM_SETTING_IP6_CONFIG_TOKEN "token"
#define NM_SETTING_IP6_CONFIG_DHCP_DUID "dhcp-duid"
/**
* NM_SETTING_IP6_CONFIG_METHOD_IGNORE:
*
......@@ -162,6 +164,8 @@ NM_AVAILABLE_IN_1_2
NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting);
NM_AVAILABLE_IN_1_4
const char *nm_setting_ip6_config_get_token (NMSettingIP6Config *setting);
NM_AVAILABLE_IN_1_12
const char *nm_setting_ip6_config_get_dhcp_duid (NMSettingIP6Config *setting);
G_END_DECLS
......
......@@ -4436,6 +4436,52 @@ _nm_utils_inet6_is_token (const struct in6_addr *in6addr)
return FALSE;
}
/**
* _nm_utils_dhcp_duid_valid:
* @duid: the candidate DUID
*
* Checks if @duid string contains either a special duid value ("ll",
* "llt", "lease" or the "stable" variants) or a valid hex DUID.
*
* Return value: %TRUE or %FALSE
*/
gboolean
_nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin)
{
gsize duid_len;
gs_unref_bytes GBytes *duid_bin = NULL;
if (out_duid_bin)
*out_duid_bin = NULL;
if (!duid)
return FALSE;
if (NM_IN_STRSET (duid, "lease",
"llt",
"ll",
"stable-llt",
"stable-ll",
"stable-uuid")) {
return TRUE;
}
duid_bin = nm_utils_hexstr2bin (duid);
if (!duid_bin)
return FALSE;
duid_len = g_bytes_get_size (duid_bin);
/* MAX DUID lenght is 128 octects + the type code (2 octects). */
if ( duid_len <= 2
|| duid_len > (128 + 2))
return FALSE;
if (out_duid_bin)
*out_duid_bin = g_steal_pointer (&duid_bin);
return TRUE;
}
/**
* nm_utils_check_virtual_device_compatibility:
* @virtual_type: a virtual connection type
......
......@@ -1355,6 +1355,7 @@ global:
nm_setting_connection_get_mdns;
nm_setting_connection_mdns_get_type;
nm_setting_ip_tunnel_get_flags;
nm_setting_ip6_config_get_dhcp_duid;
nm_setting_vpn_get_data_keys;
nm_setting_vpn_get_secret_keys;
nm_setting_wireless_security_get_fils;
......
......@@ -704,6 +704,10 @@ ipv6.ip6-privacy=0
removes extraneous routes from the tables.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ipv6.dhcp-duid</varname></term>
<listitem><para>If left unspecified, it defaults to "lease".</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ipv6.dhcp-timeout</varname></term>
<listitem><para>If left unspecified, the default value for
......
......@@ -37,8 +37,11 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_sched.h>
#include <uuid/uuid.h>
#include "nm-utils/nm-dedup-multi.h"
#include "nm-utils/nm-random-utils.h"
#include "nm-utils/unaligned.h"
#include "nm-common-macros.h"
#include "nm-device-private.h"
......@@ -7679,12 +7682,203 @@ dhcp6_prefix_delegated (NMDhcpClient *client,
g_signal_emit (self, signals[IP6_PREFIX_DELEGATED], 0, prefix);
}
/* RFC 3315 defines the epoch for the DUID-LLT time field on Jan 1st 2000. */
#define EPOCH_DATETIME_200001010000 946684800
static GBytes *
generate_duid_llt (const guint8 *hwaddr /* ETH_ALEN bytes */,
gint64 time)
{
GByteArray *duid_arr;
const guint16 duid_type = htons (1);
const guint16 hw_type = htons (ARPHRD_ETHER);
const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000));
duid_arr = g_byte_array_sized_new (2 + 4 + 2 + ETH_ALEN);
g_byte_array_append (duid_arr, (const guint8 *) &duid_type, 2);
g_byte_array_append (duid_arr, (const guint8 *) &hw_type, 2);
g_byte_array_append (duid_arr, (const guint8 *) &duid_time, 4);
g_byte_array_append (duid_arr, hwaddr, ETH_ALEN);
return g_byte_array_free_to_bytes (duid_arr);
}
static GBytes *
generate_duid_ll (const guint8 *hwaddr /* ETH_ALEN bytes */)
{
GByteArray *duid_arr;
const guint16 duid_type = htons (3);
const guint16 hw_type = htons (ARPHRD_ETHER);
gs_unref_bytes GBytes *stable_hwaddr = NULL;
duid_arr = g_byte_array_sized_new (2 + 2 + ETH_ALEN);
g_byte_array_append (duid_arr, (const guint8 *) &duid_type, 2);
g_byte_array_append (duid_arr, (const guint8 *) &hw_type, 2);
g_byte_array_append (duid_arr, hwaddr, ETH_ALEN);
return g_byte_array_free_to_bytes (duid_arr);
}
static GBytes *
generate_duid_uuid (guint8 *data, gsize data_len)
{
const guint16 duid_type = g_htons (4);
const int DUID_SIZE = 18;
guint8 *duid_buffer;
nm_assert (data);
nm_assert (data_len >= 16);
/* Generate a DHCP Unique Identifier for DHCPv6 using the
* DUID-UUID method (see RFC 6355 section 4). Format is:
*
* u16: type (DUID-UUID = 4)
* u8[16]: UUID bytes
*/
duid_buffer = g_malloc (DUID_SIZE);
G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2);
memcpy (&duid_buffer[0], &duid_type, 2);
/* UUID is 128 bits, we just take the first 128 bits
* (regardless of data size) as the DUID-UUID.
*/
memcpy (&duid_buffer[2], data, 16);
return g_bytes_new_take (duid_buffer, DUID_SIZE);
}
static GBytes *
dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcpDuidEnforce *out_enforce)
{
NMSettingIPConfig *s_ip6;
const char *duid;
gs_free char *duid_default = NULL;
const char *duid_error = NULL;
GBytes *duid_out = NULL;
guint8 sha256_digest[32];
gsize len = sizeof (sha256_digest);
NM_SET_OUT (out_enforce, NM_DHCP_DUID_ENFORCE_NEVER);
s_ip6 = nm_connection_get_setting_ip6_config (connection);
duid = nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6));
if (!duid) {
duid_default = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"ipv6.dhcp-duid", self);
duid = duid_default;
}
if (!duid || nm_streq (duid, "lease"))
return NULL;
if (!_nm_utils_dhcp_duid_valid (duid, &duid_out))
return NULL;
if (duid_out)
return duid_out;
if (NM_IN_STRSET (duid, "ll", "llt")) {
if (!hwaddr) {
duid_error = "missing link-layer address";
goto end;
}
if (g_bytes_get_size (hwaddr) != ETH_ALEN) {
duid_error = "unsupported link-layer address";
goto end;
}
} else if (NM_IN_STRSET (duid, "stable-llt", "stable-ll", "stable-uuid")) {
NMUtilsStableType stable_type;
const char *stable_id = NULL;
guint32 salted_header;
GChecksum *sum;
const guint8 *secret_key;
gsize secret_key_len;
stable_id = _get_stable_id (self, connection, &stable_type);
if (!stable_id) {
nm_assert_not_reached ();
duid_error = "cannot retrieve the stable id";
goto end;
}
salted_header = htonl (670531087 + stable_type);
nm_utils_secret_key_get (&secret_key, &secret_key_len);
sum = g_checksum_new (G_CHECKSUM_SHA256);
g_checksum_update (sum, (const guchar *) &salted_header, sizeof (salted_header));
g_checksum_update (sum, (const guchar *) stable_id, -1);
g_checksum_update (sum, (const guchar *) secret_key, secret_key_len);
g_checksum_get_digest (sum, sha256_digest, &len);
g_checksum_free (sum);
}
NM_SET_OUT (out_enforce, NM_DHCP_DUID_ENFORCE_ALWAYS);
#define EPOCH_DATETIME_THREE_YEARS (356 * 24 * 3600 * 3)
if (nm_streq0 (duid, "ll")) {
duid_out = generate_duid_ll (g_bytes_get_data (hwaddr, NULL));
} else if (nm_streq0 (duid, "llt")) {
gint64 time;
time = nm_utils_secret_key_get_timestamp ();
if (!time) {
duid_error = "cannot retrieve the secret key timestamp";
goto end;
}
duid_out = generate_duid_llt (g_bytes_get_data (hwaddr, NULL), time);
} else if (nm_streq0 (duid, "stable-ll")) {
duid_out = generate_duid_ll (sha256_digest);
} else if (nm_streq0 (duid, "stable-llt")) {
gint64 time;
/* We want a variable time between the secret_key timestamp and three years
* before. Let's compute the time (in seconds) from 0 to 3 years; then we'll
* subtract it from the secret_key timestamp.
*/
time = nm_utils_secret_key_get_timestamp ();
if (!time) {
duid_error = "cannot retrieve the secret key timestamp";
goto end;
}
/* don't use too old timestamps. They cannot be expressed in DUID-LLT and
* would all be truncated to zero. */
time = NM_MAX (time, EPOCH_DATETIME_200001010000 + EPOCH_DATETIME_THREE_YEARS);
time -= (unaligned_read_be32 (&sha256_digest[ETH_ALEN]) % EPOCH_DATETIME_THREE_YEARS);
duid_out = generate_duid_llt (sha256_digest, time);
} else if (nm_streq0 (duid, "stable-uuid")) {
duid_out = generate_duid_uuid (sha256_digest, len);
}
end:
if (!duid_out) {
if (!duid_error)
duid_error = "generation failed";
_LOGD (LOGD_IP6, "duid-gen (%s): %s. Fallback to 'lease'.", duid, duid_error);
}
return duid_out;
}
static gboolean
dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMSettingIPConfig *s_ip6;
gs_unref_bytes GBytes *hwaddr = NULL;
gs_unref_bytes GBytes *duid = NULL;
NMDhcpDuidEnforce enforce_duid;
const NMPlatformIP6Address *ll_addr = NULL;
g_assert (connection);
......@@ -7705,6 +7899,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
hwaddr = nm_platform_link_get_address_as_bytes (nm_device_get_platform (self),
nm_device_get_ip_ifindex (self));
duid = dhcp6_get_duid (self, connection, hwaddr, &enforce_duid);
priv->dhcp6.client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
nm_device_get_multi_index (self),
nm_device_get_ip_iface (self),
......@@ -7716,6 +7911,8 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
nm_device_get_route_metric (self, AF_INET6),
nm_setting_ip_config_get_dhcp_send_hostname (s_ip6),
nm_setting_ip_config_get_dhcp_hostname (s_ip6),
duid,
enforce_duid,
get_dhcp_timeout (self, AF_INET6),
priv->dhcp_anycast_address,
(priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
......
......@@ -576,6 +576,8 @@ get_duid (NMDhcpClient *self)
gboolean
nm_dhcp_client_start_ip6 (NMDhcpClient *self,
GBytes *client_id,
NMDhcpDuidEnforce enforce_duid,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
const char *hostname,
......@@ -593,10 +595,23 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self,
g_return_val_if_fail (priv->uuid != NULL, FALSE);
nm_assert (!priv->duid);
/* Read the default DUID for this DHCPv6 client from the
* client-specific persistent configuration.
*/
priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self);
switch (enforce_duid) {
case NM_DHCP_DUID_ENFORCE_NEVER:
case NM_DHCP_DUID_ENFORCE_LEASE_FALLBACK:
priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self);
if (priv->duid)
break;
/* fall through */
case NM_DHCP_DUID_ENFORCE_ALWAYS:
if (client_id) {
priv->duid = g_bytes_ref (client_id);
break;
}
/* fall through */
default:
nm_assert_not_reached ();
}
_LOGD ("DUID is '%s'", (str = nm_dhcp_utils_duid_to_string (priv->duid)));
......
......@@ -23,6 +23,7 @@
#include "nm-setting-ip6-config.h"
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
#include "nm-dhcp-utils.h"
#define NM_DHCP_TIMEOUT_DEFAULT ((guint32) 45) /* default DHCP timeout, in seconds */
#define NM_DHCP_TIMEOUT_INFINITY G_MAXINT32
......@@ -149,6 +150,8 @@ gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self,
const char *last_ip4_address);
gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self,
GBytes *client_id,
NMDhcpDuidEnforce enforce_duid,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
const char *hostname,
......
......@@ -164,6 +164,7 @@ client_start (NMDhcpManager *self,
guint32 route_metric,
const struct in6_addr *ipv6_ll_addr,
GBytes *dhcp_client_id,
NMDhcpDuidEnforce enforce_duid,
guint32 timeout,
const char *dhcp_anycast_addr,
const char *hostname,
......@@ -218,7 +219,7 @@ client_start (NMDhcpManager *self,
if (addr_family == AF_INET)
success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address);
else
success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, privacy, needed_prefixes);
success = nm_dhcp_client_start_ip6 (client, dhcp_client_id, enforce_duid, dhcp_anycast_addr, ipv6_ll_addr, hostname, privacy, needed_prefixes);
if (!success) {
remove_client_unref (self, client);
......@@ -280,7 +281,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
return client_start (self, AF_INET, multi_idx, iface, ifindex, hwaddr, uuid,
route_table, route_metric, NULL,
dhcp_client_id, timeout, dhcp_anycast_addr, hostname,
dhcp_client_id, 0, timeout, dhcp_anycast_addr, hostname,
use_fqdn, FALSE, 0, last_ip_address, 0);
}
......@@ -297,6 +298,8 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
GBytes *duid,
NMDhcpDuidEnforce enforce_duid,
guint32 timeout,
const char *dhcp_anycast_addr,
gboolean info_only,
......@@ -314,8 +317,8 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
hostname = dhcp_hostname ?: priv->default_hostname;
}
return client_start (self, AF_INET6, multi_idx, iface, ifindex, hwaddr, uuid,
route_table, route_metric, ll_addr,
NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only,
route_table, route_metric, ll_addr, duid, enforce_duid,
timeout, dhcp_anycast_addr, hostname, TRUE, info_only,
privacy, NULL, needed_prefixes);
}
......
......@@ -72,6 +72,8 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
GBytes *duid,
NMDhcpDuidEnforce enforce_duid,
guint32 timeout,
const char *dhcp_anycast_addr,
gboolean info_only,
......
......@@ -24,6 +24,12 @@
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
typedef enum {
NM_DHCP_DUID_ENFORCE_NEVER = 0,
NM_DHCP_DUID_ENFORCE_LEASE_FALLBACK,
NM_DHCP_DUID_ENFORCE_ALWAYS,
} NMDhcpDuidEnforce;
NMIP4Config *nm_dhcp_utils_ip4_config_from_options (struct _NMDedupMultiIndex *multi_idx,
int ifindex,
const char *iface,
......
......@@ -2896,7 +2896,7 @@ nm_utils_secret_key_get (const guint8 **out_secret_key,
return secret_key->is_good;
}
guint64
gint64
nm_utils_secret_key_get_timestamp (void)
{
struct stat stat_buf;
......
......@@ -285,7 +285,7 @@ gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_u
gboolean nm_utils_secret_key_get (const guint8 **out_secret_key,
gsize *out_key_len);
guint64 nm_utils_secret_key_get_timestamp (void);
gint64 nm_utils_secret_key_get_timestamp (void);
const char *nm_utils_get_boot_id (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment