core: refactor nm_utils_ipv6_addr_set_stable_privacy() to not fail

It's great to have functions that cannot fail, because it allows to
skip any error handling.

_set_stable_privacy() as it was could not fail, so the only reason why
nm_utils_ipv6_addr_set_stable_privacy() could fail is because the DAD
counter exhausted.

Also, it will be useful to have a function that does not do the counter
check, where the caller wants to handle that differently.

Rename some functions, and make the core nm_utils_ipv6_addr_set_stable_privacy()
not failable.
This commit is contained in:
Thomas Haller 2021-08-25 15:13:36 +02:00
parent 4b6e119010
commit 5a4124f738
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
5 changed files with 103 additions and 114 deletions

View file

@ -10333,12 +10333,12 @@ check_and_add_ipv6ll_addr(NMDevice *self)
const char * stable_id;
stable_id = _prop_get_connection_stable_id(self, connection, &stable_type);
if (!nm_utils_ipv6_addr_set_stable_privacy(stable_type,
&lladdr,
nm_device_get_iface(self),
stable_id,
priv->linklocal6_dad_counter++,
&error)) {
if (!nm_utils_ipv6_addr_set_stable_privacy_may_fail(stable_type,
&lladdr,
nm_device_get_iface(self),
stable_id,
priv->linklocal6_dad_counter++,
&error)) {
_LOGW(LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
g_clear_error(&error);
linklocal6_failed(self);

View file

@ -476,12 +476,12 @@ complete_address(NMNDisc *ndisc, NMNDiscAddress *addr)
priv = NM_NDISC_GET_PRIVATE(ndisc);
if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
if (!nm_utils_ipv6_addr_set_stable_privacy(priv->stable_type,
&addr->address,
priv->ifname,
priv->network_id,
addr->dad_counter++,
&error)) {
if (!nm_utils_ipv6_addr_set_stable_privacy_may_fail(priv->stable_type,
&addr->address,
priv->ifname,
priv->network_id,
addr->dad_counter++,
&error)) {
_LOGW("complete-address: failed to generate an stable-privacy address: %s",
error->message);
g_clear_error(&error);

View file

@ -3426,15 +3426,14 @@ _is_reserved_ipv6_iid(const guint8 *iid)
return FALSE;
}
static gboolean
_set_stable_privacy(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
const guint8 * host_id,
gsize host_id_len,
GError ** error)
void
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
const guint8 * host_id,
gsize host_id_len)
{
nm_auto_free_checksum GChecksum *sum = NULL;
guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA256];
@ -3483,30 +3482,29 @@ _set_stable_privacy(NMUtilsStableType stable_type,
}
memcpy(addr->s6_addr + 8, &digest[0], 8);
return TRUE;
}
gboolean
nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
guint8 * host_id,
gsize host_id_len,
GError ** error)
void
nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter)
{
return _set_stable_privacy(stable_type,
addr,
ifname,
network_id,
dad_counter,
host_id,
host_id_len,
error);
const guint8 *host_id;
gsize host_id_len;
nm_utils_host_id_get(&host_id, &host_id_len);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(stable_type,
addr,
ifname,
network_id,
dad_counter,
host_id,
host_id_len);
}
#define RFC7217_IDGEN_RETRIES 3
/**
* nm_utils_ipv6_addr_set_stable_privacy:
*
@ -3516,19 +3514,16 @@ nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type,
* Returns: %TRUE on success, %FALSE if the address could not be generated.
*/
gboolean
nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
GError ** error)
nm_utils_ipv6_addr_set_stable_privacy_may_fail(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
GError ** error)
{
const guint8 *host_id;
gsize host_id_len;
g_return_val_if_fail(network_id, FALSE);
if (dad_counter >= RFC7217_IDGEN_RETRIES) {
if (dad_counter >= NM_STABLE_PRIVACY_RFC7217_IDGEN_RETRIES) {
g_set_error_literal(error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
@ -3536,16 +3531,8 @@ nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type,
return FALSE;
}
nm_utils_host_id_get(&host_id, &host_id_len);
return _set_stable_privacy(stable_type,
addr,
ifname,
network_id,
dad_counter,
host_id,
host_id_len,
error);
nm_utils_ipv6_addr_set_stable_privacy(stable_type, addr, ifname, network_id, dad_counter);
return TRUE;
}
/*****************************************************************************/

View file

@ -281,21 +281,28 @@ NMUtilsStableType nm_utils_stable_id_parse(const char *stable_id,
char *nm_utils_stable_id_random(void);
char *nm_utils_stable_id_generated_complete(const char *msg);
gboolean nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
guint8 * host_id,
gsize host_id_len,
GError ** error);
#define NM_STABLE_PRIVACY_RFC7217_IDGEN_RETRIES 3
gboolean nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType id_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
GError ** error);
void nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
const guint8 * host_id,
gsize host_id_len);
void nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter);
gboolean nm_utils_ipv6_addr_set_stable_privacy_may_fail(NMUtilsStableType stable_type,
struct in6_addr * addr,
const char * ifname,
const char * network_id,
guint32 dad_counter,
GError ** error);
char *nm_utils_hw_addr_gen_random_eth(const char *current_mac_address,
const char *generate_mac_address_mask);

View file

@ -16,60 +16,55 @@ test_stable_privacy(void)
struct in6_addr addr1;
inet_pton(AF_INET6, "1234::", &addr1);
nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"6b138152-9f3e-4b97-aaf7-e6e553f2a24e",
0,
(guint8 *) "key",
3,
NULL);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"6b138152-9f3e-4b97-aaf7-e6e553f2a24e",
0,
(guint8 *) "key",
3);
nmtst_assert_ip6_address(&addr1, "1234::4ceb:14cd:3d54:793f");
/* We get an address without the UUID. */
inet_pton(AF_INET6, "1::", &addr1);
nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"",
384,
(guint8 *) "key",
3,
NULL);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"",
384,
(guint8 *) "key",
3);
nmtst_assert_ip6_address(&addr1, "1::11aa:2530:9144:dafa");
/* We get a different address in a different network. */
inet_pton(AF_INET6, "2::", &addr1);
nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"",
384,
(guint8 *) "key",
3,
NULL);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID,
&addr1,
"eth666",
"",
384,
(guint8 *) "key",
3);
nmtst_assert_ip6_address(&addr1, "2::338e:8d:c11:8726");
inet_pton(AF_INET6, "1234::", &addr1);
nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_STABLE_ID,
&addr1,
"eth666",
"6b138152-9f3e-4b97-aaf7-e6e553f2a24e",
0,
(guint8 *) "key",
3,
NULL);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_STABLE_ID,
&addr1,
"eth666",
"6b138152-9f3e-4b97-aaf7-e6e553f2a24e",
0,
(guint8 *) "key",
3);
nmtst_assert_ip6_address(&addr1, "1234::ad4c:ae44:3d30:af1e");
inet_pton(AF_INET6, "1234::", &addr1);
nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_STABLE_ID,
&addr1,
"eth666",
"stable-id-1",
0,
(guint8 *) "key",
3,
NULL);
nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_STABLE_ID,
&addr1,
"eth666",
"stable-id-1",
0,
(guint8 *) "key",
3);
nmtst_assert_ip6_address(&addr1, "1234::4944:67b0:7a6c:1cf");
}