From e71f7775a7b28957a0f6522135b6386edebd7889 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 15:04:26 +0200 Subject: [PATCH 01/12] platform: fix comparing parent_ifindex in nm_platform_lnk_macsec_cmp() --- src/platform/nm-platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index eedd2d8243..a04c3723fa 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5302,6 +5302,7 @@ nm_platform_lnk_macsec_hash (const NMPlatformLnkMacsec *obj) { guint h = NM_HASH_INIT (226984267u); + h = NM_HASH_COMBINE (h, obj->parent_ifindex); h = NM_HASH_COMBINE (h, obj->sci); h = NM_HASH_COMBINE_UINT64 (h, obj->icv_length); h = NM_HASH_COMBINE_UINT64 (h, obj->cipher_suite); @@ -5321,6 +5322,7 @@ int nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b) { NM_CMP_SELF (a, b); + NM_CMP_FIELD (a, b, parent_ifindex); NM_CMP_FIELD (a, b, sci); NM_CMP_FIELD (a, b, icv_length); NM_CMP_FIELD (a, b, cipher_suite); From bdb8e65434e1556f0022c2f1fc5a1427e36b0976 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 19:59:33 +0200 Subject: [PATCH 02/12] shared: add _nm_align() and _nm_alignof() macros --- shared/nm-utils/nm-macros-internal.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index 6b70693258..352e581365 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -26,11 +26,14 @@ #include #include -#define _nm_packed __attribute__ ((packed)) -#define _nm_unused __attribute__ ((unused)) -#define _nm_pure __attribute__ ((pure)) -#define _nm_const __attribute__ ((const)) -#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#define _nm_packed __attribute__ ((packed)) +#define _nm_unused __attribute__ ((unused)) +#define _nm_pure __attribute__ ((pure)) +#define _nm_const __attribute__ ((const)) +#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#define _nm_align(s) __attribute__ ((aligned (s))) +#define _nm_alignof(type) __alignof (type) +#define _nm_alignas(type) _nm_align (_nm_alignof (type)) /*****************************************************************************/ From acbab884ee80d8816169892340dba995f23b90bc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 19:59:53 +0200 Subject: [PATCH 03/12] shared: add _NM_ENSURE_TYPE() macro --- shared/nm-utils/nm-macros-internal.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index 352e581365..bbdf50be71 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -288,6 +288,18 @@ NM_G_ERROR_MSG (GError *error) ((type *) (obj)) #endif +#if _NM_CC_SUPPORT_GENERIC +/* returns @value, if the type of @value matches @type. + * This requires support for C11 _Generic(). If no support is + * present, this returns @value directly. + * + * It's useful to check the let the compiler ensure that @value is + * of a certain type. */ +#define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value))) +#else +#define _NM_ENSURE_TYPE(type, value) (value) +#endif + /*****************************************************************************/ #define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y)) From 1766bbeab4f6807e4ed1ecd26db8a9947f72cf58 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 14 Oct 2017 13:28:20 +0200 Subject: [PATCH 04/12] test: add gdbus leak to valgrind.suppressions ==28576== 78 (72 direct, 6 indirect) bytes in 1 blocks are definitely lost in loss record 843 of 1,311 ==28576== at 0x4C2EB6B: malloc (vg_replace_malloc.c:299) ==28576== by 0x6FD0A38: g_malloc (gmem.c:94) ==28576== by 0x6FE8575: g_slice_alloc (gslice.c:1025) ==28576== by 0x6FE8A08: g_slice_alloc0 (gslice.c:1051) ==28576== by 0x7010261: g_system_thread_new (gthread-posix.c:1152) ==28576== by 0x6FF283E: g_thread_new_internal (gthread.c:874) ==28576== by 0x6FF28E7: g_thread_new (gthread.c:827) ==28576== by 0x6FCC4A3: g_get_worker_context (gmain.c:5851) ==28576== by 0x681A814: g_task_thread_pool_init (gtask.c:1977) ==28576== by 0x681A814: g_task_get_type (gtask.c:592) ==28576== by 0x685CB50: ensure_required_types (gdbusprivate.c:231) ==28576== by 0x685CB50: _g_dbus_initialize (gdbusprivate.c:1927) ==28576== by 0x6850CA0: g_bus_get_sync (gdbusconnection.c:7267) ==28576== by 0x10B6AC: nmtstc_service_init (nm-test-utils-impl.c:91) ==28576== by 0x10D261: test_setup (test-secret-agent.c:249) ==28576== by 0x6FF118B: test_case_run (gtestutils.c:2160) ==28576== by 0x6FF118B: g_test_run_suite_internal (gtestutils.c:2244) ==28576== by 0x6FF139A: g_test_run_suite_internal (gtestutils.c:2256) ==28576== by 0x6FF139A: g_test_run_suite_internal (gtestutils.c:2256) ==28576== by 0x6FF1571: g_test_run_suite (gtestutils.c:2332) ==28576== by 0x6FF1590: g_test_run (gtestutils.c:1599) ==28576== by 0x10D0EE: main (test-secret-agent.c:654) --- valgrind.suppressions | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/valgrind.suppressions b/valgrind.suppressions index cafde5e8a2..a13212ec34 100644 --- a/valgrind.suppressions +++ b/valgrind.suppressions @@ -455,9 +455,7 @@ fun:g_task_thread_pool_init fun:g_task_get_type fun:ensure_required_types - fun:_g_dbus_shared_thread_ref - fun:_g_dbus_worker_new - fun:initable_init + ... fun:g_bus_get_sync } { From 281d2d9fade7f20d1162b93a73e2419659881fa5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 14 Oct 2017 13:28:20 +0200 Subject: [PATCH 05/12] shared: split random and hash utils "nm-utils/nm-shared-utils.h" shall contain utility function without other dependencies. It is intended to be used by other projects as-is. nm_utils_random_bytes() requires getrandom() and a HAVE_GETRANDOM configure check. That makes it more cumbersome to re-use "nm-shared-utils.h", in cases where you don't care about nm_utils_random_bytes(). Split nm_utils_random_bytes() out to a separate file. Same for hash utils, which depend on nm_utils_random_bytes(). Also, hash utils will eventually be extended to use siphash24. --- Makefile.am | 4 + libnm-core/nm-utils.c | 1 + shared/nm-utils/nm-dedup-multi.c | 2 + shared/nm-utils/nm-hash-utils.c | 50 +++++++++ shared/nm-utils/nm-hash-utils.h | 47 +++++++++ shared/nm-utils/nm-random-utils.c | 165 ++++++++++++++++++++++++++++++ shared/nm-utils/nm-random-utils.h | 27 +++++ shared/nm-utils/nm-shared-utils.c | 160 ----------------------------- shared/nm-utils/nm-shared-utils.h | 28 ----- src/dhcp/nm-dhcp-client.c | 1 + src/nm-core-utils.c | 1 + src/nm-core-utils.h | 2 + 12 files changed, 300 insertions(+), 188 deletions(-) create mode 100644 shared/nm-utils/nm-hash-utils.c create mode 100644 shared/nm-utils/nm-hash-utils.h create mode 100644 shared/nm-utils/nm-random-utils.c create mode 100644 shared/nm-utils/nm-random-utils.h diff --git a/Makefile.am b/Makefile.am index 06cceb344e..12aff3d666 100644 --- a/Makefile.am +++ b/Makefile.am @@ -421,7 +421,9 @@ libnm_core_lib_h_priv = \ shared/nm-utils/c-list-util.h \ shared/nm-utils/nm-dedup-multi.h \ shared/nm-utils/nm-enum-utils.h \ + shared/nm-utils/nm-hash-utils.h \ shared/nm-utils/nm-shared-utils.h \ + shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-udev-utils.h \ shared/nm-meta-setting.h \ libnm-core/crypto.h \ @@ -437,7 +439,9 @@ libnm_core_lib_c_real = \ shared/nm-utils/c-list-util.c \ shared/nm-utils/nm-dedup-multi.c \ shared/nm-utils/nm-enum-utils.c \ + shared/nm-utils/nm-hash-utils.c \ shared/nm-utils/nm-shared-utils.c \ + shared/nm-utils/nm-random-utils.c \ shared/nm-utils/nm-udev-utils.c \ shared/nm-meta-setting.c \ libnm-core/crypto.c \ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 5b8af9b205..9a79ba47c0 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -38,6 +38,7 @@ #endif #include "nm-utils/nm-enum-utils.h" +#include "nm-utils/nm-hash-utils.h" #include "nm-common-macros.h" #include "nm-utils-private.h" #include "nm-setting-private.h" diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c index e7616074b0..04eec19436 100644 --- a/shared/nm-utils/nm-dedup-multi.c +++ b/shared/nm-utils/nm-dedup-multi.c @@ -23,6 +23,8 @@ #include "nm-dedup-multi.h" +#include "nm-hash-utils.h" + /*****************************************************************************/ typedef struct { diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c new file mode 100644 index 0000000000..6d9bb7005e --- /dev/null +++ b/shared/nm-utils/nm-hash-utils.c @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-hash-utils.h" + +#include "nm-shared-utils.h" +#include "nm-random-utils.h" + +/*****************************************************************************/ + +guint +NM_HASH_INIT (guint seed) +{ + static volatile guint global_seed = 0; + guint g, s; + + /* we xor @seed with a random @global_seed. This is to make the hashing behavior + * less predictable and harder to exploit collisions. */ + g = global_seed; + if (G_UNLIKELY (g == 0)) { + nm_utils_random_bytes (&s, sizeof (s)); + if (s == 0) + s = 42; + g_atomic_int_compare_and_exchange ((int *) &global_seed, 0, s); + g = global_seed; + nm_assert (g); + } + + return g ^ seed; +} diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h new file mode 100644 index 0000000000..de563b7dfa --- /dev/null +++ b/shared/nm-utils/nm-hash-utils.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2017 Red Hat, Inc. + */ + +#ifndef __NM_HASH_UTILS_H__ +#define __NM_HASH_UTILS_H__ + +guint NM_HASH_INIT (guint seed); + +static inline guint +NM_HASH_COMBINE (guint h, guint val) +{ + /* see g_str_hash() for reasons */ + return (h << 5) + h + val; +} + +static inline guint +NM_HASH_COMBINE_UINT64 (guint h, guint64 val) +{ + return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32))); +} + +static inline guint +NM_HASH_POINTER (gconstpointer ptr) +{ + /* same as g_direct_hash(), but inline. */ + return GPOINTER_TO_UINT (ptr); +} + +#endif /* __NM_HASH_UTILS_H__ */ diff --git a/shared/nm-utils/nm-random-utils.c b/shared/nm-utils/nm-random-utils.c new file mode 100644 index 0000000000..5d9e29da89 --- /dev/null +++ b/shared/nm-utils/nm-random-utils.c @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-random-utils.h" + +#include + +#if USE_SYS_RANDOM_H +#include +#else +#include +#endif + +#include "nm-shared-utils.h" + +/*****************************************************************************/ + +/** + * nm_utils_random_bytes: + * @p: the buffer to fill + * @n: the number of bytes to write to @p. + * + * Uses getrandom() or reads /dev/urandom to fill the buffer + * with random data. If all fails, as last fallback it uses + * GRand to fill the buffer with pseudo random numbers. + * The function always succeeds in writing some random numbers + * to the buffer. The return value of FALSE indicates that the + * obtained bytes are probably not of good randomness. + * + * Returns: whether the written bytes are good. If you + * don't require good randomness, you can ignore the return + * value. + * + * Note that if calling getrandom() fails because there is not enough + * entroy (at early boot), the function will read /dev/urandom. + * Which of course, still has low entropy, and cause kernel to log + * a warning. + */ +gboolean +nm_utils_random_bytes (void *p, size_t n) +{ + int fd; + int r; + gboolean has_high_quality = TRUE; + gboolean urandom_success; + guint8 *buf = p; + gboolean avoid_urandom = FALSE; + + g_return_val_if_fail (p, FALSE); + g_return_val_if_fail (n > 0, FALSE); + +#if HAVE_GETRANDOM + { + static gboolean have_syscall = TRUE; + + if (have_syscall) { + r = getrandom (buf, n, GRND_NONBLOCK); + if (r > 0) { + if ((size_t) r == n) + return TRUE; + + /* no or partial read. There is not enough entropy. + * Fill the rest reading from urandom, and remember that + * some bits are not hight quality. */ + nm_assert (r < n); + buf += r; + n -= r; + has_high_quality = FALSE; + + /* At this point, we don't want to read /dev/urandom, because + * the entropy pool is low (early boot?), and asking for more + * entropy causes kernel messages to be logged. + * + * We use our fallback via GRand. Note that g_rand_new() also + * tries to seed itself with data from /dev/urandom, but since + * we reuse the instance, it shouldn't matter. */ + avoid_urandom = TRUE; + } else { + if (errno == ENOSYS) { + /* no support for getrandom(). We don't know whether + * we urandom will give us good quality. Assume yes. */ + have_syscall = FALSE; + } else { + /* unknown error. We'll read urandom below, but we don't have + * high-quality randomness. */ + has_high_quality = FALSE; + } + } + } + } +#endif + + urandom_success = FALSE; + if (!avoid_urandom) { +fd_open: + fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); + if (fd < 0) { + r = errno; + if (r == EINTR) + goto fd_open; + } else { + r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE); + close (fd); + if (r >= 0) + urandom_success = TRUE; + } + } + + if (!urandom_success) { + static _nm_thread_local GRand *rand = NULL; + gsize i; + int j; + + /* we failed to fill the bytes reading from urandom. + * Fill the bits using GRand pseudo random numbers. + * + * We don't have good quality. + */ + has_high_quality = FALSE; + + if (G_UNLIKELY (!rand)) + rand = g_rand_new (); + + nm_assert (n > 0); + i = 0; + for (;;) { + const union { + guint32 v32; + guint8 v8[4]; + } v = { + .v32 = g_rand_int (rand), + }; + + for (j = 0; j < 4; ) { + buf[i++] = v.v8[j++]; + if (i >= n) + goto done; + } + } +done: + ; + } + + return has_high_quality; +} diff --git a/shared/nm-utils/nm-random-utils.h b/shared/nm-utils/nm-random-utils.h new file mode 100644 index 0000000000..15a118d340 --- /dev/null +++ b/shared/nm-utils/nm-random-utils.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2017 Red Hat, Inc. + */ + +#ifndef __NM_RANDOM_UTILS_H__ +#define __NM_RANDOM_UTILS_H__ + +gboolean nm_utils_random_bytes (void *p, size_t n); + +#endif /* __NM_RANDOM_UTILS_H__ */ diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index ba99ce2f87..cea60edfb0 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -28,12 +28,6 @@ #include #include -#if USE_SYS_RANDOM_H -#include -#else -#include -#endif - /*****************************************************************************/ const void *const _NM_PTRARRAY_EMPTY[1] = { NULL }; @@ -863,29 +857,6 @@ nm_g_object_class_find_property_from_gtype (GType gtype, /*****************************************************************************/ -guint -NM_HASH_INIT (guint seed) -{ - static volatile guint global_seed = 0; - guint g, s; - - /* we xor @seed with a random @global_seed. This is to make the hashing behavior - * less predictable and harder to exploit collisions. */ - g = global_seed; - if (G_UNLIKELY (g == 0)) { - nm_utils_random_bytes (&s, sizeof (s)); - if (s == 0) - s = 42; - g_atomic_int_compare_and_exchange ((int *) &global_seed, 0, s); - g = global_seed; - nm_assert (g); - } - - return g ^ seed; -} - -/*****************************************************************************/ - static void _str_append_escape (GString *s, char ch) { @@ -1118,134 +1089,3 @@ nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll) return 0; } - -/*****************************************************************************/ - -/** - * nm_utils_random_bytes: - * @p: the buffer to fill - * @n: the number of bytes to write to @p. - * - * Uses getrandom() or reads /dev/urandom to fill the buffer - * with random data. If all fails, as last fallback it uses - * GRand to fill the buffer with pseudo random numbers. - * The function always succeeds in writing some random numbers - * to the buffer. The return value of FALSE indicates that the - * obtained bytes are probably not of good randomness. - * - * Returns: whether the written bytes are good. If you - * don't require good randomness, you can ignore the return - * value. - * - * Note that if calling getrandom() fails because there is not enough - * entroy (at early boot), the function will read /dev/urandom. - * Which of course, still has low entropy, and cause kernel to log - * a warning. - */ -gboolean -nm_utils_random_bytes (void *p, size_t n) -{ - int fd; - int r; - gboolean has_high_quality = TRUE; - gboolean urandom_success; - guint8 *buf = p; - gboolean avoid_urandom = FALSE; - - g_return_val_if_fail (p, FALSE); - g_return_val_if_fail (n > 0, FALSE); - -#if HAVE_GETRANDOM - { - static gboolean have_syscall = TRUE; - - if (have_syscall) { - r = getrandom (buf, n, GRND_NONBLOCK); - if (r > 0) { - if ((size_t) r == n) - return TRUE; - - /* no or partial read. There is not enough entropy. - * Fill the rest reading from urandom, and remember that - * some bits are not hight quality. */ - nm_assert (r < n); - buf += r; - n -= r; - has_high_quality = FALSE; - - /* At this point, we don't want to read /dev/urandom, because - * the entropy pool is low (early boot?), and asking for more - * entropy causes kernel messages to be logged. - * - * We use our fallback via GRand. Note that g_rand_new() also - * tries to seed itself with data from /dev/urandom, but since - * we reuse the instance, it shouldn't matter. */ - avoid_urandom = TRUE; - } else { - if (errno == ENOSYS) { - /* no support for getrandom(). We don't know whether - * we urandom will give us good quality. Assume yes. */ - have_syscall = FALSE; - } else { - /* unknown error. We'll read urandom below, but we don't have - * high-quality randomness. */ - has_high_quality = FALSE; - } - } - } - } -#endif - - urandom_success = FALSE; - if (!avoid_urandom) { -fd_open: - fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); - if (fd < 0) { - r = errno; - if (r == EINTR) - goto fd_open; - } else { - r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE); - close (fd); - if (r >= 0) - urandom_success = TRUE; - } - } - - if (!urandom_success) { - static _nm_thread_local GRand *rand = NULL; - gsize i; - int j; - - /* we failed to fill the bytes reading from urandom. - * Fill the bits using GRand pseudo random numbers. - * - * We don't have good quality. - */ - has_high_quality = FALSE; - - if (G_UNLIKELY (!rand)) - rand = g_rand_new (); - - nm_assert (n > 0); - i = 0; - for (;;) { - const union { - guint32 v32; - guint8 v8[4]; - } v = { - .v32 = g_rand_int (rand), - }; - - for (j = 0; j < 4; ) { - buf[i++] = v.v8[j++]; - if (i >= n) - goto done; - } - } -done: - ; - } - - return has_high_quality; -} diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 0f9df73fb3..96aab5341e 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -378,30 +378,6 @@ GParamSpec *nm_g_object_class_find_property_from_gtype (GType gtype, /*****************************************************************************/ -guint NM_HASH_INIT (guint seed); - -static inline guint -NM_HASH_COMBINE (guint h, guint val) -{ - /* see g_str_hash() for reasons */ - return (h << 5) + h + val; -} - -static inline guint -NM_HASH_COMBINE_UINT64 (guint h, guint64 val) -{ - return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32))); -} - -static inline guint -NM_HASH_POINTER (gconstpointer ptr) -{ - /* same as g_direct_hash(), but inline. */ - return GPOINTER_TO_UINT (ptr); -} - -/*****************************************************************************/ - typedef enum { NM_UTILS_STR_UTF8_SAFE_FLAG_NONE = 0, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL = 0x0001, @@ -430,8 +406,4 @@ int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll) /*****************************************************************************/ -gboolean nm_utils_random_bytes (void *p, size_t n); - -/*****************************************************************************/ - #endif /* __NM_SHARED_UTILS_H__ */ diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 59845c8c7a..e8ff9ff292 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -32,6 +32,7 @@ #include #include "nm-utils/nm-dedup-multi.h" +#include "nm-utils/nm-random-utils.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 48a4aa25db..94f71ce3ea 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -36,6 +36,7 @@ #include #include +#include "nm-utils/nm-random-utils.h" #include "nm-utils.h" #include "nm-core-internal.h" #include "nm-setting-connection.h" diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 9d35e2f62d..283bd686fb 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -25,6 +25,8 @@ #include #include +#include "nm-utils/nm-hash-utils.h" + #include "nm-connection.h" /*****************************************************************************/ From 0e9e35e30913ccd01857bb104880976b63404049 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 13 Oct 2017 14:00:22 +0200 Subject: [PATCH 06/12] all: refactor hashing by introducing NMHashState The privious NM_HASH_* macros directly operated on a guint value and were thus close to the actual implementation. Replace them by adding a NMHashState struct and accessors to update the hash state. This hides the implementation better and would allow us to carry more state. For example, we could switch to siphash24() transparently. For now, we still do a form basically djb2 hashing, albeit with differing start seed. Also add nm_hash_str() and nm_str_hash(): - nm_hash_str() is our own string hashing implementation - nm_str_hash() is our own string implementation, but with a GHashFunc signature, suitable to pass it to g_hash_table_new(). Also, it has this name in order to remind you of g_str_hash(), which it is replacing. --- libnm-core/nm-utils.c | 14 +- libnm-core/tests/test-general.c | 62 ++++ shared/nm-utils/nm-dedup-multi.c | 14 +- shared/nm-utils/nm-hash-utils.c | 31 +- shared/nm-utils/nm-hash-utils.h | 105 ++++++- src/devices/nm-device.c | 9 +- src/devices/nm-lldp-listener.c | 13 +- src/nm-core-utils.c | 9 +- src/nm-core-utils.h | 17 +- src/platform/nm-platform.c | 467 ++++++++++++++++--------------- src/platform/nmp-object.c | 173 +++++++----- 11 files changed, 556 insertions(+), 358 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 9a79ba47c0..4ac41944c8 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4007,27 +4007,27 @@ _nm_utils_strstrdictkey_hash (gconstpointer a) { const NMUtilsStrStrDictKey *k = a; const signed char *p; - guint32 h = NM_HASH_INIT (76642997u); + NMHashState h; + nm_hash_init (&h, 76642997u); if (k) { if (((int) k->type) & ~STRSTRDICTKEY_ALL_SET) g_return_val_if_reached (0); - h = NM_HASH_COMBINE (h, k->type); + nm_hash_update_uint (&h, k->type); if (k->type & STRSTRDICTKEY_ALL_SET) { p = (void *) k->data; for (; *p != '\0'; p++) - h = NM_HASH_COMBINE (h, *p); + nm_hash_update_uint (&h, *p); if (k->type == STRSTRDICTKEY_ALL_SET) { /* the key contains two strings. Continue... */ - h = NM_HASH_COMBINE (h, '\0'); + nm_hash_update_uint (&h, '\0'); for (p++; *p != '\0'; p++) - h = NM_HASH_COMBINE (h, *p); + nm_hash_update_uint (&h, *p); } } } - - return h; + return nm_hash_complete (&h); } gboolean diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index b95e307cd7..31a445971e 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -26,6 +26,7 @@ #include #include "nm-utils/c-list-util.h" +#include "nm-utils/nm-hash-utils.h" #include "nm-utils.h" #include "nm-setting-private.h" @@ -78,6 +79,66 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int)); /*****************************************************************************/ +static guint +_test_hash_str (const char *str) +{ + NMHashState h; + guint v, v2; + const guint SEED = 10; + + nm_hash_init (&h, SEED); + nm_hash_update_str (&h, str); + v = nm_hash_complete (&h); + + { + /* assert that hashing a string and a buffer yields the + * same result. + * + * I think that is a desirable property. */ + nm_hash_init (&h, SEED); + nm_hash_update_mem (&h, str, str ? strlen (str) : 0); + v2 = nm_hash_complete (&h); + } + g_assert (v == v2); + return v; +} + +static void +test_nm_hash (void) +{ + NMHashState h; + + _test_hash_str (""); + _test_hash_str ("a"); + _test_hash_str ("aa"); + _test_hash_str ("diceros bicornis longipes"); + + memset (&h, 0, sizeof (h)); + g_assert_cmpint (nm_hash_complete (&h), ==, 1396707757u); + + /* note how two different string still always hash the same, + * although we use a global seed that we initialize each time + * differently. + * + * The aim would be that two collisions depend on the seed value, + * which they currently don't. */ + g_assert_cmpint (nm_hash_str ("BA"), ==, nm_hash_str ("Ab")); + + /* with the current hasing algorighm, once we know two words that hash + * the same, we can trivally find more collions by concatenating + * them (which is bad). */ + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbAbAb")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbAbBA")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbBAAb")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbBABA")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BAAbAb")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BAAbBA")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BABAAb")); + g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BABABA")); +} + +/*****************************************************************************/ + static void test_nm_g_slice_free_fcn (void) { @@ -6341,6 +6402,7 @@ int main (int argc, char **argv) { nmtst_init (&argc, &argv, TRUE); + g_test_add_func ("/core/general/test_nm_hash", test_nm_hash); g_test_add_func ("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn); g_test_add_func ("/core/general/test_c_list_sort", test_c_list_sort); g_test_add_func ("/core/general/test_dedup_multi", test_dedup_multi); diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c index 04eec19436..b1872d4766 100644 --- a/shared/nm-utils/nm-dedup-multi.c +++ b/shared/nm-utils/nm-dedup-multi.c @@ -176,21 +176,21 @@ _dict_idx_entries_hash (const NMDedupMultiEntry *entry) const NMDedupMultiIdxType *idx_type; const NMDedupMultiObj *obj; gboolean lookup_head; - guint h; + NMHashState h; _entry_unpack (entry, &idx_type, &obj, &lookup_head); + nm_hash_init (&h, 1914869417u); if (idx_type->klass->idx_obj_partition_hash) { nm_assert (obj); - h = idx_type->klass->idx_obj_partition_hash (idx_type, obj); - } else - h = NM_HASH_INIT (1914869417u); + nm_hash_update_uint (&h, idx_type->klass->idx_obj_partition_hash (idx_type, obj)); + } if (!lookup_head) - h = NM_HASH_COMBINE (h, idx_type->klass->idx_obj_id_hash (idx_type, obj)); + nm_hash_update_uint (&h, idx_type->klass->idx_obj_id_hash (idx_type, obj)); - h = NM_HASH_COMBINE (h, GPOINTER_TO_UINT (idx_type)); - return h; + nm_hash_update_ptr (&h, idx_type); + return nm_hash_complete (&h); } static gboolean diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c index 6d9bb7005e..4a450218e7 100644 --- a/shared/nm-utils/nm-hash-utils.c +++ b/shared/nm-utils/nm-hash-utils.c @@ -28,12 +28,14 @@ /*****************************************************************************/ -guint -NM_HASH_INIT (guint seed) +void +nm_hash_init (NMHashState *state, guint static_seed) { static volatile guint global_seed = 0; guint g, s; + nm_assert (state); + /* we xor @seed with a random @global_seed. This is to make the hashing behavior * less predictable and harder to exploit collisions. */ g = global_seed; @@ -46,5 +48,28 @@ NM_HASH_INIT (guint seed) nm_assert (g); } - return g ^ seed; + s = g ^ static_seed; + state->hash = s; +} + +guint +nm_hash_str (const char *str) +{ + NMHashState h; + + nm_hash_init (&h, 1867854211u); + nm_hash_update_str (&h, str); + return nm_hash_complete (&h); +} + +guint +nm_str_hash (gconstpointer str) +{ + return nm_hash_str (str); +} + +guint +nm_direct_hash (gconstpointer ptr) +{ + return nm_hash_ptr (ptr); } diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index de563b7dfa..55a832ef14 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -22,26 +22,107 @@ #ifndef __NM_HASH_UTILS_H__ #define __NM_HASH_UTILS_H__ -guint NM_HASH_INIT (guint seed); +#include + +typedef struct { + guint hash; +} NMHashState; + +void nm_hash_init (NMHashState *state, guint static_seed); static inline guint -NM_HASH_COMBINE (guint h, guint val) +nm_hash_complete (NMHashState *state) { - /* see g_str_hash() for reasons */ - return (h << 5) + h + val; + nm_assert (state); + /* we don't ever want to return a zero hash. + * + * NMPObject requires that in _idx_obj_part(), and it's just a good idea. */ + return state->hash ?: 1396707757u; +} + +static inline void +nm_hash_update_uint (NMHashState *state, guint val) +{ + guint h; + + nm_assert (state); + + h = state->hash; + h = (h << 5) + h + val; + state->hash = h; +} + +static inline void +nm_hash_update_uint64 (NMHashState *state, guint64 val) +{ + guint h; + + nm_assert (state); + + h = state->hash; + h = (h << 5) + h + ((guint) val); + h = (h << 5) + h + ((guint) (val >> 32)); + state->hash = h; +} + +static inline void +nm_hash_update_ptr (NMHashState *state, gconstpointer ptr) +{ + if (sizeof (ptr) <= sizeof (guint)) + nm_hash_update_uint (state, ((guint) ((uintptr_t) ptr))); + else + nm_hash_update_uint64 (state, (guint64) ((uintptr_t) ptr)); +} + +static inline void +nm_hash_update_mem (NMHashState *state, const void *ptr, gsize n) +{ + gsize i; + guint h; + + nm_assert (state); + + /* use the same hash seed as nm_hash_update_str(). + * That way, nm_hash_update_str(&h, s) is identical to + * nm_hash_update_mem(&h, s, strlen(s)). */ + h = state->hash; + for (i = 0; i < n; i++) + h = (h << 5) + h + ((guint) ((const guint8 *) ptr)[i]); + h = (h << 5) + h + 1774132687u; + state->hash = h; +} + +static inline void +nm_hash_update_str (NMHashState *state, const char *str) +{ + const guint8 *p = (const guint8 *) str; + guint8 c; + guint h; + + nm_assert (state); + + /* Note that NULL hashes differently from "". */ + h = state->hash; + if (str) { + while ((c = *p++)) + h = (h << 5) + h + ((guint) c); + h = (h << 5) + h + 1774132687u; + } else + h = (h << 5) + h + 2967906233u; + state->hash = h; } static inline guint -NM_HASH_COMBINE_UINT64 (guint h, guint64 val) +nm_hash_ptr (gconstpointer ptr) { - return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32))); + if (sizeof (ptr) <= sizeof (guint)) + return (guint) ((uintptr_t) ptr); + else + return ((guint) (((uintptr_t) ptr) >> 32)) ^ ((guint) ((uintptr_t) ptr)); } +guint nm_direct_hash (gconstpointer str); -static inline guint -NM_HASH_POINTER (gconstpointer ptr) -{ - /* same as g_direct_hash(), but inline. */ - return GPOINTER_TO_UINT (ptr); -} +guint nm_hash_str (const char *str); +guint nm_str_hash (gconstpointer str); #endif /* __NM_HASH_UTILS_H__ */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index c8ec439e5a..cbb806861f 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2858,11 +2858,12 @@ typedef struct { static guint _v4_has_shadowed_routes_detect_hash (const IP4RPFilterData *d) { - guint h = NM_HASH_INIT (1105201169u); + NMHashState h; - h = NM_HASH_COMBINE (h, d->network); - h = NM_HASH_COMBINE (h, d->plen); - return h; + nm_hash_init (&h, 1105201169u); + nm_hash_update_uint (&h, d->network); + nm_hash_update_uint (&h, d->plen); + return nm_hash_complete (&h); } static gboolean diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index 28e7fd6c77..3cf6a209ec 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -274,13 +274,14 @@ static guint lldp_neighbor_id_hash (gconstpointer ptr) { const LldpNeighbor *neigh = ptr; - guint hash = NM_HASH_INIT (23423423u); + NMHashState h; - hash = NM_HASH_COMBINE (hash, neigh->chassis_id ? g_str_hash (neigh->chassis_id) : 12321u); - hash = NM_HASH_COMBINE (hash, neigh->port_id ? g_str_hash (neigh->port_id) : 34342343u); - hash = NM_HASH_COMBINE (hash, neigh->chassis_id_type); - hash = NM_HASH_COMBINE (hash, neigh->port_id_type); - return hash; + nm_hash_init (&h, 23423423u); + nm_hash_update_str (&h, neigh->chassis_id); + nm_hash_update_str (&h, neigh->port_id); + nm_hash_update_uint (&h, neigh->chassis_id_type); + nm_hash_update_uint (&h, neigh->port_id_type); + return nm_hash_complete (&h); } static int diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 94f71ce3ea..04a382ae48 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -189,12 +189,11 @@ nm_utils_exp10 (gint16 ex) guint nm_utils_in6_addr_hash (const struct in6_addr *addr) { - guint hash = NM_HASH_INIT (3675559913u); - int i; + NMHashState h; - for (i = 0; i < sizeof (*addr); i++) - hash = NM_HASH_COMBINE (hash, ((const guint8 *) addr)[i]); - return hash; + nm_hash_init (&h, 3675559913u); + nm_hash_update_in6addr (&h, addr); + return nm_hash_complete (&h); } /*****************************************************************************/ diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 283bd686fb..097cac5fd3 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -128,24 +128,23 @@ nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in #define NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(a, b, plen) \ NM_CMP_RETURN (nm_utils_ip6_address_same_prefix_cmp ((a), (b), (plen))) -static inline guint -NM_HASH_COMBINE_IN6ADDR (guint h, const struct in6_addr *addr) +static inline void +nm_hash_update_in6addr (NMHashState *h, const struct in6_addr *addr) { - if (!addr) - g_return_val_if_reached (h); - return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (addr)); + nm_hash_update_mem (h, addr, addr ? sizeof (*addr) : 0); } -static inline guint -NM_HASH_COMBINE_IN6ADDR_PREFIX (guint h, const struct in6_addr *addr, guint8 plen) +static inline void +nm_hash_update_in6addr_prefix (NMHashState *h, const struct in6_addr *addr, guint8 plen) { struct in6_addr a; if (!addr) - g_return_val_if_reached (h); + g_return_if_reached (); + nm_utils_ip6_address_clear_host_address (&a, addr, plen); /* we don't hash plen itself. The caller may want to do that.*/ - return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&a)); + nm_hash_update_in6addr (h, &a); } double nm_utils_exp10 (gint16 e); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index a04c3723fa..60b1a5aa17 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5126,34 +5126,30 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi guint nm_platform_link_hash (const NMPlatformLink *obj) { - guint h = NM_HASH_INIT (99413953u); - guint8 i8; + NMHashState h; - h = NM_HASH_COMBINE (h, obj->ifindex); - h = NM_HASH_COMBINE (h, obj->type); - h = NM_HASH_COMBINE (h, g_str_hash (obj->name)); - h = NM_HASH_COMBINE (h, obj->master); - h = NM_HASH_COMBINE (h, obj->parent); - h = NM_HASH_COMBINE (h, obj->n_ifi_flags); - h = NM_HASH_COMBINE (h, obj->connected); - h = NM_HASH_COMBINE (h, obj->mtu); - h = NM_HASH_COMBINE (h, !!obj->initialized); - h = NM_HASH_COMBINE (h, obj->arptype); - h = NM_HASH_COMBINE (h, obj->addr.len); - h = NM_HASH_COMBINE (h, obj->inet6_addr_gen_mode_inv); - if (obj->kind) - h = NM_HASH_COMBINE (h, g_str_hash (obj->kind)); - if (obj->driver) - h = NM_HASH_COMBINE (h, g_str_hash (obj->driver)); - for (i8 = 0; i8 < obj->addr.len; i8++) - h = NM_HASH_COMBINE (h, obj->addr.data[i8]); - for (i8 = 0; i8 < sizeof (obj->inet6_token); i8++) - h = NM_HASH_COMBINE (h, obj->inet6_token.id_u8[i8]); - h = NM_HASH_COMBINE (h, obj->rx_packets); - h = NM_HASH_COMBINE (h, obj->rx_bytes); - h = NM_HASH_COMBINE (h, obj->tx_packets); - h = NM_HASH_COMBINE (h, obj->tx_bytes); - return h; + nm_hash_init (&h, 99413953u); + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_uint (&h, obj->type); + nm_hash_update_str (&h, obj->name); + nm_hash_update_uint (&h, obj->master); + nm_hash_update_uint (&h, obj->parent); + nm_hash_update_uint (&h, obj->n_ifi_flags); + nm_hash_update_uint (&h, obj->connected); + nm_hash_update_uint (&h, obj->mtu); + nm_hash_update_uint (&h, !!obj->initialized); + nm_hash_update_uint (&h, obj->arptype); + nm_hash_update_uint (&h, obj->addr.len); + nm_hash_update_uint (&h, obj->inet6_addr_gen_mode_inv); + nm_hash_update_str (&h, obj->kind); + nm_hash_update_str (&h, obj->driver); + nm_hash_update_mem (&h, obj->addr.data, obj->addr.len); + nm_hash_update_mem (&h, &obj->inet6_token, sizeof (obj->inet6_token)); + nm_hash_update_uint (&h, obj->rx_packets); + nm_hash_update_uint (&h, obj->rx_bytes); + nm_hash_update_uint (&h, obj->tx_packets); + nm_hash_update_uint (&h, obj->tx_bytes); + return nm_hash_complete (&h); } int @@ -5187,19 +5183,20 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) guint nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj) { - guint h = NM_HASH_INIT (1887023311u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE (h, obj->input_flags); - h = NM_HASH_COMBINE (h, obj->output_flags); - h = NM_HASH_COMBINE (h, obj->input_key); - h = NM_HASH_COMBINE (h, obj->output_key); - h = NM_HASH_COMBINE (h, obj->local); - h = NM_HASH_COMBINE (h, obj->remote); - h = NM_HASH_COMBINE (h, obj->ttl); - h = NM_HASH_COMBINE (h, obj->tos); - h = NM_HASH_COMBINE (h, !obj->path_mtu_discovery); - return h; + nm_hash_init (&h, 1887023311u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_uint (&h, obj->input_flags); + nm_hash_update_uint (&h, obj->output_flags); + nm_hash_update_uint (&h, obj->input_key); + nm_hash_update_uint (&h, obj->output_key); + nm_hash_update_uint (&h, obj->local); + nm_hash_update_uint (&h, obj->remote); + nm_hash_update_uint (&h, obj->ttl); + nm_hash_update_uint (&h, obj->tos); + nm_hash_update_uint (&h, !obj->path_mtu_discovery); + return nm_hash_complete (&h); } int @@ -5222,12 +5219,13 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) guint nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj) { - guint h = NM_HASH_INIT (1748638583u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->p_key); + nm_hash_init (&h, 1748638583u); + nm_hash_update_uint (&h, obj->p_key); if (obj->mode) - h = NM_HASH_COMBINE (h, g_str_hash (obj->mode)); - return h; + nm_hash_update_str (&h, obj->mode); + return nm_hash_complete (&h); } int @@ -5242,17 +5240,18 @@ nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatfo guint nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj) { - guint h = NM_HASH_INIT (1651660009u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->local); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->remote); - h = NM_HASH_COMBINE (h, obj->ttl); - h = NM_HASH_COMBINE (h, obj->tclass); - h = NM_HASH_COMBINE (h, obj->encap_limit); - h = NM_HASH_COMBINE (h, obj->flow_label); - h = NM_HASH_COMBINE (h, obj->proto); - return h; + nm_hash_init (&h, 1651660009u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_in6addr (&h, &obj->local); + nm_hash_update_in6addr (&h, &obj->remote); + nm_hash_update_uint (&h, obj->ttl); + nm_hash_update_uint (&h, obj->tclass); + nm_hash_update_uint (&h, obj->encap_limit); + nm_hash_update_uint (&h, obj->flow_label); + nm_hash_update_uint (&h, obj->proto); + return nm_hash_complete (&h); } int @@ -5273,15 +5272,16 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6 guint nm_platform_lnk_ipip_hash (const NMPlatformLnkIpIp *obj) { - guint h = NM_HASH_INIT (861934429u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE (h, obj->local); - h = NM_HASH_COMBINE (h, obj->remote); - h = NM_HASH_COMBINE (h, obj->ttl); - h = NM_HASH_COMBINE (h, obj->tos); - h = NM_HASH_COMBINE (h, obj->path_mtu_discovery); - return h; + nm_hash_init (&h, 861934429u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_uint (&h, obj->local); + nm_hash_update_uint (&h, obj->remote); + nm_hash_update_uint (&h, obj->ttl); + nm_hash_update_uint (&h, obj->tos); + nm_hash_update_uint (&h, obj->path_mtu_discovery); + return nm_hash_complete (&h); } int @@ -5300,22 +5300,23 @@ nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b guint nm_platform_lnk_macsec_hash (const NMPlatformLnkMacsec *obj) { - guint h = NM_HASH_INIT (226984267u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE (h, obj->sci); - h = NM_HASH_COMBINE_UINT64 (h, obj->icv_length); - h = NM_HASH_COMBINE_UINT64 (h, obj->cipher_suite); - h = NM_HASH_COMBINE (h, obj->window); - h = NM_HASH_COMBINE (h, obj->encoding_sa); - h = NM_HASH_COMBINE (h, obj->validation); - h = NM_HASH_COMBINE (h, obj->encrypt); - h = NM_HASH_COMBINE (h, obj->protect); - h = NM_HASH_COMBINE (h, obj->include_sci); - h = NM_HASH_COMBINE (h, obj->es); - h = NM_HASH_COMBINE (h, obj->scb); - h = NM_HASH_COMBINE (h, obj->replay_protect); - return h; + nm_hash_init (&h, 226984267u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_uint (&h, obj->sci); + nm_hash_update_uint64 (&h, obj->icv_length); + nm_hash_update_uint64 (&h, obj->cipher_suite); + nm_hash_update_uint (&h, obj->window); + nm_hash_update_uint (&h, obj->encoding_sa); + nm_hash_update_uint (&h, obj->validation); + nm_hash_update_uint (&h, obj->encrypt); + nm_hash_update_uint (&h, obj->protect); + nm_hash_update_uint (&h, obj->include_sci); + nm_hash_update_uint (&h, obj->es); + nm_hash_update_uint (&h, obj->scb); + nm_hash_update_uint (&h, obj->replay_protect); + return nm_hash_complete (&h); } int @@ -5341,12 +5342,13 @@ nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMac guint nm_platform_lnk_macvlan_hash (const NMPlatformLnkMacvlan *obj) { - guint h = NM_HASH_INIT (771014989u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->mode); - h = NM_HASH_COMBINE (h, obj->no_promisc); - h = NM_HASH_COMBINE (h, obj->tap); - return h; + nm_hash_init (&h, 771014989u); + nm_hash_update_uint (&h, obj->mode); + nm_hash_update_uint (&h, obj->no_promisc); + nm_hash_update_uint (&h, obj->tap); + return nm_hash_complete (&h); } int @@ -5362,17 +5364,18 @@ nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkM guint nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj) { - guint h = NM_HASH_INIT (1690154969u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE (h, obj->local); - h = NM_HASH_COMBINE (h, obj->remote); - h = NM_HASH_COMBINE (h, obj->ttl); - h = NM_HASH_COMBINE (h, obj->tos); - h = NM_HASH_COMBINE (h, obj->path_mtu_discovery); - h = NM_HASH_COMBINE (h, obj->flags); - h = NM_HASH_COMBINE (h, obj->proto); - return h; + nm_hash_init (&h, 1690154969u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_uint (&h, obj->local); + nm_hash_update_uint (&h, obj->remote); + nm_hash_update_uint (&h, obj->ttl); + nm_hash_update_uint (&h, obj->tos); + nm_hash_update_uint (&h, obj->path_mtu_discovery); + nm_hash_update_uint (&h, obj->flags); + nm_hash_update_uint (&h, obj->proto); + return nm_hash_complete (&h); } int @@ -5393,11 +5396,12 @@ nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) guint nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj) { - guint h = NM_HASH_INIT (58751383u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->id); - h = NM_HASH_COMBINE (h, obj->flags); - return h; + nm_hash_init (&h, 58751383u); + nm_hash_update_uint (&h, obj->id); + nm_hash_update_uint (&h, obj->flags); + return nm_hash_complete (&h); } int @@ -5412,27 +5416,28 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b guint nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj) { - guint h = NM_HASH_INIT (461041297u); + NMHashState h; - h = NM_HASH_COMBINE (h, obj->parent_ifindex); - h = NM_HASH_COMBINE (h, obj->id); - h = NM_HASH_COMBINE (h, obj->group); - h = NM_HASH_COMBINE (h, obj->local); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->group6); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->local6); - h = NM_HASH_COMBINE (h, obj->tos); - h = NM_HASH_COMBINE (h, obj->ttl); - h = NM_HASH_COMBINE (h, obj->learning); - h = NM_HASH_COMBINE (h, obj->ageing); - h = NM_HASH_COMBINE (h, obj->limit); - h = NM_HASH_COMBINE (h, obj->dst_port); - h = NM_HASH_COMBINE (h, obj->src_port_min); - h = NM_HASH_COMBINE (h, obj->src_port_max); - h = NM_HASH_COMBINE (h, obj->proxy); - h = NM_HASH_COMBINE (h, obj->rsc); - h = NM_HASH_COMBINE (h, obj->l2miss); - h = NM_HASH_COMBINE (h, obj->l3miss); - return h; + nm_hash_init (&h, 461041297u); + nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_uint (&h, obj->id); + nm_hash_update_uint (&h, obj->group); + nm_hash_update_uint (&h, obj->local); + nm_hash_update_in6addr (&h, &obj->group6); + nm_hash_update_in6addr (&h, &obj->local6); + nm_hash_update_uint (&h, obj->tos); + nm_hash_update_uint (&h, obj->ttl); + nm_hash_update_uint (&h, obj->learning); + nm_hash_update_uint (&h, obj->ageing); + nm_hash_update_uint (&h, obj->limit); + nm_hash_update_uint (&h, obj->dst_port); + nm_hash_update_uint (&h, obj->src_port_min); + nm_hash_update_uint (&h, obj->src_port_max); + nm_hash_update_uint (&h, obj->proxy); + nm_hash_update_uint (&h, obj->rsc); + nm_hash_update_uint (&h, obj->l2miss); + nm_hash_update_uint (&h, obj->l3miss); + return nm_hash_complete (&h); } int @@ -5463,21 +5468,22 @@ nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan guint nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj) { - guint h = NM_HASH_INIT (469681301u); + NMHashState h; + nm_hash_init (&h, 469681301u); if (obj) { - h = NM_HASH_COMBINE (h, obj->ifindex); - h = NM_HASH_COMBINE (h, obj->address); - h = NM_HASH_COMBINE (h, obj->plen); - h = NM_HASH_COMBINE (h, obj->peer_address); - h = NM_HASH_COMBINE (h, obj->addr_source); - h = NM_HASH_COMBINE (h, obj->timestamp); - h = NM_HASH_COMBINE (h, obj->lifetime); - h = NM_HASH_COMBINE (h, obj->preferred); - h = NM_HASH_COMBINE (h, obj->n_ifa_flags); - h = NM_HASH_COMBINE (h, g_str_hash (obj->label)); + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_uint (&h, obj->address); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_uint (&h, obj->peer_address); + nm_hash_update_uint (&h, obj->addr_source); + nm_hash_update_uint (&h, obj->timestamp); + nm_hash_update_uint (&h, obj->lifetime); + nm_hash_update_uint (&h, obj->preferred); + nm_hash_update_uint (&h, obj->n_ifa_flags); + nm_hash_update_str (&h, obj->label); } - return h; + return nm_hash_complete (&h); } int @@ -5500,20 +5506,21 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A guint nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj) { - guint h = NM_HASH_INIT (605908909u); + NMHashState h; + nm_hash_init (&h, 605908909u); if (obj) { - h = NM_HASH_COMBINE (h, obj->ifindex); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->address); - h = NM_HASH_COMBINE (h, obj->plen); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->peer_address); - h = NM_HASH_COMBINE (h, obj->addr_source); - h = NM_HASH_COMBINE (h, obj->timestamp); - h = NM_HASH_COMBINE (h, obj->lifetime); - h = NM_HASH_COMBINE (h, obj->preferred); - h = NM_HASH_COMBINE (h, obj->n_ifa_flags); + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_in6addr (&h, &obj->address); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_in6addr (&h, &obj->peer_address); + nm_hash_update_uint (&h, obj->addr_source); + nm_hash_update_uint (&h, obj->timestamp); + nm_hash_update_uint (&h, obj->lifetime); + nm_hash_update_uint (&h, obj->preferred); + nm_hash_update_uint (&h, obj->n_ifa_flags); } - return h; + return nm_hash_complete (&h); } int @@ -5539,76 +5546,77 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type) { - guint h = NM_HASH_INIT (1228913327u); + NMHashState h; - h = NM_HASH_COMBINE (h, cmp_type); + nm_hash_init (&h, 1228913327u); + nm_hash_update_uint (&h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - h = NM_HASH_COMBINE (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); - h = NM_HASH_COMBINE (h, obj->plen); - h = NM_HASH_COMBINE (h, obj->metric); - h = NM_HASH_COMBINE (h, obj->tos); + nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_uint (&h, obj->metric); + nm_hash_update_uint (&h, obj->tos); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - h = NM_HASH_COMBINE (h, obj->ifindex); - h = NM_HASH_COMBINE (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - h = NM_HASH_COMBINE (h, _ip_route_scope_inv_get_normalized (obj)); - h = NM_HASH_COMBINE (h, obj->gateway); - h = NM_HASH_COMBINE (h, obj->mss); - h = NM_HASH_COMBINE (h, obj->pref_src); - h = NM_HASH_COMBINE (h, obj->window); - h = NM_HASH_COMBINE (h, obj->cwnd); - h = NM_HASH_COMBINE (h, obj->initcwnd); - h = NM_HASH_COMBINE (h, obj->initrwnd); - h = NM_HASH_COMBINE (h, obj->mtu); - h = NM_HASH_COMBINE (h, obj->lock_window); - h = NM_HASH_COMBINE (h, obj->lock_cwnd); - h = NM_HASH_COMBINE (h, obj->lock_initcwnd); - h = NM_HASH_COMBINE (h, obj->lock_initrwnd); - h = NM_HASH_COMBINE (h, obj->lock_mtu); + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_uint (&h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_uint (&h, obj->gateway); + nm_hash_update_uint (&h, obj->mss); + nm_hash_update_uint (&h, obj->pref_src); + nm_hash_update_uint (&h, obj->window); + nm_hash_update_uint (&h, obj->cwnd); + nm_hash_update_uint (&h, obj->initcwnd); + nm_hash_update_uint (&h, obj->initrwnd); + nm_hash_update_uint (&h, obj->mtu); + nm_hash_update_uint (&h, obj->lock_window); + nm_hash_update_uint (&h, obj->lock_cwnd); + nm_hash_update_uint (&h, obj->lock_initcwnd); + nm_hash_update_uint (&h, obj->lock_initrwnd); + nm_hash_update_uint (&h, obj->lock_mtu); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - h = NM_HASH_COMBINE (h, obj->table_coerced); - h = NM_HASH_COMBINE (h, obj->ifindex); + nm_hash_update_uint (&h, obj->table_coerced); + nm_hash_update_uint (&h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); else - h = NM_HASH_COMBINE (h, obj->network); - h = NM_HASH_COMBINE (h, obj->plen); - h = NM_HASH_COMBINE (h, obj->metric); - h = NM_HASH_COMBINE (h, obj->gateway); + nm_hash_update_uint (&h, obj->network); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_uint (&h, obj->metric); + nm_hash_update_uint (&h, obj->gateway); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - h = NM_HASH_COMBINE (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - h = NM_HASH_COMBINE (h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_uint (&h, _ip_route_scope_inv_get_normalized (obj)); } else { - h = NM_HASH_COMBINE (h, obj->rt_source); - h = NM_HASH_COMBINE (h, obj->scope_inv); + nm_hash_update_uint (&h, obj->rt_source); + nm_hash_update_uint (&h, obj->scope_inv); } - h = NM_HASH_COMBINE (h, obj->mss); - h = NM_HASH_COMBINE (h, obj->pref_src); - h = NM_HASH_COMBINE (h, obj->rt_cloned); - h = NM_HASH_COMBINE (h, obj->tos); - h = NM_HASH_COMBINE (h, obj->lock_window); - h = NM_HASH_COMBINE (h, obj->lock_cwnd); - h = NM_HASH_COMBINE (h, obj->lock_initcwnd); - h = NM_HASH_COMBINE (h, obj->lock_initrwnd); - h = NM_HASH_COMBINE (h, obj->lock_mtu); - h = NM_HASH_COMBINE (h, obj->window); - h = NM_HASH_COMBINE (h, obj->cwnd); - h = NM_HASH_COMBINE (h, obj->initcwnd); - h = NM_HASH_COMBINE (h, obj->initrwnd); - h = NM_HASH_COMBINE (h, obj->mtu); + nm_hash_update_uint (&h, obj->mss); + nm_hash_update_uint (&h, obj->pref_src); + nm_hash_update_uint (&h, obj->rt_cloned); + nm_hash_update_uint (&h, obj->tos); + nm_hash_update_uint (&h, obj->lock_window); + nm_hash_update_uint (&h, obj->lock_cwnd); + nm_hash_update_uint (&h, obj->lock_initcwnd); + nm_hash_update_uint (&h, obj->lock_initrwnd); + nm_hash_update_uint (&h, obj->lock_mtu); + nm_hash_update_uint (&h, obj->window); + nm_hash_update_uint (&h, obj->cwnd); + nm_hash_update_uint (&h, obj->initcwnd); + nm_hash_update_uint (&h, obj->initrwnd); + nm_hash_update_uint (&h, obj->mtu); break; } } - return h; + return nm_hash_complete (&h); } int @@ -5691,71 +5699,72 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type) { - guint h = NM_HASH_INIT (1053326051u); + NMHashState h; - h = NM_HASH_COMBINE (h, cmp_type); + nm_hash_init (&h, 1053326051u); + nm_hash_update_uint (&h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - h = NM_HASH_COMBINE (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen); - h = NM_HASH_COMBINE (h, obj->plen); - h = NM_HASH_COMBINE (h, nm_utils_ip6_route_metric_normalize (obj->metric)); - h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->src, obj->src_plen); - h = NM_HASH_COMBINE (h, obj->src_plen); + nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_uint (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); + nm_hash_update_uint (&h, obj->src_plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - h = NM_HASH_COMBINE (h, obj->ifindex); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->gateway); + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_in6addr (&h, &obj->gateway); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - h = NM_HASH_COMBINE (h, obj->table_coerced); - h = NM_HASH_COMBINE (h, obj->ifindex); + nm_hash_update_uint (&h, obj->table_coerced); + nm_hash_update_uint (&h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen); + nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); else - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->network); - h = NM_HASH_COMBINE (h, obj->plen); + nm_hash_update_in6addr (&h, &obj->network); + nm_hash_update_uint (&h, obj->plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE (h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_uint (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); else - h = NM_HASH_COMBINE (h, obj->metric); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->gateway); - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->pref_src); + nm_hash_update_uint (&h, obj->metric); + nm_hash_update_in6addr (&h, &obj->gateway); + nm_hash_update_in6addr (&h, &obj->pref_src); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->src, obj->src_plen); - h = NM_HASH_COMBINE (h, obj->src_plen); - h = NM_HASH_COMBINE (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); + nm_hash_update_uint (&h, obj->src_plen); + nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); } else { - h = NM_HASH_COMBINE_IN6ADDR (h, &obj->src); - h = NM_HASH_COMBINE (h, obj->src_plen); - h = NM_HASH_COMBINE (h, obj->rt_source); + nm_hash_update_in6addr (&h, &obj->src); + nm_hash_update_uint (&h, obj->src_plen); + nm_hash_update_uint (&h, obj->rt_source); } - h = NM_HASH_COMBINE (h, obj->mss); - h = NM_HASH_COMBINE (h, obj->rt_cloned); - h = NM_HASH_COMBINE (h, obj->lock_window); - h = NM_HASH_COMBINE (h, obj->lock_cwnd); - h = NM_HASH_COMBINE (h, obj->lock_initcwnd); - h = NM_HASH_COMBINE (h, obj->lock_initrwnd); - h = NM_HASH_COMBINE (h, obj->lock_mtu); - h = NM_HASH_COMBINE (h, obj->window); - h = NM_HASH_COMBINE (h, obj->cwnd); - h = NM_HASH_COMBINE (h, obj->initcwnd); - h = NM_HASH_COMBINE (h, obj->initrwnd); - h = NM_HASH_COMBINE (h, obj->mtu); + nm_hash_update_uint (&h, obj->mss); + nm_hash_update_uint (&h, obj->rt_cloned); + nm_hash_update_uint (&h, obj->lock_window); + nm_hash_update_uint (&h, obj->lock_cwnd); + nm_hash_update_uint (&h, obj->lock_initcwnd); + nm_hash_update_uint (&h, obj->lock_initrwnd); + nm_hash_update_uint (&h, obj->lock_mtu); + nm_hash_update_uint (&h, obj->window); + nm_hash_update_uint (&h, obj->cwnd); + nm_hash_update_uint (&h, obj->initcwnd); + nm_hash_update_uint (&h, obj->initrwnd); + nm_hash_update_uint (&h, obj->mtu); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - h = NM_HASH_COMBINE (h, _route_pref_normalize (obj->rt_pref)); + nm_hash_update_uint (&h, _route_pref_normalize (obj->rt_pref)); else - h = NM_HASH_COMBINE (h, obj->rt_pref); + nm_hash_update_uint (&h, obj->rt_pref); break; } } - return h; + return nm_hash_complete (&h); } int diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 24651a66d0..fdc8dd87a9 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -121,9 +121,19 @@ _idx_obj_id_equal (const NMDedupMultiIdxType *idx_type, * on whether the objects are equal. * * _HASH_NON_ZERO() is used to for case 2), to avoid that the a zero hash value - * is returned. */ -#define _HASH_NON_ZERO(h) \ - ((h) ?: (1998098407 + __LINE__)) \ + * is returned. + * + * Actually, nm_hash_complete() never returns zero. This code is only + * here as a safeguard and a reminder that the has MUST not be zero. */ +static inline guint +_HASH_NON_ZERO (NMHashState *h) +{ + guint v; + + v = nm_hash_complete (h); + nm_assert (v != 0); + return v; +} static guint _idx_obj_part (const DedupMultiIdxType *idx_type, @@ -131,7 +141,6 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, const NMPObject *obj_a, const NMPObject *obj_b) { - guint h; NMPObjectType obj_type; /* the hash/equals functions are strongly related. So, keep them @@ -150,10 +159,12 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, if (obj_b) return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b); if (request_hash) { - h = NM_HASH_INIT (487703243u); - h = NM_HASH_COMBINE (h, idx_type->cache_id_type); - h = NM_HASH_COMBINE (h, NMP_OBJECT_GET_TYPE (obj_a)); - return _HASH_NON_ZERO (h); + NMHashState h; + + nm_hash_init (&h, 487703243u); + nm_hash_update_uint (&h, idx_type->cache_id_type); + nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); + return _HASH_NON_ZERO (&h); } return 1; @@ -170,11 +181,13 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, && nm_streq (obj_a->link.name, obj_b->link.name); } if (request_hash) { + NMHashState h; + /* we request a hash from obj_a. Hash the relevant parts. */ - h = NM_HASH_INIT (2126752699u); - h = NM_HASH_COMBINE (h, idx_type->cache_id_type); - h = NM_HASH_COMBINE (h, g_str_hash (obj_a->link.name)); - return _HASH_NON_ZERO (h); + nm_hash_init (&h, 2126752699u); + nm_hash_update_uint (&h, idx_type->cache_id_type); + nm_hash_update_str (&h, obj_a->link.name); + return _HASH_NON_ZERO (&h); } /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ return 1; @@ -191,10 +204,12 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, && nmp_object_is_visible (obj_b); } if (request_hash) { - h = NM_HASH_INIT (4278960223u); - h = NM_HASH_COMBINE (h, idx_type->cache_id_type); - h = NM_HASH_COMBINE (h, NMP_OBJECT_GET_TYPE (obj_a)); - return _HASH_NON_ZERO (h); + NMHashState h; + + nm_hash_init (&h, 4278960223u); + nm_hash_update_uint (&h, idx_type->cache_id_type); + nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); + return _HASH_NON_ZERO (&h); } return 1; @@ -212,11 +227,13 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, && nmp_object_is_visible (obj_b); } if (request_hash) { - h = NM_HASH_INIT (920415631u); - h = NM_HASH_COMBINE (h, idx_type->cache_id_type); - h = NM_HASH_COMBINE (h, NMP_OBJECT_GET_TYPE (obj_a)); - h = NM_HASH_COMBINE (h, obj_a->object.ifindex); - return _HASH_NON_ZERO (h); + NMHashState h; + + nm_hash_init (&h, 920415631u); + nm_hash_update_uint (&h, idx_type->cache_id_type); + nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); + nm_hash_update_uint (&h, obj_a->object.ifindex); + return _HASH_NON_ZERO (&h); } return 1; @@ -234,13 +251,15 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, : (nm_platform_ip6_route_cmp (&obj_a->ip6_route, &obj_b->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0)); } if (request_hash) { - h = NM_HASH_INIT (778646573u); - h = NM_HASH_COMBINE (h, idx_type->cache_id_type); + NMHashState h; + + nm_hash_init (&h, 778646573u); + nm_hash_update_uint (&h, idx_type->cache_id_type); if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) - h = NM_HASH_COMBINE (h, nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); + nm_hash_update_uint (&h, nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); else - h = NM_HASH_COMBINE (h, nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); - return _HASH_NON_ZERO (h); + nm_hash_update_uint (&h, nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); + return _HASH_NON_ZERO (&h); } return 1; @@ -301,18 +320,18 @@ _dedup_multi_idx_type_init (DedupMultiIdxType *idx_type, NMPCacheIdType cache_id /*****************************************************************************/ -static guint -_vlan_xgress_qos_mappings_hash (guint n_map, +static void +_vlan_xgress_qos_mappings_hash (NMHashState *h, + guint n_map, const NMVlanQosMapping *map) { - guint h = NM_HASH_INIT (1453577309u); guint i; + nm_hash_update_uint (h, 1453577309u); for (i = 0; i < n_map; i++) { - h = NM_HASH_COMBINE (h, map[i].from); - h = NM_HASH_COMBINE (h, map[i].to); + nm_hash_update_uint (h, map[i].from); + nm_hash_update_uint (h, map[i].to); } - return h; } static int @@ -745,14 +764,14 @@ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsiz _vt_cmd_plobj_to_string_id (link, NMPlatformLink, "%d", obj->ifindex); _vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s", obj->ifindex, nm_utils_inet4_ntop ( obj->address, buf1), obj->plen, obj->peer_address != obj->address ? "," : "", - obj->peer_address != obj->address ? nm_utils_inet4_ntop (obj->peer_address & _nm_utils_ip4_prefix_to_netmask (obj->plen), buf2) : ""); + obj->peer_address != obj->address ? nm_utils_inet4_ntop (nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen), buf2) : ""); _vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1)); guint nmp_object_hash (const NMPObject *obj) { const NMPClass *klass; - guint h; + NMHashState h; if (!obj) return 0; @@ -761,44 +780,50 @@ nmp_object_hash (const NMPObject *obj) klass = NMP_OBJECT_GET_CLASS (obj); - h = NM_HASH_INIT (816200863u); + nm_hash_init (&h, 816200863u); + nm_hash_update_uint (&h, klass->obj_type); if (klass->cmd_obj_hash) - h = NM_HASH_COMBINE (h, klass->cmd_obj_hash (obj)); + nm_hash_update_uint (&h, klass->cmd_obj_hash (obj)); else if (klass->cmd_plobj_hash) - h = NM_HASH_COMBINE (h, klass->cmd_plobj_hash (&obj->object)); + nm_hash_update_uint (&h, klass->cmd_plobj_hash (&obj->object)); else - return NM_HASH_POINTER (obj); - return NM_HASH_COMBINE (h, klass->obj_type); + nm_hash_update_ptr (&h, obj); + + return nm_hash_complete (&h); } static guint _vt_cmd_obj_hash_link (const NMPObject *obj) { - guint h = NM_HASH_INIT (3448776161u); + NMHashState h; nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK); - h = NM_HASH_COMBINE (h, nm_platform_link_hash (&obj->link)); - h = NM_HASH_COMBINE (h, obj->_link.netlink.is_in_netlink); + nm_hash_init (&h, 3448776161u); + nm_hash_update_uint (&h, nm_platform_link_hash (&obj->link)); + nm_hash_update_uint (&h, obj->_link.netlink.is_in_netlink); if (obj->_link.netlink.lnk) - h = NM_HASH_COMBINE (h, nmp_object_hash (obj->_link.netlink.lnk)); - h = NM_HASH_COMBINE (h, GPOINTER_TO_UINT (obj->_link.udev.device)); - return h; + nm_hash_update_uint (&h, nmp_object_hash (obj->_link.netlink.lnk)); + nm_hash_update_ptr (&h, obj->_link.udev.device); + return nm_hash_complete (&h); } static guint _vt_cmd_obj_hash_lnk_vlan (const NMPObject *obj) { - guint h = NM_HASH_INIT (914932607u); + NMHashState h; nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_VLAN); - h = NM_HASH_COMBINE (h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); - h = NM_HASH_COMBINE (h, _vlan_xgress_qos_mappings_hash (obj->_lnk_vlan.n_ingress_qos_map, - obj->_lnk_vlan.ingress_qos_map)); - h = NM_HASH_COMBINE (h, _vlan_xgress_qos_mappings_hash (obj->_lnk_vlan.n_egress_qos_map, - obj->_lnk_vlan.egress_qos_map)); - return h; + nm_hash_init (&h, 914932607u); + nm_hash_update_uint (&h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); + _vlan_xgress_qos_mappings_hash (&h, + obj->_lnk_vlan.n_ingress_qos_map, + obj->_lnk_vlan.ingress_qos_map); + _vlan_xgress_qos_mappings_hash (&h, + obj->_lnk_vlan.n_egress_qos_map, + obj->_lnk_vlan.egress_qos_map); + return nm_hash_complete (&h); } int @@ -1082,47 +1107,43 @@ nmp_object_id_hash (const NMPObject *obj) if (!klass->cmd_plobj_id_hash) { /* The klass doesn't implement ID compare. It means, to use pointer - * equality (g_direct_hash). */ - return NM_HASH_POINTER (obj); + * equality. */ + return nm_hash_ptr (obj); } return klass->cmd_plobj_id_hash (&obj->object); } -#define _vt_cmd_plobj_id_hash(type, plat_type, cmd) \ +#define _vt_cmd_plobj_id_hash(type, plat_type, hash_seed, cmd) \ static guint \ _vt_cmd_plobj_id_hash_##type (const NMPlatformObject *_obj) \ { \ const plat_type *const obj = (const plat_type *) _obj; \ - guint hash; \ + NMHashState h; \ + nm_hash_init (&h, (hash_seed)); \ { cmd; } \ - return hash; \ + return nm_hash_complete (&h); \ } -_vt_cmd_plobj_id_hash (link, NMPlatformLink, { - hash = NM_HASH_INIT (3982791431u); - hash = NM_HASH_COMBINE (hash, ((guint) obj->ifindex)); +_vt_cmd_plobj_id_hash (link, NMPlatformLink, 3982791431u, { + nm_hash_update_uint (&h, obj->ifindex); }) -_vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, { - hash = NM_HASH_INIT (3591309853u); - hash = NM_HASH_COMBINE (hash, ((guint) obj->ifindex)); - hash = NM_HASH_COMBINE (hash, obj->plen); - hash = NM_HASH_COMBINE (hash, obj->address); +_vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, 3591309853u, { + nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_uint (&h, obj->plen); + nm_hash_update_uint (&h, obj->address); /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ - hash = NM_HASH_COMBINE (hash, (obj->peer_address & _nm_utils_ip4_prefix_to_netmask (obj->plen))); + nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen)); }) -_vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, { - hash = NM_HASH_INIT (2907861637u); - hash = NM_HASH_COMBINE (hash, ((guint) obj->ifindex)); +_vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, 2907861637u, { + nm_hash_update_uint (&h, obj->ifindex); /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ - hash = NM_HASH_COMBINE (hash, nm_utils_in6_addr_hash (&obj->address)); + nm_hash_update_in6addr (&h, &obj->address); }) -_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, { - hash = NM_HASH_INIT (1038302471u); - hash = NM_HASH_COMBINE (hash, nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); +_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, 1038302471u, { + nm_hash_update_uint (&h, nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); }) -_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, { - hash = NM_HASH_INIT (1233384151u); - hash = NM_HASH_COMBINE (hash, nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); +_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, 1233384151u, { + nm_hash_update_uint (&h, nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); }) gboolean From 3434261811b6edde77689983ac4c4e70cd2ca39a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 13 Oct 2017 16:12:35 +0200 Subject: [PATCH 07/12] core,clients: use our own string hashing function nm_str_hash() Replace the usage of g_str_hash() with our own nm_str_hash(). GLib's g_str_hash() uses djb2 hashing function, just like we do at the moment. The only difference is, that we use a diffrent seed value. Note, that we initialize the hash seed with random data (by calling getrandom() or reading /dev/urandom). That is a change compared to before. This change of the hashing function and accessing the random pool might be undesired for libnm/libnm-core. Hence, the change is not done there as it possibly changes behavior for public API. Maybe we should do that later though. At this point, there isn't much of a change. This patch becomes interesting, if we decide to use a different hashing algorithm. --- Makefile.am | 16 +++++++++------- clients/cli/common.c | 3 ++- clients/cli/connections.c | 4 +++- clients/cli/nmcli.c | 4 +++- clients/common/nm-meta-setting-desc.c | 5 +++-- clients/common/nm-secret-agent-simple.c | 6 ++++-- clients/common/tests/test-general.c | 4 +++- clients/tui/nmt-connect-connection-list.c | 6 ++++-- src/NetworkManagerUtils.c | 2 +- src/devices/bluetooth/nm-bluez4-adapter.c | 3 ++- src/devices/bluetooth/nm-bluez5-manager.c | 2 +- src/devices/nm-device-ethernet.c | 2 +- src/devices/nm-device-factory.c | 2 +- src/devices/nm-device.c | 4 ++-- src/devices/wifi/nm-device-wifi.c | 2 +- src/devices/wwan/nm-modem-manager.c | 2 +- src/devices/wwan/nm-modem-ofono.c | 2 +- src/dhcp/nm-dhcp-client.c | 2 +- src/dhcp/nm-dhcp-dhclient-utils.c | 2 +- src/dhcp/nm-dhcp-systemd.c | 4 ++-- src/dhcp/tests/test-dhcp-utils.c | 2 +- src/nm-auth-utils.c | 3 ++- src/nm-checkpoint-manager.c | 2 +- src/nm-checkpoint.c | 2 +- src/nm-config-data.c | 4 ++-- src/nm-exported-object.c | 4 ++-- src/platform/nm-fake-platform.c | 2 +- src/platform/nm-linux-platform.c | 2 +- src/platform/nmp-object.c | 18 +++++++++--------- src/settings/nm-agent-manager.c | 2 +- src/settings/nm-settings-connection.c | 2 +- src/settings/nm-settings.c | 2 +- src/settings/plugins/ibft/nms-ibft-plugin.c | 2 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c | 4 ++-- src/settings/plugins/ifcfg-rh/shvar.c | 2 +- .../plugins/ifnet/nms-ifnet-net-parser.c | 6 +++--- src/settings/plugins/ifnet/nms-ifnet-plugin.c | 4 ++-- .../plugins/ifnet/nms-ifnet-wpa-parser.c | 9 +++++---- .../plugins/ifupdown/nms-ifupdown-plugin.c | 8 ++++---- .../plugins/keyfile/nms-keyfile-plugin.c | 4 ++-- src/supplicant/nm-supplicant-config.c | 4 ++-- src/supplicant/nm-supplicant-interface.c | 2 +- src/vpn/nm-vpn-manager.c | 2 +- 43 files changed, 93 insertions(+), 76 deletions(-) diff --git a/Makefile.am b/Makefile.am index 12aff3d666..ee8e4f079a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3192,6 +3192,15 @@ clients_cppflags = \ check_ltlibraries += clients/common/libnmc-base.la clients_common_libnmc_base_la_SOURCES = \ + shared/nm-utils/nm-enum-utils.c \ + shared/nm-utils/nm-enum-utils.h \ + shared/nm-utils/nm-hash-utils.c \ + shared/nm-utils/nm-hash-utils.h \ + shared/nm-utils/nm-random-utils.c \ + shared/nm-utils/nm-random-utils.h \ + shared/nm-utils/nm-shared-utils.c \ + shared/nm-utils/nm-shared-utils.h \ + \ clients/common/nm-secret-agent-simple.c \ clients/common/nm-secret-agent-simple.h \ clients/common/nm-vpn-helpers.c \ @@ -3240,11 +3249,6 @@ EXTRA_LTLIBRARIES += clients/common/libnmc.la endif clients_common_libnmc_la_SOURCES = \ - shared/nm-utils/nm-enum-utils.c \ - shared/nm-utils/nm-enum-utils.h \ - shared/nm-utils/nm-shared-utils.c \ - shared/nm-utils/nm-shared-utils.h \ - \ shared/nm-meta-setting.c \ shared/nm-meta-setting.h \ \ @@ -3426,8 +3430,6 @@ clients_tui_newt_libnmt_newt_a_CPPFLAGS = \ bin_PROGRAMS += clients/tui/nmtui clients_tui_nmtui_SOURCES = \ - shared/nm-utils/nm-shared-utils.c \ - shared/nm-utils/nm-shared-utils.h \ clients/tui/nmtui.c \ clients/tui/nmtui.h \ clients/tui/nmtui-connect.c \ diff --git a/clients/cli/common.c b/clients/cli/common.c index 0f5dff4baf..246b597d56 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -31,6 +31,7 @@ #include #include +#include "nm-utils/nm-hash-utils.h" #include "nm-vpn-helpers.h" #include "nm-client-utils.h" @@ -41,7 +42,7 @@ static char ** _ip_config_get_routes (NMIPConfig *cfg) { - gs_unref_hashtable GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + gs_unref_hashtable GHashTable *hash = g_hash_table_new (nm_str_hash, g_str_equal); GPtrArray *ptr_array; char **arr; guint i; diff --git a/clients/cli/connections.c b/clients/cli/connections.c index e518c9aa7c..5ef82a4e48 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -31,6 +31,8 @@ #include #include +#include "nm-utils/nm-hash-utils.h" + #include "nm-client-utils.h" #include "nm-vpn-helpers.h" #include "nm-meta-setting-access.h" @@ -2268,7 +2270,7 @@ parse_passwords (const char *passwd_file, GError **error) char *pwd_spec, *pwd, *prop; const char *setting; - pwds_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); if (!passwd_file) return pwds_hash; diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 70d78db6f0..ee621ca3bb 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -36,6 +36,8 @@ #include "nm-client-utils.h" +#include "nm-utils/nm-hash-utils.h" + #include "polkit-agent.h" #include "utils.h" #include "common.h" @@ -124,7 +126,7 @@ complete_fields (const char *option, const char *prefix) GHashTable *h; const char *option_with_value[2] = { option, prefix }; - h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + h = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); complete_field (h, metagen_ip4_config); complete_field (h, nmc_fields_dhcp4_config); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index c429f4d41c..4e90c42643 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -25,6 +25,7 @@ #include #include "nm-common-macros.h" +#include "nm-utils/nm-hash-utils.h" #include "nm-utils/nm-enum-utils.h" #include "NetworkManager.h" @@ -188,7 +189,7 @@ _parse_ip_route (int family, } if (!attrs) - attrs = g_hash_table_new (g_str_hash, g_str_equal); + attrs = g_hash_table_new (nm_str_hash, g_str_equal); g_hash_table_iter_init (&iter, tmp_attrs); while (g_hash_table_iter_next (&iter, (gpointer *) &iter_key, (gpointer *) &iter_value)) { @@ -3011,7 +3012,7 @@ _get_fcn_ip_config_routes (ARGS_GET_FCN) for (i = 0; i < num_routes; i++) { gs_free char *attr_str = NULL; gs_strfreev char **attr_names = NULL; - gs_unref_hashtable GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + gs_unref_hashtable GHashTable *hash = g_hash_table_new (nm_str_hash, g_str_equal); int j; route = nm_setting_ip_config_get_route (s_ip, i); diff --git a/clients/common/nm-secret-agent-simple.c b/clients/common/nm-secret-agent-simple.c index 0faf68a567..c08f7fe244 100644 --- a/clients/common/nm-secret-agent-simple.c +++ b/clients/common/nm-secret-agent-simple.c @@ -33,6 +33,8 @@ #include +#include "nm-utils/nm-hash-utils.h" + #include "NetworkManager.h" #include "nm-vpn-service-plugin.h" @@ -86,7 +88,7 @@ nm_secret_agent_simple_init (NMSecretAgentSimple *agent) { NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent); - priv->requests = g_hash_table_new_full (g_str_hash, g_str_equal, + priv->requests = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, nm_secret_agent_simple_request_free); } @@ -694,7 +696,7 @@ nm_secret_agent_simple_response (NMSecretAgentSimple *self, g_variant_builder_init (&vpn_secrets_builder, G_VARIANT_TYPE ("a{ss}")); - settings = g_hash_table_new (g_str_hash, g_str_equal); + settings = g_hash_table_new (nm_str_hash, g_str_equal); for (i = 0; i < secrets->len; i++) { NMSecretAgentSimpleSecretReal *secret = secrets->pdata[i]; diff --git a/clients/common/tests/test-general.c b/clients/common/tests/test-general.c index 591bcd98f0..64efd14d2a 100644 --- a/clients/common/tests/test-general.c +++ b/clients/common/tests/test-general.c @@ -21,6 +21,8 @@ #include "NetworkManager.h" +#include "nm-utils/nm-hash-utils.h" + #include "nm-meta-setting-access.h" #include "nm-utils/nm-test-utils.h" @@ -77,7 +79,7 @@ test_client_meta_check (void) g_assert (info->properties_num == NM_PTRARRAY_LEN (info->properties)); if (info->properties_num) { - gs_unref_hashtable GHashTable *property_names = g_hash_table_new (g_str_hash, g_str_equal); + gs_unref_hashtable GHashTable *property_names = g_hash_table_new (nm_str_hash, g_str_equal); g_assert (info->properties); for (p = 0; p < info->properties_num; p++) { diff --git a/clients/tui/nmt-connect-connection-list.c b/clients/tui/nmt-connect-connection-list.c index afcbd35ebd..6e69a04b8f 100644 --- a/clients/tui/nmt-connect-connection-list.c +++ b/clients/tui/nmt-connect-connection-list.c @@ -30,6 +30,8 @@ #include "NetworkManager.h" +#include "nm-utils/nm-hash-utils.h" + #include "nmtui.h" #include "nmt-connect-connection-list.h" @@ -274,7 +276,7 @@ add_connections_for_aps (NmtConnectDevice *nmtdev, if (!aps->len) return; - seen_ssids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + seen_ssids = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < aps->len; i++) { ap = aps->pdata[i]; @@ -362,7 +364,7 @@ append_nmt_devices_for_virtual_devices (GSList *nmt_devices, NmtConnectConnection *nmtconn; int sort_order; - devices_by_name = g_hash_table_new (g_str_hash, g_str_equal); + devices_by_name = g_hash_table_new (nm_str_hash, g_str_equal); for (i = 0; i < connections->len; i++) { conn = connections->pdata[i]; diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 316f4acf15..b7a2faaa17 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -299,7 +299,7 @@ nm_utils_complete_generic (NMPlatform *platform, } /* Normalize */ - parameters = g_hash_table_new (g_str_hash, g_str_equal); + parameters = g_hash_table_new (nm_str_hash, g_str_equal); g_hash_table_insert (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD, default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); nm_connection_normalize (connection, parameters, NULL, NULL); diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c index 131f144cb7..0f19f9981a 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.c +++ b/src/devices/bluetooth/nm-bluez4-adapter.c @@ -25,6 +25,7 @@ #include #include "nm-dbus-interface.h" +#include "nm-utils/nm-hash-utils.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" #include "nm-core-internal.h" @@ -340,7 +341,7 @@ nm_bluez4_adapter_init (NMBluez4Adapter *self) { NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self); - priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, + priv->devices = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); } diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 8ef28b73dd..1649da248a 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -514,7 +514,7 @@ nm_bluez5_manager_init (NMBluez5Manager *self) bluez_connect (self); - priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, + priv->devices = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); c_list_init (&priv->network_servers); diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index ca30a1e8e7..90a96cda20 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -294,7 +294,7 @@ nm_device_ethernet_init (NMDeviceEthernet *self) priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); self->_priv = priv; - priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->s390_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); } static NMDeviceCapabilities diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index 4e0d7939d4..0d1c601f1e 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -351,7 +351,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call g_return_if_fail (factories_by_setting == NULL); factories_by_link = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); - factories_by_setting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) factories_list_unref); + factories_by_setting = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, (GDestroyNotify) factories_list_unref); #define _ADD_INTERNAL(get_type_fcn) \ G_STMT_START { \ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index cbb806861f..5ce96cf71a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -8939,7 +8939,7 @@ _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, #if NM_MORE_ASSERTS > 10 /* Assert that the keys are unique. */ { - gs_unref_hashtable GHashTable *check_dups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + gs_unref_hashtable GHashTable *check_dups = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); for (i = 0; argv[i]; i++) { if (!nm_g_hash_table_add (check_dups, (char *) argv[i])) @@ -13989,7 +13989,7 @@ nm_device_init (NMDevice *self) priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT; priv->unmanaged_mask = priv->unmanaged_flags; priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); - priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); + priv->ip6_saved_properties = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; priv->v4_commit_first_time = TRUE; diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index ebd5317a52..3d9c967747 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -3360,7 +3360,7 @@ nm_device_wifi_init (NMDeviceWifi *self) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); priv->mode = NM_802_11_MODE_INFRA; - priv->aps = g_hash_table_new (g_str_hash, g_str_equal); + priv->aps = g_hash_table_new (nm_str_hash, g_str_equal); } static void diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index 3dd9377699..59cd2bca5f 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -840,7 +840,7 @@ nm_modem_manager_init (NMModemManager *self) { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->modems = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); priv->main_cancellable = g_cancellable_new (); diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c index 1fe6debcba..8b3fc2e883 100644 --- a/src/devices/wwan/nm-modem-ofono.c +++ b/src/devices/wwan/nm-modem-ofono.c @@ -1147,7 +1147,7 @@ create_connect_properties (NMConnection *connection) const char *str; setting = nm_connection_get_setting_gsm (connection); - properties = g_hash_table_new (g_str_hash, g_str_equal); + properties = g_hash_table_new (nm_str_hash, g_str_equal); str = nm_setting_gsm_get_apn (setting); if (str) diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index e8ff9ff292..20ea092f0d 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -772,7 +772,7 @@ nm_dhcp_client_handle_event (gpointer unused, GVariant *value; /* Copy options */ - str_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + str_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); g_variant_iter_init (&iter, options); while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) { maybe_add_option (self, str_options, name, value); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index a82d78733b..e63e6a8696 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -739,7 +739,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (NMDedupMultiIndex *multi_idx, g_hash_table_destroy (hash); } - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); } else if (hash && strlen (*line)) add_lease_option (hash, *line); } diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index c8c90304c8..9b1a44332c 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -525,7 +525,7 @@ bound4_handle (NMDhcpSystemd *self) _LOGD ("lease available"); - options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); + options = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); ip4_config = lease_to_ip4_config (nm_dhcp_client_get_multi_idx (NM_DHCP_CLIENT (self)), iface, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)), @@ -853,7 +853,7 @@ bound6_handle (NMDhcpSystemd *self) _LOGD ("lease available"); - options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); + options = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); ip6_config = lease_to_ip6_config (nm_dhcp_client_get_multi_idx (NM_DHCP_CLIENT (self)), iface, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)), diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c index 1419b2648d..72f3119112 100644 --- a/src/dhcp/tests/test-dhcp-utils.c +++ b/src/dhcp/tests/test-dhcp-utils.c @@ -57,7 +57,7 @@ fill_table (const Option *test_options, GHashTable *table) const Option *opt; if (!table) - table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + table = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); for (opt = test_options; opt->name; opt++) g_hash_table_insert (table, (gpointer) opt->name, (gpointer) opt->value); return table; diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index b8e64ceb9d..f1aff43029 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -24,6 +24,7 @@ #include +#include "nm-utils/nm-hash-utils.h" #include "nm-setting-connection.h" #include "nm-auth-subject.h" #include "nm-auth-manager.h" @@ -131,7 +132,7 @@ nm_auth_chain_new_subject (NMAuthSubject *subject, self = g_slice_new0 (NMAuthChain); self->refcount = 1; - self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, chain_data_free); + self->data = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, chain_data_free); self->done_func = done_func; self->user_data = user_data; self->context = context ? g_object_ref (context) : NULL; diff --git a/src/nm-checkpoint-manager.c b/src/nm-checkpoint-manager.c index 7f9aa398db..033c11cc43 100644 --- a/src/nm-checkpoint-manager.c +++ b/src/nm-checkpoint-manager.c @@ -283,7 +283,7 @@ nm_checkpoint_manager_new (NMManager *manager) * of NMManager shall surpass the lifetime of the NMCheckpointManager * instance. */ self->_manager = manager; - self->checkpoints = g_hash_table_new_full (g_str_hash, g_str_equal, + self->checkpoints = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, checkpoint_destroy); return self; diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c index 04f00e899b..2dd76d590f 100644 --- a/src/nm-checkpoint.c +++ b/src/nm-checkpoint.c @@ -506,7 +506,7 @@ nm_checkpoint_new (NMManager *manager, GPtrArray *devices, guint32 rollback_time priv->flags = flags; if (NM_FLAGS_HAS (flags, NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS)) { - priv->connection_uuids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + priv->connection_uuids = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); for (con = nm_settings_get_connections (nm_settings_get (), NULL); *con; con++) { g_hash_table_add (priv->connection_uuids, g_strdup (nm_settings_connection_get_uuid (*con))); diff --git a/src/nm-config-data.c b/src/nm-config-data.c index de6f62f6d1..2487b6aa62 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -875,7 +875,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) return NULL; conf = g_malloc0 (sizeof (NMGlobalDnsConfig)); - conf->domains = g_hash_table_new_full (g_str_hash, g_str_equal, + conf->domains = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) global_dns_domain_free); strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL); @@ -1077,7 +1077,7 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error) } dns_config = g_malloc0 (sizeof (NMGlobalDnsConfig)); - dns_config->domains = g_hash_table_new_full (g_str_hash, g_str_equal, + dns_config->domains = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) global_dns_domain_free); g_variant_iter_init (&iter, variant); diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 0e903b8991..94264caa6e 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -272,7 +272,7 @@ nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, classinfo = g_slice_new (NMExportedObjectClassInfo); classinfo->skeleton_types = NULL; classinfo->methods = g_array_new (FALSE, FALSE, sizeof (NMExportedObjectDBusMethodImpl)); - classinfo->properties = g_hash_table_new (g_str_hash, g_str_equal); + classinfo->properties = g_hash_table_new (nm_str_hash, g_str_equal); g_type_set_qdata (G_TYPE_FROM_CLASS (object_class), nm_exported_object_class_info_quark (), classinfo); } @@ -579,7 +579,7 @@ _create_export_path (NMExportedObjectClass *klass) p = strchr (class_export_path, '%'); if (p) { if (G_UNLIKELY (!prefix_counters)) - prefix_counters = g_hash_table_new (g_str_hash, g_str_equal); + prefix_counters = g_hash_table_new (nm_str_hash, g_str_equal); nm_assert (p[1] == 'l'); nm_assert (p[2] == 'l'); diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 9ecfaaa704..de02ebe097 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -1358,7 +1358,7 @@ nm_fake_platform_init (NMFakePlatform *fake_platform) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (fake_platform); - priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); priv->links = g_array_new (TRUE, TRUE, sizeof (NMFakePlatformLink)); } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 3b37ca539e..c40a2c532b 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3062,7 +3062,7 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *pathid, const char * if (!priv->sysctl_get_prev_values) { _nm_logging_clear_platform_logging_cache = _nm_logging_clear_platform_logging_cache_impl; sysctl_clear_cache_list = g_slist_prepend (sysctl_clear_cache_list, platform); - priv->sysctl_get_prev_values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->sysctl_get_prev_values = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); } else prev_value = g_hash_table_lookup (priv->sysctl_get_prev_values, pathid); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index fdc8dd87a9..540059cad9 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -321,9 +321,9 @@ _dedup_multi_idx_type_init (DedupMultiIdxType *idx_type, NMPCacheIdType cache_id /*****************************************************************************/ static void -_vlan_xgress_qos_mappings_hash (NMHashState *h, - guint n_map, - const NMVlanQosMapping *map) +_vlan_xgress_qos_mappings_hash_update (guint n_map, + const NMVlanQosMapping *map, + NMHashState *h) { guint i; @@ -817,12 +817,12 @@ _vt_cmd_obj_hash_lnk_vlan (const NMPObject *obj) nm_hash_init (&h, 914932607u); nm_hash_update_uint (&h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); - _vlan_xgress_qos_mappings_hash (&h, - obj->_lnk_vlan.n_ingress_qos_map, - obj->_lnk_vlan.ingress_qos_map); - _vlan_xgress_qos_mappings_hash (&h, - obj->_lnk_vlan.n_egress_qos_map, - obj->_lnk_vlan.egress_qos_map); + _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_ingress_qos_map, + obj->_lnk_vlan.ingress_qos_map, + &h); + _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_egress_qos_map, + obj->_lnk_vlan.egress_qos_map, + &h); return nm_hash_complete (&h); } diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 137f40329f..bcd178435f 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -1559,7 +1559,7 @@ nm_agent_manager_init (NMAgentManager *self) NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); c_list_init (&priv->requests); - priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->agents = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); } static void diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 3ac42b0172..768f55f8cb 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -2776,7 +2776,7 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); - priv->seen_bssids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + priv->seen_bssids = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index d24e797044..10c160cbc8 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1885,7 +1885,7 @@ nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); /* Hold a reference to the agent manager so it stays alive; the only * other holders are NMSettingsConnection objects which are often diff --git a/src/settings/plugins/ibft/nms-ibft-plugin.c b/src/settings/plugins/ibft/nms-ibft-plugin.c index c9069dc74c..9b1f5ccd00 100644 --- a/src/settings/plugins/ibft/nms-ibft-plugin.c +++ b/src/settings/plugins/ibft/nms-ibft-plugin.c @@ -152,7 +152,7 @@ nms_ibft_plugin_init (NMSIbftPlugin *self) { NMSIbftPluginPrivate *priv = NMS_IBFT_PLUGIN_GET_PRIVATE (self); - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); } static void diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index a3092e7126..f51a760d9c 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -461,7 +461,7 @@ _paths_from_connections (GHashTable *connections) { GHashTableIter iter; NMIfcfgConnection *connection; - GHashTable *paths = g_hash_table_new (g_str_hash, g_str_equal); + GHashTable *paths = g_hash_table_new (nm_str_hash, g_str_equal); g_hash_table_iter_init (&iter, connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { @@ -991,7 +991,7 @@ settings_plugin_ifcfg_init (SettingsPluginIfcfg *plugin) { SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE ((SettingsPluginIfcfg *) plugin); - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); } static void diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index d939d0ee6b..87fefd8db6 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -882,7 +882,7 @@ svGetKeys (shvarFile *s) /* we don't clone the keys. The keys are only valid * until @s gets modified. */ if (!keys) - keys = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + keys = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); g_hash_table_add (keys, (gpointer) line->key); } } diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-parser.c b/src/settings/plugins/ifnet/nms-ifnet-net-parser.c index 0007f9cdd5..d3e4721919 100644 --- a/src/settings/plugins/ifnet/nms-ifnet-net-parser.c +++ b/src/settings/plugins/ifnet/nms-ifnet-net-parser.c @@ -58,7 +58,7 @@ add_new_connection_config (const gchar * type, const gchar * name) /* Return existing connection */ if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL) return new_conn; - new_conn = g_hash_table_new (g_str_hash, g_str_equal); + new_conn = g_hash_table_new (nm_str_hash, g_str_equal); new_name = g_strdup (name); g_hash_table_insert (new_conn, g_strdup ("name"), new_name); g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type)); @@ -302,8 +302,8 @@ ifnet_init (gchar * config_file) net_parser_data_changed = FALSE; - conn_table = g_hash_table_new (g_str_hash, g_str_equal); - global_settings_table = g_hash_table_new (g_str_hash, g_str_equal); + conn_table = g_hash_table_new (nm_str_hash, g_str_equal); + global_settings_table = g_hash_table_new (nm_str_hash, g_str_equal); functions_list = NULL; if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR)) diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.c b/src/settings/plugins/ifnet/nms-ifnet-plugin.c index faac258768..802988c19a 100644 --- a/src/settings/plugins/ifnet/nms-ifnet-plugin.c +++ b/src/settings/plugins/ifnet/nms-ifnet-plugin.c @@ -226,7 +226,7 @@ reload_connections (NMSettingsPlugin *config) NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH, FALSE); - new_connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + new_connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); /* Reread on-disk data and refresh in-memory connections from it */ conn_names = ifnet_get_connection_names (); @@ -444,7 +444,7 @@ init (NMSettingsPlugin *config) nm_log_info (LOGD_SETTINGS, "Initializing!"); - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); priv->unmanaged_well_known = !is_managed_plugin (); nm_log_info (LOGD_SETTINGS, "management mode: %s", priv->unmanaged_well_known ? "unmanaged" : "managed"); diff --git a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c index 61e4da7cf4..2b62e88659 100644 --- a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c +++ b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c @@ -26,6 +26,7 @@ #include #include +#include "nm-utils/nm-hash-utils.h" #include "settings/nm-settings-plugin.h" #include "nms-ifnet-net-parser.h" @@ -270,8 +271,8 @@ wpa_parser_init (const char *wpa_supplicant_conf) gboolean complete = FALSE; wpa_parser_data_changed = FALSE; - wsec_table = g_hash_table_new (g_str_hash, g_str_equal); - wsec_global_table = g_hash_table_new (g_str_hash, g_str_equal); + wsec_table = g_hash_table_new (nm_str_hash, g_str_equal); + wsec_global_table = g_hash_table_new (nm_str_hash, g_str_equal); if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR)) channel = @@ -292,7 +293,7 @@ wpa_parser_init (const char *wpa_supplicant_conf) continue; } else { GHashTable *network = - g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_new (nm_str_hash, g_str_equal); do { gchar *quote_start, *quote_end = NULL, *comment; @@ -512,7 +513,7 @@ wpa_add_security (const char *ssid) return TRUE; else { GHashTable *security = - g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_new (nm_str_hash, g_str_equal); gchar *ssid_i; nm_log_info (LOGD_SETTINGS, "Adding security for %s", ssid); diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 189b6e69cb..b718a3f831 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -338,16 +338,16 @@ init (NMSettingsPlugin *config) const char *block_name; NMIfupdownConnection *connection; - auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); + auto_ifaces = g_hash_table_new (nm_str_hash, g_str_equal); if(!priv->connections) - priv->connections = g_hash_table_new (g_str_hash, g_str_equal); + priv->connections = g_hash_table_new (nm_str_hash, g_str_equal); if(!priv->kernel_ifaces) - priv->kernel_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _udev_device_unref); + priv->kernel_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, _udev_device_unref); if(!priv->eni_ifaces) - priv->eni_ifaces = g_hash_table_new (g_str_hash, g_str_equal); + priv->eni_ifaces = g_hash_table_new (nm_str_hash, g_str_equal); nm_log_info (LOGD_SETTINGS, "init!"); diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c index 4af80142e1..ee4db32048 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -378,7 +378,7 @@ _paths_from_connections (GHashTable *connections) { GHashTableIter iter; NMSKeyfileConnection *connection; - GHashTable *paths = g_hash_table_new (g_str_hash, g_str_equal); + GHashTable *paths = g_hash_table_new (nm_str_hash, g_str_equal); g_hash_table_iter_init (&iter, connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { @@ -588,7 +588,7 @@ nms_keyfile_plugin_init (NMSKeyfilePlugin *plugin) NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (plugin); priv->config = g_object_ref (nm_config_get ()); - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); } static void diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 71d2f2cc4a..16e7851a08 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -88,11 +88,11 @@ nm_supplicant_config_init (NMSupplicantConfig * self) { NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); - priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, + priv->config = g_hash_table_new_full (nm_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) config_option_free); - priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal, + priv->blobs = g_hash_table_new_full (nm_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) blob_free); diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index 0c6c3f36d1..44f887cb61 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -1912,7 +1912,7 @@ nm_supplicant_interface_init (NMSupplicantInterface * self) NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT; - priv->bss_proxies = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, bss_data_destroy); + priv->bss_proxies = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, bss_data_destroy); } NMSupplicantInterface * diff --git a/src/vpn/nm-vpn-manager.c b/src/vpn/nm-vpn-manager.c index 8e708d125c..d063916873 100644 --- a/src/vpn/nm-vpn-manager.c +++ b/src/vpn/nm-vpn-manager.c @@ -255,7 +255,7 @@ nm_vpn_manager_init (NMVpnManager *self) try_add_plugin (self, info->data); g_slist_free_full (infos, g_object_unref); - priv->active_services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + priv->active_services = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); } static void From ee76b0979ff0b3eef77168af0cbbdb4f1a9b843a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 13 Oct 2017 17:16:23 +0200 Subject: [PATCH 08/12] all: use siphash24 for hashing siphash24() is wildly used by projects nowadays. It's certainly slower then our djb hashing that we used before. But quite likely it's fast enough for us, given how wildly it is used. I think it would be hard to profile NetworkManager to show that the performance of hash tables is the issue, be it with djb or siphash24. Certainly with siphash24() it's much harder to exploit the hashing algorithm to cause worst case hash operations (provided that the seed is kept private). Does this better resistance against a denial of service matter for us? Probably not, but let's better be safe then sorry. Note that systemd's implementation uses a different seed for each hash table (at least, after the hash table grows to a certain size). We don't do that and use only one global seed. --- Makefile.am | 11 +- libnm-core/tests/test-general.c | 44 ++---- shared/nm-utils/nm-hash-utils.c | 80 ++++++++--- shared/nm-utils/nm-hash-utils.h | 113 +++++++-------- .../src/basic => shared/nm-utils}/siphash24.c | 5 +- .../src/basic => shared/nm-utils}/siphash24.h | 0 src/devices/nm-lldp-listener.c | 4 +- src/platform/nm-platform.c | 11 +- src/platform/nmp-object.c | 2 +- src/systemd/src/basic/unaligned.h | 129 ------------------ 10 files changed, 147 insertions(+), 252 deletions(-) rename {src/systemd/src/basic => shared/nm-utils}/siphash24.c (99%) rename {src/systemd/src/basic => shared/nm-utils}/siphash24.h (100%) delete mode 100644 src/systemd/src/basic/unaligned.h diff --git a/Makefile.am b/Makefile.am index ee8e4f079a..1c26e00ac4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -425,6 +425,7 @@ libnm_core_lib_h_priv = \ shared/nm-utils/nm-shared-utils.h \ shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-udev-utils.h \ + shared/nm-utils/siphash24.h \ shared/nm-meta-setting.h \ libnm-core/crypto.h \ libnm-core/nm-connection-private.h \ @@ -443,6 +444,7 @@ libnm_core_lib_c_real = \ shared/nm-utils/nm-shared-utils.c \ shared/nm-utils/nm-random-utils.c \ shared/nm-utils/nm-udev-utils.c \ + shared/nm-utils/siphash24.c \ shared/nm-meta-setting.c \ libnm-core/crypto.c \ libnm-core/nm-connection.c \ @@ -1127,6 +1129,7 @@ src_libsystemd_nm_la_cppflags = \ -I$(builddir)/libnm-core \ -I$(srcdir)/src \ -I$(srcdir)/src/systemd/sd-adapt \ + -I$(srcdir)/shared/nm-utils \ -I$(srcdir)/src/systemd/src/systemd \ -I$(srcdir)/src/systemd/src/basic \ -I$(srcdir)/src/systemd/src/shared \ @@ -1213,8 +1216,6 @@ src_libsystemd_nm_la_SOURCES = \ src/systemd/src/basic/refcnt.h \ src/systemd/src/basic/set.h \ src/systemd/src/basic/signal-util.h \ - src/systemd/src/basic/siphash24.c \ - src/systemd/src/basic/siphash24.h \ src/systemd/src/basic/socket-util.c \ src/systemd/src/basic/socket-util.h \ src/systemd/src/basic/sparse-endian.h \ @@ -1228,7 +1229,6 @@ src_libsystemd_nm_la_SOURCES = \ src/systemd/src/basic/time-util.c \ src/systemd/src/basic/time-util.h \ src/systemd/src/basic/umask-util.h \ - src/systemd/src/basic/unaligned.h \ src/systemd/src/basic/utf8.c \ src/systemd/src/basic/utf8.h \ src/systemd/src/basic/util.c \ @@ -3009,6 +3009,9 @@ $(src_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(src_tests_test_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) src_tests_test_systemd_CPPFLAGS = $(src_libsystemd_nm_la_cppflags) +src_tests_test_systemd_SOURCES = \ + shared/nm-utils/siphash24.c \ + src/tests/test-systemd.c src_tests_test_systemd_LDADD = \ src/libsystemd-nm.la \ $(src_libsystemd_nm_la_libadd) @@ -3200,6 +3203,8 @@ clients_common_libnmc_base_la_SOURCES = \ shared/nm-utils/nm-random-utils.h \ shared/nm-utils/nm-shared-utils.c \ shared/nm-utils/nm-shared-utils.h \ + shared/nm-utils/siphash24.c \ + shared/nm-utils/siphash24.h \ \ clients/common/nm-secret-agent-simple.c \ clients/common/nm-secret-agent-simple.h \ diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 31a445971e..9bf567154a 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -87,18 +87,17 @@ _test_hash_str (const char *str) const guint SEED = 10; nm_hash_init (&h, SEED); - nm_hash_update_str (&h, str); + nm_hash_update_str0 (&h, str); v = nm_hash_complete (&h); - { - /* assert that hashing a string and a buffer yields the - * same result. - * - * I think that is a desirable property. */ - nm_hash_init (&h, SEED); - nm_hash_update_mem (&h, str, str ? strlen (str) : 0); - v2 = nm_hash_complete (&h); - } + /* assert that hashing a string and a buffer yields the + * same result. + * + * I think that is a desirable property. */ + nm_hash_init (&h, SEED); + nm_hash_update_mem (&h, str, strlen (str)); + v2 = nm_hash_complete (&h); + g_assert (v == v2); return v; } @@ -106,35 +105,10 @@ _test_hash_str (const char *str) static void test_nm_hash (void) { - NMHashState h; - _test_hash_str (""); _test_hash_str ("a"); _test_hash_str ("aa"); _test_hash_str ("diceros bicornis longipes"); - - memset (&h, 0, sizeof (h)); - g_assert_cmpint (nm_hash_complete (&h), ==, 1396707757u); - - /* note how two different string still always hash the same, - * although we use a global seed that we initialize each time - * differently. - * - * The aim would be that two collisions depend on the seed value, - * which they currently don't. */ - g_assert_cmpint (nm_hash_str ("BA"), ==, nm_hash_str ("Ab")); - - /* with the current hasing algorighm, once we know two words that hash - * the same, we can trivally find more collions by concatenating - * them (which is bad). */ - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbAbAb")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbAbBA")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbBAAb")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("AbBABA")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BAAbAb")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BAAbBA")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BABAAb")); - g_assert_cmpint (nm_hash_str ("BABABA"), ==, nm_hash_str ("BABABA")); } /*****************************************************************************/ diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c index 4a450218e7..afcc846c54 100644 --- a/shared/nm-utils/nm-hash-utils.c +++ b/shared/nm-utils/nm-hash-utils.c @@ -23,33 +23,59 @@ #include "nm-hash-utils.h" +#include + #include "nm-shared-utils.h" #include "nm-random-utils.h" /*****************************************************************************/ +#define HASH_KEY_SIZE 16u +#define HASH_KEY_SIZE_GUINT ((HASH_KEY_SIZE + sizeof (guint) - 1) / sizeof (guint)) + +G_STATIC_ASSERT (sizeof (guint) * HASH_KEY_SIZE_GUINT >= HASH_KEY_SIZE); + +static const guint8 * +_get_hash_key (void) +{ + static const guint8 *volatile global_seed = NULL; + const guint8 *g; + + g = global_seed; + if (G_UNLIKELY (g == NULL)) { + /* the returned hash is aligned to guin64, hence, it is save + * to use it as guint* or guint64* pointer. */ + static union { + guint8 v8[HASH_KEY_SIZE]; + } g_arr _nm_alignas (guint64); + static gsize g_lock; + + if (g_once_init_enter (&g_lock)) { + nm_utils_random_bytes (g_arr.v8, sizeof (g_arr.v8)); + g_atomic_pointer_compare_and_exchange (&global_seed, NULL, g_arr.v8); + g = g_arr.v8; + g_once_init_leave (&g_lock, 1); + } else { + g = global_seed; + nm_assert (g); + } + } + + return g; +} + void nm_hash_init (NMHashState *state, guint static_seed) { - static volatile guint global_seed = 0; - guint g, s; + const guint8 *g; + guint seed[HASH_KEY_SIZE_GUINT]; nm_assert (state); - /* we xor @seed with a random @global_seed. This is to make the hashing behavior - * less predictable and harder to exploit collisions. */ - g = global_seed; - if (G_UNLIKELY (g == 0)) { - nm_utils_random_bytes (&s, sizeof (s)); - if (s == 0) - s = 42; - g_atomic_int_compare_and_exchange ((int *) &global_seed, 0, s); - g = global_seed; - nm_assert (g); - } - - s = g ^ static_seed; - state->hash = s; + g = _get_hash_key (); + memcpy (seed, g, HASH_KEY_SIZE); + seed[0] ^= static_seed; + siphash24_init (&state->_state, (const guint8 *) seed); } guint @@ -57,8 +83,11 @@ nm_hash_str (const char *str) { NMHashState h; - nm_hash_init (&h, 1867854211u); - nm_hash_update_str (&h, str); + if (str) { + nm_hash_init (&h, 1867854211u); + nm_hash_update_str (&h, str); + } else + nm_hash_init (&h, 842995561u); return nm_hash_complete (&h); } @@ -68,6 +97,21 @@ nm_str_hash (gconstpointer str) return nm_hash_str (str); } +guint +nm_hash_ptr (gconstpointer ptr) +{ + guint h; + + h = ((const guint *) _get_hash_key ())[0]; + + if (sizeof (ptr) <= sizeof (guint)) + h = h ^ ((guint) ((uintptr_t) ptr)); + else + h = h ^ ((guint) (((uintptr_t) ptr) >> 32)) ^ ((guint) ((uintptr_t) ptr)); + + return h ?: 2907677551u; +} + guint nm_direct_hash (gconstpointer ptr) { diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index 55a832ef14..45afa9ae32 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -22,10 +22,10 @@ #ifndef __NM_HASH_UTILS_H__ #define __NM_HASH_UTILS_H__ -#include +#include "siphash24.h" typedef struct { - guint hash; + struct siphash _state; } NMHashState; void nm_hash_init (NMHashState *state, guint static_seed); @@ -33,93 +33,94 @@ void nm_hash_init (NMHashState *state, guint static_seed); static inline guint nm_hash_complete (NMHashState *state) { + guint64 h; + nm_assert (state); + + h = siphash24_finalize (&state->_state); + /* we don't ever want to return a zero hash. * * NMPObject requires that in _idx_obj_part(), and it's just a good idea. */ - return state->hash ?: 1396707757u; + return (((guint) (h >> 32)) ^ ((guint) h)) ?: 1396707757u; +} + +static inline void +nm_hash_update (NMHashState *state, const void *ptr, gsize n) +{ + nm_assert (state); + nm_assert (ptr); + nm_assert (n > 0); + + siphash24_compress (ptr, n, &state->_state); } static inline void nm_hash_update_uint (NMHashState *state, guint val) { - guint h; - - nm_assert (state); - - h = state->hash; - h = (h << 5) + h + val; - state->hash = h; + nm_hash_update (state, &val, sizeof (val)); } static inline void nm_hash_update_uint64 (NMHashState *state, guint64 val) { - guint h; - - nm_assert (state); - - h = state->hash; - h = (h << 5) + h + ((guint) val); - h = (h << 5) + h + ((guint) (val >> 32)); - state->hash = h; + nm_hash_update (state, &val, sizeof (val)); } static inline void nm_hash_update_ptr (NMHashState *state, gconstpointer ptr) { - if (sizeof (ptr) <= sizeof (guint)) - nm_hash_update_uint (state, ((guint) ((uintptr_t) ptr))); - else - nm_hash_update_uint64 (state, (guint64) ((uintptr_t) ptr)); + nm_hash_update (state, &ptr, sizeof (ptr)); } static inline void nm_hash_update_mem (NMHashState *state, const void *ptr, gsize n) { - gsize i; - guint h; + /* This also hashes the length of the data. That means, + * hashing two consecutive binary fields (of arbitrary + * length), will hash differently. That is, + * [[1,1], []] differs from [[1],[1]]. + * + * If you have a constant length (sizeof), use nm_hash_update() + * instead. */ + nm_hash_update (state, &n, sizeof (n)); + if (n > 0) + siphash24_compress (ptr, n, &state->_state); +} - nm_assert (state); +static inline void +nm_hash_update_str0 (NMHashState *state, const char *str) +{ + if (str) + nm_hash_update_mem (state, str, strlen (str)); + else { + gsize n = G_MAXSIZE; - /* use the same hash seed as nm_hash_update_str(). - * That way, nm_hash_update_str(&h, s) is identical to - * nm_hash_update_mem(&h, s, strlen(s)). */ - h = state->hash; - for (i = 0; i < n; i++) - h = (h << 5) + h + ((guint) ((const guint8 *) ptr)[i]); - h = (h << 5) + h + 1774132687u; - state->hash = h; + nm_hash_update (state, &n, sizeof (n)); + } } static inline void nm_hash_update_str (NMHashState *state, const char *str) { - const guint8 *p = (const guint8 *) str; - guint8 c; - guint h; - - nm_assert (state); - - /* Note that NULL hashes differently from "". */ - h = state->hash; - if (str) { - while ((c = *p++)) - h = (h << 5) + h + ((guint) c); - h = (h << 5) + h + 1774132687u; - } else - h = (h << 5) + h + 2967906233u; - state->hash = h; + nm_assert (str); + nm_hash_update (state, str, strlen (str) + 1); } -static inline guint -nm_hash_ptr (gconstpointer ptr) -{ - if (sizeof (ptr) <= sizeof (guint)) - return (guint) ((uintptr_t) ptr); - else - return ((guint) (((uintptr_t) ptr) >> 32)) ^ ((guint) ((uintptr_t) ptr)); -} +#if _NM_CC_SUPPORT_GENERIC +/* Like nm_hash_update_str(), but restricted to arrays only. nm_hash_update_str() only works + * with a @str argument that cannot be NULL. If you have a string pointer, that is never NULL, use + * nm_hash_update() instead. */ +#define nm_hash_update_strarr(state, str) \ + (_Generic (&(str), \ + const char (*) [sizeof (str)]: nm_hash_update_str ((state), (str)), \ + char (*) [sizeof (str)]: nm_hash_update_str ((state), (str))) \ + ) +#else +#define nm_hash_update_strarr(state, str) nm_hash_update_str ((state), (str)) +#endif + +guint nm_hash_ptr (gconstpointer ptr); guint nm_direct_hash (gconstpointer str); guint nm_hash_str (const char *str); diff --git a/src/systemd/src/basic/siphash24.c b/shared/nm-utils/siphash24.c similarity index 99% rename from src/systemd/src/basic/siphash24.c rename to shared/nm-utils/siphash24.c index e4b1cb1081..3a5a635d28 100644 --- a/src/systemd/src/basic/siphash24.c +++ b/shared/nm-utils/siphash24.c @@ -17,11 +17,12 @@ coding style) */ -#include "nm-sd-adapt.h" +#include "nm-default.h" + +#define assert(cond) nm_assert (cond) #include -#include "macro.h" #include "siphash24.h" #include "unaligned.h" diff --git a/src/systemd/src/basic/siphash24.h b/shared/nm-utils/siphash24.h similarity index 100% rename from src/systemd/src/basic/siphash24.h rename to shared/nm-utils/siphash24.h diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index 3cf6a209ec..2431f909e8 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -277,8 +277,8 @@ lldp_neighbor_id_hash (gconstpointer ptr) NMHashState h; nm_hash_init (&h, 23423423u); - nm_hash_update_str (&h, neigh->chassis_id); - nm_hash_update_str (&h, neigh->port_id); + nm_hash_update_str0 (&h, neigh->chassis_id); + nm_hash_update_str0 (&h, neigh->port_id); nm_hash_update_uint (&h, neigh->chassis_id_type); nm_hash_update_uint (&h, neigh->port_id_type); return nm_hash_complete (&h); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 60b1a5aa17..df87c85038 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5131,7 +5131,7 @@ nm_platform_link_hash (const NMPlatformLink *obj) nm_hash_init (&h, 99413953u); nm_hash_update_uint (&h, obj->ifindex); nm_hash_update_uint (&h, obj->type); - nm_hash_update_str (&h, obj->name); + nm_hash_update_strarr (&h, obj->name); nm_hash_update_uint (&h, obj->master); nm_hash_update_uint (&h, obj->parent); nm_hash_update_uint (&h, obj->n_ifi_flags); @@ -5141,8 +5141,8 @@ nm_platform_link_hash (const NMPlatformLink *obj) nm_hash_update_uint (&h, obj->arptype); nm_hash_update_uint (&h, obj->addr.len); nm_hash_update_uint (&h, obj->inet6_addr_gen_mode_inv); - nm_hash_update_str (&h, obj->kind); - nm_hash_update_str (&h, obj->driver); + nm_hash_update_str0 (&h, obj->kind); + nm_hash_update_str0 (&h, obj->driver); nm_hash_update_mem (&h, obj->addr.data, obj->addr.len); nm_hash_update_mem (&h, &obj->inet6_token, sizeof (obj->inet6_token)); nm_hash_update_uint (&h, obj->rx_packets); @@ -5223,8 +5223,7 @@ nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj) nm_hash_init (&h, 1748638583u); nm_hash_update_uint (&h, obj->p_key); - if (obj->mode) - nm_hash_update_str (&h, obj->mode); + nm_hash_update_str0 (&h, obj->mode); return nm_hash_complete (&h); } @@ -5481,7 +5480,7 @@ nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj) nm_hash_update_uint (&h, obj->lifetime); nm_hash_update_uint (&h, obj->preferred); nm_hash_update_uint (&h, obj->n_ifa_flags); - nm_hash_update_str (&h, obj->label); + nm_hash_update_strarr (&h, obj->label); } return nm_hash_complete (&h); } diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 540059cad9..731c81f0f2 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -186,7 +186,7 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, /* we request a hash from obj_a. Hash the relevant parts. */ nm_hash_init (&h, 2126752699u); nm_hash_update_uint (&h, idx_type->cache_id_type); - nm_hash_update_str (&h, obj_a->link.name); + nm_hash_update_strarr (&h, obj_a->link.name); return _HASH_NON_ZERO (&h); } /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ diff --git a/src/systemd/src/basic/unaligned.h b/src/systemd/src/basic/unaligned.h deleted file mode 100644 index 7c847a3ccb..0000000000 --- a/src/systemd/src/basic/unaligned.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include -#include - -/* BE */ - -static inline uint16_t unaligned_read_be16(const void *_u) { - const uint8_t *u = _u; - - return (((uint16_t) u[0]) << 8) | - ((uint16_t) u[1]); -} - -static inline uint32_t unaligned_read_be32(const void *_u) { - const uint8_t *u = _u; - - return (((uint32_t) unaligned_read_be16(u)) << 16) | - ((uint32_t) unaligned_read_be16(u + 2)); -} - -static inline uint64_t unaligned_read_be64(const void *_u) { - const uint8_t *u = _u; - - return (((uint64_t) unaligned_read_be32(u)) << 32) | - ((uint64_t) unaligned_read_be32(u + 4)); -} - -static inline void unaligned_write_be16(void *_u, uint16_t a) { - uint8_t *u = _u; - - u[0] = (uint8_t) (a >> 8); - u[1] = (uint8_t) a; -} - -static inline void unaligned_write_be32(void *_u, uint32_t a) { - uint8_t *u = _u; - - unaligned_write_be16(u, (uint16_t) (a >> 16)); - unaligned_write_be16(u + 2, (uint16_t) a); -} - -static inline void unaligned_write_be64(void *_u, uint64_t a) { - uint8_t *u = _u; - - unaligned_write_be32(u, (uint32_t) (a >> 32)); - unaligned_write_be32(u + 4, (uint32_t) a); -} - -/* LE */ - -static inline uint16_t unaligned_read_le16(const void *_u) { - const uint8_t *u = _u; - - return (((uint16_t) u[1]) << 8) | - ((uint16_t) u[0]); -} - -static inline uint32_t unaligned_read_le32(const void *_u) { - const uint8_t *u = _u; - - return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | - ((uint32_t) unaligned_read_le16(u)); -} - -static inline uint64_t unaligned_read_le64(const void *_u) { - const uint8_t *u = _u; - - return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | - ((uint64_t) unaligned_read_le32(u)); -} - -static inline void unaligned_write_le16(void *_u, uint16_t a) { - uint8_t *u = _u; - - u[0] = (uint8_t) a; - u[1] = (uint8_t) (a >> 8); -} - -static inline void unaligned_write_le32(void *_u, uint32_t a) { - uint8_t *u = _u; - - unaligned_write_le16(u, (uint16_t) a); - unaligned_write_le16(u + 2, (uint16_t) (a >> 16)); -} - -static inline void unaligned_write_le64(void *_u, uint64_t a) { - uint8_t *u = _u; - - unaligned_write_le32(u, (uint32_t) a); - unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); -} - -#if __BYTE_ORDER == __BIG_ENDIAN -#define unaligned_read_ne16 unaligned_read_be16 -#define unaligned_read_ne32 unaligned_read_be32 -#define unaligned_read_ne64 unaligned_read_be64 - -#define unaligned_write_ne16 unaligned_write_be16 -#define unaligned_write_ne32 unaligned_write_be32 -#define unaligned_write_ne64 unaligned_write_be64 -#else -#define unaligned_read_ne16 unaligned_read_le16 -#define unaligned_read_ne32 unaligned_read_le32 -#define unaligned_read_ne64 unaligned_read_le64 - -#define unaligned_write_ne16 unaligned_write_le16 -#define unaligned_write_ne32 unaligned_write_le32 -#define unaligned_write_ne64 unaligned_write_le64 -#endif From 2f56de7492563c75fdbb480aa6f06c1442c867b5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 16 Oct 2017 12:38:16 +0200 Subject: [PATCH 09/12] all: add helper functions for nm_hash_update*() By using a macro, we don't cast all the types to guint. Instead, we use their native types directly. Hence, we don't need nm_hash_update_uint64() nor nm_hash_update_ptr(). Also, for types smaller then guint like char, we save hashing the all zero bytes. --- libnm-core/nm-utils.c | 17 +- libnm-core/tests/test-general.c | 83 +++++++ shared/nm-utils/nm-dedup-multi.c | 6 +- shared/nm-utils/nm-hash-utils.h | 107 +++++++-- src/devices/nm-device.c | 4 +- src/devices/nm-lldp-listener.c | 5 +- src/nm-core-utils.c | 12 -- src/nm-core-utils.h | 9 +- src/platform/nm-platform.c | 357 ++++++++++++++++--------------- src/platform/nmp-object.c | 84 ++++---- 10 files changed, 425 insertions(+), 259 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 4ac41944c8..b3c3fc5d68 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4006,7 +4006,7 @@ guint _nm_utils_strstrdictkey_hash (gconstpointer a) { const NMUtilsStrStrDictKey *k = a; - const signed char *p; + const char *p; NMHashState h; nm_hash_init (&h, 76642997u); @@ -4014,17 +4014,18 @@ _nm_utils_strstrdictkey_hash (gconstpointer a) if (((int) k->type) & ~STRSTRDICTKEY_ALL_SET) g_return_val_if_reached (0); - nm_hash_update_uint (&h, k->type); + nm_hash_update_val (&h, k->type); if (k->type & STRSTRDICTKEY_ALL_SET) { - p = (void *) k->data; - for (; *p != '\0'; p++) - nm_hash_update_uint (&h, *p); + gsize n; + + n = 0; + p = strchr (k->data, '\0'); if (k->type == STRSTRDICTKEY_ALL_SET) { /* the key contains two strings. Continue... */ - nm_hash_update_uint (&h, '\0'); - for (p++; *p != '\0'; p++) - nm_hash_update_uint (&h, *p); + p = strchr (p + 1, '\0'); } + if (p != k->data) + nm_hash_update (&h, k->data, p - k->data); } } return nm_hash_complete (&h); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 9bf567154a..1f4aa21702 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -79,6 +79,41 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int)); /*****************************************************************************/ +typedef struct _nm_packed { + int v0; + char v1; + double v2; + guint8 v3; +} TestHashStruct; + +static void +_test_hash_struct (int v0, char v1, double v2, guint8 v3) +{ + const TestHashStruct s = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + }; + NMHashState h; + guint hh; + + nm_hash_init (&h, 100); + nm_hash_update (&h, &s, sizeof (s)); + hh = nm_hash_complete (&h); + + nm_hash_init (&h, 100); + nm_hash_update_val (&h, v0); + nm_hash_update_val (&h, v1); + nm_hash_update_val (&h, v2); + nm_hash_update_val (&h, v3); + g_assert_cmpint (hh, ==, nm_hash_complete (&h)); + + nm_hash_init (&h, 100); + nm_hash_update_vals (&h, v0, v1, v2, v3); + g_assert_cmpint (hh, ==, nm_hash_complete (&h)); +} + static guint _test_hash_str (const char *str) { @@ -102,6 +137,34 @@ _test_hash_str (const char *str) return v; } +#define _test_hash_vals(type, ...) \ + G_STMT_START { \ + NMHashState h0, h1, h2, h3; \ + const type v[] = { __VA_ARGS__ }; \ + guint h; \ + guint i; \ + \ + nm_hash_init (&h0, 10); \ + nm_hash_init (&h1, 10); \ + nm_hash_init (&h2, 10); \ + nm_hash_init (&h3, 10); \ + \ + /* assert that it doesn't matter, whether we hash the values individually, + * or all at once, or via the convenience macros nm_hash_update_val() + * and nm_hash_update_vals(). */ \ + for (i = 0; i < G_N_ELEMENTS (v); i++) { \ + nm_hash_update (&h0, &v[i], sizeof (type)); \ + nm_hash_update_val (&h1, v[i]); \ + } \ + nm_hash_update_vals (&h2, __VA_ARGS__); \ + nm_hash_update (&h3, v, sizeof (v)); \ + \ + h = nm_hash_complete (&h0); \ + g_assert_cmpint (h, ==, nm_hash_complete (&h1)); \ + g_assert_cmpint (h, ==, nm_hash_complete (&h2)); \ + g_assert_cmpint (h, ==, nm_hash_complete (&h3)); \ + } G_STMT_END + static void test_nm_hash (void) { @@ -109,6 +172,26 @@ test_nm_hash (void) _test_hash_str ("a"); _test_hash_str ("aa"); _test_hash_str ("diceros bicornis longipes"); + + /* assert that nm_hash_update_vals() is the same as calling nm_hash_update_val() multiple times. */ + _test_hash_vals (int, 1); + _test_hash_vals (int, 1, 2); + _test_hash_vals (int, 1, 2, 3); + _test_hash_vals (int, 1, 2, 3, 4); + _test_hash_vals (long, 1l); + _test_hash_vals (long, 1l, 2l, 3l, 4l, 5l); + + _test_hash_struct (10, 'a', 5.4, 7); + _test_hash_struct (-10, '\0', -5.4e49, 255); + + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint8, 1, 0), ==, 0x002); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint8, 1, 1), ==, 0x003); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint8, 1, 1, 0, 0, 0, 0), ==, 0x030); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint8, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint8, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint16, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint16, 0, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint (NM_HASH_COMBINE_BOOLS (guint16, 1, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x131); } /*****************************************************************************/ diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c index b1872d4766..fb57f6c1ad 100644 --- a/shared/nm-utils/nm-dedup-multi.c +++ b/shared/nm-utils/nm-dedup-multi.c @@ -183,13 +183,13 @@ _dict_idx_entries_hash (const NMDedupMultiEntry *entry) nm_hash_init (&h, 1914869417u); if (idx_type->klass->idx_obj_partition_hash) { nm_assert (obj); - nm_hash_update_uint (&h, idx_type->klass->idx_obj_partition_hash (idx_type, obj)); + nm_hash_update_val (&h, idx_type->klass->idx_obj_partition_hash (idx_type, obj)); } if (!lookup_head) - nm_hash_update_uint (&h, idx_type->klass->idx_obj_id_hash (idx_type, obj)); + nm_hash_update_val (&h, idx_type->klass->idx_obj_id_hash (idx_type, obj)); - nm_hash_update_ptr (&h, idx_type); + nm_hash_update_val (&h, idx_type); return nm_hash_complete (&h); } diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index 45afa9ae32..276e1ebe02 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -23,10 +23,13 @@ #define __NM_HASH_UTILS_H__ #include "siphash24.h" +#include "nm-macros-internal.h" -typedef struct { +struct _NMHashState { struct siphash _state; -} NMHashState; +}; + +typedef struct _NMHashState NMHashState; void nm_hash_init (NMHashState *state, guint static_seed); @@ -55,23 +58,101 @@ nm_hash_update (NMHashState *state, const void *ptr, gsize n) siphash24_compress (ptr, n, &state->_state); } +#define nm_hash_update_val(state, val) \ + G_STMT_START { \ + typeof (val) _val = (val); \ + \ + nm_hash_update ((state), &_val, sizeof (_val)); \ + } G_STMT_END + static inline void -nm_hash_update_uint (NMHashState *state, guint val) +nm_hash_update_bool (NMHashState *state, bool val) { nm_hash_update (state, &val, sizeof (val)); } -static inline void -nm_hash_update_uint64 (NMHashState *state, guint64 val) -{ - nm_hash_update (state, &val, sizeof (val)); -} +#define _NM_HASH_COMBINE_BOOLS_x_1( t, y) ((y) ? ((t) (1ull << 0)) : ((t) 0ull)) +#define _NM_HASH_COMBINE_BOOLS_x_2( t, y, ...) ((y) ? ((t) (1ull << 1)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_1 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_3( t, y, ...) ((y) ? ((t) (1ull << 2)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_2 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_4( t, y, ...) ((y) ? ((t) (1ull << 3)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_3 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_5( t, y, ...) ((y) ? ((t) (1ull << 4)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_4 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_6( t, y, ...) ((y) ? ((t) (1ull << 5)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_5 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_7( t, y, ...) ((y) ? ((t) (1ull << 6)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_6 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_8( t, y, ...) ((y) ? ((t) (1ull << 7)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_7 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_9( t, y, ...) ((y) ? ((t) (1ull << 8)) : ((t) 0ull)) | (G_STATIC_ASSERT_EXPR (sizeof (t) >= 2), (_NM_HASH_COMBINE_BOOLS_x_8 (t, __VA_ARGS__))) +#define _NM_HASH_COMBINE_BOOLS_x_10(t, y, ...) ((y) ? ((t) (1ull << 9)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_9 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_11(t, y, ...) ((y) ? ((t) (1ull << 10)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_10 (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_n2(t, n, ...) _NM_HASH_COMBINE_BOOLS_x_##n (t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_n(t, n, ...) _NM_HASH_COMBINE_BOOLS_n2(t, n, __VA_ARGS__) -static inline void -nm_hash_update_ptr (NMHashState *state, gconstpointer ptr) -{ - nm_hash_update (state, &ptr, sizeof (ptr)); -} +#define NM_HASH_COMBINE_BOOLS(type, ...) ((type) (_NM_HASH_COMBINE_BOOLS_n(type, NM_NARG (__VA_ARGS__), __VA_ARGS__))) + +#define nm_hash_update_bools(state, ...) \ + nm_hash_update_val (state, NM_HASH_COMBINE_BOOLS (guint8, __VA_ARGS__)) + +#define _NM_HASH_COMBINE_VALS_typ_x_1( y) typeof (y) _v1; +#define _NM_HASH_COMBINE_VALS_typ_x_2( y, ...) typeof (y) _v2; _NM_HASH_COMBINE_VALS_typ_x_1 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_3( y, ...) typeof (y) _v3; _NM_HASH_COMBINE_VALS_typ_x_2 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_4( y, ...) typeof (y) _v4; _NM_HASH_COMBINE_VALS_typ_x_3 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_5( y, ...) typeof (y) _v5; _NM_HASH_COMBINE_VALS_typ_x_4 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_6( y, ...) typeof (y) _v6; _NM_HASH_COMBINE_VALS_typ_x_5 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_7( y, ...) typeof (y) _v7; _NM_HASH_COMBINE_VALS_typ_x_6 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_8( y, ...) typeof (y) _v8; _NM_HASH_COMBINE_VALS_typ_x_7 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_9( y, ...) typeof (y) _v9; _NM_HASH_COMBINE_VALS_typ_x_8 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_10(y, ...) typeof (y) _v10; _NM_HASH_COMBINE_VALS_typ_x_9 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_11(y, ...) typeof (y) _v11; _NM_HASH_COMBINE_VALS_typ_x_10 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_12(y, ...) typeof (y) _v12; _NM_HASH_COMBINE_VALS_typ_x_11 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_13(y, ...) typeof (y) _v13; _NM_HASH_COMBINE_VALS_typ_x_12 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_14(y, ...) typeof (y) _v14; _NM_HASH_COMBINE_VALS_typ_x_13 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_15(y, ...) typeof (y) _v15; _NM_HASH_COMBINE_VALS_typ_x_14 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_16(y, ...) typeof (y) _v16; _NM_HASH_COMBINE_VALS_typ_x_15 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_17(y, ...) typeof (y) _v17; _NM_HASH_COMBINE_VALS_typ_x_16 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_18(y, ...) typeof (y) _v18; _NM_HASH_COMBINE_VALS_typ_x_17 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_19(y, ...) typeof (y) _v19; _NM_HASH_COMBINE_VALS_typ_x_18 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_20(y, ...) typeof (y) _v20; _NM_HASH_COMBINE_VALS_typ_x_19 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_n2(n, ...) _NM_HASH_COMBINE_VALS_typ_x_##n (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_n(n, ...) _NM_HASH_COMBINE_VALS_typ_n2(n, __VA_ARGS__) + +#define _NM_HASH_COMBINE_VALS_val_x_1( y) ._v1 = (y), +#define _NM_HASH_COMBINE_VALS_val_x_2( y, ...) ._v2 = (y), _NM_HASH_COMBINE_VALS_val_x_1 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_3( y, ...) ._v3 = (y), _NM_HASH_COMBINE_VALS_val_x_2 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_4( y, ...) ._v4 = (y), _NM_HASH_COMBINE_VALS_val_x_3 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_5( y, ...) ._v5 = (y), _NM_HASH_COMBINE_VALS_val_x_4 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_6( y, ...) ._v6 = (y), _NM_HASH_COMBINE_VALS_val_x_5 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_7( y, ...) ._v7 = (y), _NM_HASH_COMBINE_VALS_val_x_6 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_8( y, ...) ._v8 = (y), _NM_HASH_COMBINE_VALS_val_x_7 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_9( y, ...) ._v9 = (y), _NM_HASH_COMBINE_VALS_val_x_8 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_10(y, ...) ._v10 = (y), _NM_HASH_COMBINE_VALS_val_x_9 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_11(y, ...) ._v11 = (y), _NM_HASH_COMBINE_VALS_val_x_10 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_12(y, ...) ._v12 = (y), _NM_HASH_COMBINE_VALS_val_x_11 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_13(y, ...) ._v13 = (y), _NM_HASH_COMBINE_VALS_val_x_12 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_14(y, ...) ._v14 = (y), _NM_HASH_COMBINE_VALS_val_x_13 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_15(y, ...) ._v15 = (y), _NM_HASH_COMBINE_VALS_val_x_14 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_16(y, ...) ._v16 = (y), _NM_HASH_COMBINE_VALS_val_x_15 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_17(y, ...) ._v17 = (y), _NM_HASH_COMBINE_VALS_val_x_16 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_18(y, ...) ._v18 = (y), _NM_HASH_COMBINE_VALS_val_x_17 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_19(y, ...) ._v19 = (y), _NM_HASH_COMBINE_VALS_val_x_18 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_20(y, ...) ._v20 = (y), _NM_HASH_COMBINE_VALS_val_x_19 (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_n2(n, ...) _NM_HASH_COMBINE_VALS_val_x_##n (__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_n(n, ...) _NM_HASH_COMBINE_VALS_val_n2(n, __VA_ARGS__) + +/* NM_HASH_COMBINE_VALS() is faster then nm_hash_update_val() as it combines multiple + * calls to nm_hash_update() using a packed structure. */ +#define NM_HASH_COMBINE_VALS(var, ...) \ + const struct _nm_packed { \ + _NM_HASH_COMBINE_VALS_typ_n (NM_NARG (__VA_ARGS__), __VA_ARGS__) \ + } var _nm_alignas (guint64) = { \ + _NM_HASH_COMBINE_VALS_val_n (NM_NARG (__VA_ARGS__), __VA_ARGS__) \ + } + +/* nm_hash_update_vals() is faster then nm_hash_update_val() as it combines multiple + * calls to nm_hash_update() using a packed structure. */ +#define nm_hash_update_vals(state, ...) \ + G_STMT_START { \ + NM_HASH_COMBINE_VALS (_val, __VA_ARGS__); \ + \ + nm_hash_update ((state), &_val, sizeof (_val)); \ + } G_STMT_END static inline void nm_hash_update_mem (NMHashState *state, const void *ptr, gsize n) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 5ce96cf71a..a6a0fb35bc 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2861,8 +2861,8 @@ _v4_has_shadowed_routes_detect_hash (const IP4RPFilterData *d) NMHashState h; nm_hash_init (&h, 1105201169u); - nm_hash_update_uint (&h, d->network); - nm_hash_update_uint (&h, d->plen); + nm_hash_update_val (&h, d->network); + nm_hash_update_val (&h, d->plen); return nm_hash_complete (&h); } diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index 2431f909e8..2ed2a7d9fa 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -279,8 +279,9 @@ lldp_neighbor_id_hash (gconstpointer ptr) nm_hash_init (&h, 23423423u); nm_hash_update_str0 (&h, neigh->chassis_id); nm_hash_update_str0 (&h, neigh->port_id); - nm_hash_update_uint (&h, neigh->chassis_id_type); - nm_hash_update_uint (&h, neigh->port_id_type); + nm_hash_update_vals (&h, + neigh->chassis_id_type, + neigh->port_id_type); return nm_hash_complete (&h); } diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 04a382ae48..6199521b66 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -186,18 +186,6 @@ nm_utils_exp10 (gint16 ex) /*****************************************************************************/ -guint -nm_utils_in6_addr_hash (const struct in6_addr *addr) -{ - NMHashState h; - - nm_hash_init (&h, 3675559913u); - nm_hash_update_in6addr (&h, addr); - return nm_hash_complete (&h); -} - -/*****************************************************************************/ - /* * nm_ethernet_address_is_valid: * @addr: pointer to a binary or ASCII Ethernet address diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 097cac5fd3..8dc65283ed 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -92,8 +92,6 @@ GETTER (void) \ /*****************************************************************************/ -guint nm_utils_in6_addr_hash (const struct in6_addr *addr); - gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen); @@ -131,7 +129,9 @@ nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in static inline void nm_hash_update_in6addr (NMHashState *h, const struct in6_addr *addr) { - nm_hash_update_mem (h, addr, addr ? sizeof (*addr) : 0); + nm_assert (addr); + + nm_hash_update (h, addr, sizeof (*addr)); } static inline void @@ -139,8 +139,7 @@ nm_hash_update_in6addr_prefix (NMHashState *h, const struct in6_addr *addr, guin { struct in6_addr a; - if (!addr) - g_return_if_reached (); + nm_assert (addr); nm_utils_ip6_address_clear_host_address (&a, addr, plen); /* we don't hash plen itself. The caller may want to do that.*/ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index df87c85038..83b6744ced 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5129,26 +5129,29 @@ nm_platform_link_hash (const NMPlatformLink *obj) NMHashState h; nm_hash_init (&h, 99413953u); - nm_hash_update_uint (&h, obj->ifindex); - nm_hash_update_uint (&h, obj->type); + nm_hash_update_vals (&h, + obj->ifindex, + obj->master, + obj->parent); + nm_hash_update_val (&h, obj->type); nm_hash_update_strarr (&h, obj->name); - nm_hash_update_uint (&h, obj->master); - nm_hash_update_uint (&h, obj->parent); - nm_hash_update_uint (&h, obj->n_ifi_flags); - nm_hash_update_uint (&h, obj->connected); - nm_hash_update_uint (&h, obj->mtu); - nm_hash_update_uint (&h, !!obj->initialized); - nm_hash_update_uint (&h, obj->arptype); - nm_hash_update_uint (&h, obj->addr.len); - nm_hash_update_uint (&h, obj->inet6_addr_gen_mode_inv); + nm_hash_update_vals (&h, + obj->n_ifi_flags, + obj->mtu); + nm_hash_update_bools (&h, obj->connected, + obj->initialized); + nm_hash_update_val (&h, obj->arptype); + nm_hash_update_val (&h, obj->inet6_addr_gen_mode_inv); nm_hash_update_str0 (&h, obj->kind); nm_hash_update_str0 (&h, obj->driver); + /* nm_hash_update_mem() also hashes the length obj->addr.len */ nm_hash_update_mem (&h, obj->addr.data, obj->addr.len); - nm_hash_update_mem (&h, &obj->inet6_token, sizeof (obj->inet6_token)); - nm_hash_update_uint (&h, obj->rx_packets); - nm_hash_update_uint (&h, obj->rx_bytes); - nm_hash_update_uint (&h, obj->tx_packets); - nm_hash_update_uint (&h, obj->tx_bytes); + nm_hash_update (&h, &obj->inet6_token, sizeof (obj->inet6_token)); + nm_hash_update_vals (&h, + obj->rx_packets, + obj->rx_bytes, + obj->tx_packets, + obj->tx_bytes); return nm_hash_complete (&h); } @@ -5186,16 +5189,16 @@ nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj) NMHashState h; nm_hash_init (&h, 1887023311u); - nm_hash_update_uint (&h, obj->parent_ifindex); - nm_hash_update_uint (&h, obj->input_flags); - nm_hash_update_uint (&h, obj->output_flags); - nm_hash_update_uint (&h, obj->input_key); - nm_hash_update_uint (&h, obj->output_key); - nm_hash_update_uint (&h, obj->local); - nm_hash_update_uint (&h, obj->remote); - nm_hash_update_uint (&h, obj->ttl); - nm_hash_update_uint (&h, obj->tos); - nm_hash_update_uint (&h, !obj->path_mtu_discovery); + nm_hash_update_val (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->input_flags); + nm_hash_update_val (&h, obj->output_flags); + nm_hash_update_val (&h, obj->input_key); + nm_hash_update_val (&h, obj->output_key); + nm_hash_update_val (&h, obj->local); + nm_hash_update_val (&h, obj->remote); + nm_hash_update_val (&h, obj->ttl); + nm_hash_update_val (&h, obj->tos); + nm_hash_update_bool (&h, obj->path_mtu_discovery); return nm_hash_complete (&h); } @@ -5222,7 +5225,7 @@ nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj) NMHashState h; nm_hash_init (&h, 1748638583u); - nm_hash_update_uint (&h, obj->p_key); + nm_hash_update_val (&h, obj->p_key); nm_hash_update_str0 (&h, obj->mode); return nm_hash_complete (&h); } @@ -5242,14 +5245,14 @@ nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj) NMHashState h; nm_hash_init (&h, 1651660009u); - nm_hash_update_uint (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->parent_ifindex); nm_hash_update_in6addr (&h, &obj->local); nm_hash_update_in6addr (&h, &obj->remote); - nm_hash_update_uint (&h, obj->ttl); - nm_hash_update_uint (&h, obj->tclass); - nm_hash_update_uint (&h, obj->encap_limit); - nm_hash_update_uint (&h, obj->flow_label); - nm_hash_update_uint (&h, obj->proto); + nm_hash_update_val (&h, obj->ttl); + nm_hash_update_val (&h, obj->tclass); + nm_hash_update_val (&h, obj->encap_limit); + nm_hash_update_val (&h, obj->flow_label); + nm_hash_update_val (&h, obj->proto); return nm_hash_complete (&h); } @@ -5274,12 +5277,12 @@ nm_platform_lnk_ipip_hash (const NMPlatformLnkIpIp *obj) NMHashState h; nm_hash_init (&h, 861934429u); - nm_hash_update_uint (&h, obj->parent_ifindex); - nm_hash_update_uint (&h, obj->local); - nm_hash_update_uint (&h, obj->remote); - nm_hash_update_uint (&h, obj->ttl); - nm_hash_update_uint (&h, obj->tos); - nm_hash_update_uint (&h, obj->path_mtu_discovery); + nm_hash_update_val (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->local); + nm_hash_update_val (&h, obj->remote); + nm_hash_update_val (&h, obj->ttl); + nm_hash_update_val (&h, obj->tos); + nm_hash_update_bool (&h, obj->path_mtu_discovery); return nm_hash_complete (&h); } @@ -5302,19 +5305,21 @@ nm_platform_lnk_macsec_hash (const NMPlatformLnkMacsec *obj) NMHashState h; nm_hash_init (&h, 226984267u); - nm_hash_update_uint (&h, obj->parent_ifindex); - nm_hash_update_uint (&h, obj->sci); - nm_hash_update_uint64 (&h, obj->icv_length); - nm_hash_update_uint64 (&h, obj->cipher_suite); - nm_hash_update_uint (&h, obj->window); - nm_hash_update_uint (&h, obj->encoding_sa); - nm_hash_update_uint (&h, obj->validation); - nm_hash_update_uint (&h, obj->encrypt); - nm_hash_update_uint (&h, obj->protect); - nm_hash_update_uint (&h, obj->include_sci); - nm_hash_update_uint (&h, obj->es); - nm_hash_update_uint (&h, obj->scb); - nm_hash_update_uint (&h, obj->replay_protect); + nm_hash_update_val (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->window); + nm_hash_update_vals (&h, + obj->cipher_suite, + obj->sci); + nm_hash_update_vals (&h, + obj->icv_length, + obj->encoding_sa, + obj->validation); + nm_hash_update_bools (&h, obj->encrypt, + obj->protect, + obj->include_sci, + obj->es, + obj->scb, + obj->replay_protect); return nm_hash_complete (&h); } @@ -5344,9 +5349,9 @@ nm_platform_lnk_macvlan_hash (const NMPlatformLnkMacvlan *obj) NMHashState h; nm_hash_init (&h, 771014989u); - nm_hash_update_uint (&h, obj->mode); - nm_hash_update_uint (&h, obj->no_promisc); - nm_hash_update_uint (&h, obj->tap); + nm_hash_update_val (&h, obj->mode); + nm_hash_update_bools (&h, obj->no_promisc, + obj->tap); return nm_hash_complete (&h); } @@ -5366,14 +5371,14 @@ nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj) NMHashState h; nm_hash_init (&h, 1690154969u); - nm_hash_update_uint (&h, obj->parent_ifindex); - nm_hash_update_uint (&h, obj->local); - nm_hash_update_uint (&h, obj->remote); - nm_hash_update_uint (&h, obj->ttl); - nm_hash_update_uint (&h, obj->tos); - nm_hash_update_uint (&h, obj->path_mtu_discovery); - nm_hash_update_uint (&h, obj->flags); - nm_hash_update_uint (&h, obj->proto); + nm_hash_update_val (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->local); + nm_hash_update_val (&h, obj->remote); + nm_hash_update_val (&h, obj->ttl); + nm_hash_update_val (&h, obj->tos); + nm_hash_update_bool (&h, obj->path_mtu_discovery); + nm_hash_update_val (&h, obj->flags); + nm_hash_update_val (&h, obj->proto); return nm_hash_complete (&h); } @@ -5398,8 +5403,8 @@ nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj) NMHashState h; nm_hash_init (&h, 58751383u); - nm_hash_update_uint (&h, obj->id); - nm_hash_update_uint (&h, obj->flags); + nm_hash_update_val (&h, obj->id); + nm_hash_update_val (&h, obj->flags); return nm_hash_complete (&h); } @@ -5418,24 +5423,24 @@ nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj) NMHashState h; nm_hash_init (&h, 461041297u); - nm_hash_update_uint (&h, obj->parent_ifindex); - nm_hash_update_uint (&h, obj->id); - nm_hash_update_uint (&h, obj->group); - nm_hash_update_uint (&h, obj->local); + nm_hash_update_val (&h, obj->parent_ifindex); + nm_hash_update_val (&h, obj->id); + nm_hash_update_val (&h, obj->group); + nm_hash_update_val (&h, obj->local); nm_hash_update_in6addr (&h, &obj->group6); nm_hash_update_in6addr (&h, &obj->local6); - nm_hash_update_uint (&h, obj->tos); - nm_hash_update_uint (&h, obj->ttl); - nm_hash_update_uint (&h, obj->learning); - nm_hash_update_uint (&h, obj->ageing); - nm_hash_update_uint (&h, obj->limit); - nm_hash_update_uint (&h, obj->dst_port); - nm_hash_update_uint (&h, obj->src_port_min); - nm_hash_update_uint (&h, obj->src_port_max); - nm_hash_update_uint (&h, obj->proxy); - nm_hash_update_uint (&h, obj->rsc); - nm_hash_update_uint (&h, obj->l2miss); - nm_hash_update_uint (&h, obj->l3miss); + nm_hash_update_val (&h, obj->tos); + nm_hash_update_val (&h, obj->ttl); + nm_hash_update_val (&h, obj->ageing); + nm_hash_update_val (&h, obj->limit); + nm_hash_update_val (&h, obj->dst_port); + nm_hash_update_val (&h, obj->src_port_min); + nm_hash_update_val (&h, obj->src_port_max); + nm_hash_update_bools (&h, obj->learning, + obj->proxy, + obj->rsc, + obj->l2miss, + obj->l3miss); return nm_hash_complete (&h); } @@ -5471,15 +5476,15 @@ nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj) nm_hash_init (&h, 469681301u); if (obj) { - nm_hash_update_uint (&h, obj->ifindex); - nm_hash_update_uint (&h, obj->address); - nm_hash_update_uint (&h, obj->plen); - nm_hash_update_uint (&h, obj->peer_address); - nm_hash_update_uint (&h, obj->addr_source); - nm_hash_update_uint (&h, obj->timestamp); - nm_hash_update_uint (&h, obj->lifetime); - nm_hash_update_uint (&h, obj->preferred); - nm_hash_update_uint (&h, obj->n_ifa_flags); + nm_hash_update_val (&h, obj->ifindex); + nm_hash_update_val (&h, obj->address); + nm_hash_update_val (&h, obj->plen); + nm_hash_update_val (&h, obj->peer_address); + nm_hash_update_val (&h, obj->addr_source); + nm_hash_update_val (&h, obj->timestamp); + nm_hash_update_val (&h, obj->lifetime); + nm_hash_update_val (&h, obj->preferred); + nm_hash_update_val (&h, obj->n_ifa_flags); nm_hash_update_strarr (&h, obj->label); } return nm_hash_complete (&h); @@ -5509,15 +5514,15 @@ nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj) nm_hash_init (&h, 605908909u); if (obj) { - nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_val (&h, obj->ifindex); nm_hash_update_in6addr (&h, &obj->address); - nm_hash_update_uint (&h, obj->plen); + nm_hash_update_val (&h, obj->plen); nm_hash_update_in6addr (&h, &obj->peer_address); - nm_hash_update_uint (&h, obj->addr_source); - nm_hash_update_uint (&h, obj->timestamp); - nm_hash_update_uint (&h, obj->lifetime); - nm_hash_update_uint (&h, obj->preferred); - nm_hash_update_uint (&h, obj->n_ifa_flags); + nm_hash_update_val (&h, obj->addr_source); + nm_hash_update_val (&h, obj->timestamp); + nm_hash_update_val (&h, obj->lifetime); + nm_hash_update_val (&h, obj->preferred); + nm_hash_update_val (&h, obj->n_ifa_flags); } return nm_hash_complete (&h); } @@ -5548,70 +5553,72 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT NMHashState h; nm_hash_init (&h, 1228913327u); - nm_hash_update_uint (&h, cmp_type); + nm_hash_update_val (&h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); - nm_hash_update_uint (&h, obj->plen); - nm_hash_update_uint (&h, obj->metric); - nm_hash_update_uint (&h, obj->tos); + nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_val (&h, obj->plen); + nm_hash_update_val (&h, obj->metric); + nm_hash_update_val (&h, obj->tos); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_uint (&h, obj->ifindex); - nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_uint (&h, _ip_route_scope_inv_get_normalized (obj)); - nm_hash_update_uint (&h, obj->gateway); - nm_hash_update_uint (&h, obj->mss); - nm_hash_update_uint (&h, obj->pref_src); - nm_hash_update_uint (&h, obj->window); - nm_hash_update_uint (&h, obj->cwnd); - nm_hash_update_uint (&h, obj->initcwnd); - nm_hash_update_uint (&h, obj->initrwnd); - nm_hash_update_uint (&h, obj->mtu); - nm_hash_update_uint (&h, obj->lock_window); - nm_hash_update_uint (&h, obj->lock_cwnd); - nm_hash_update_uint (&h, obj->lock_initcwnd); - nm_hash_update_uint (&h, obj->lock_initrwnd); - nm_hash_update_uint (&h, obj->lock_mtu); + nm_hash_update_val (&h, obj->ifindex); + nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_val (&h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_val (&h, obj->gateway); + nm_hash_update_val (&h, obj->mss); + nm_hash_update_val (&h, obj->pref_src); + nm_hash_update_vals (&h, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu); + nm_hash_update_bools (&h, obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - nm_hash_update_uint (&h, obj->table_coerced); - nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_val (&h, obj->table_coerced); + nm_hash_update_val (&h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_val (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); else - nm_hash_update_uint (&h, obj->network); - nm_hash_update_uint (&h, obj->plen); - nm_hash_update_uint (&h, obj->metric); - nm_hash_update_uint (&h, obj->gateway); + nm_hash_update_val (&h, obj->network); + nm_hash_update_val (&h, obj->plen); + nm_hash_update_val (&h, obj->metric); + nm_hash_update_val (&h, obj->gateway); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_uint (&h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_val (&h, _ip_route_scope_inv_get_normalized (obj)); } else { - nm_hash_update_uint (&h, obj->rt_source); - nm_hash_update_uint (&h, obj->scope_inv); + nm_hash_update_val (&h, obj->rt_source); + nm_hash_update_val (&h, obj->scope_inv); } - nm_hash_update_uint (&h, obj->mss); - nm_hash_update_uint (&h, obj->pref_src); - nm_hash_update_uint (&h, obj->rt_cloned); - nm_hash_update_uint (&h, obj->tos); - nm_hash_update_uint (&h, obj->lock_window); - nm_hash_update_uint (&h, obj->lock_cwnd); - nm_hash_update_uint (&h, obj->lock_initcwnd); - nm_hash_update_uint (&h, obj->lock_initrwnd); - nm_hash_update_uint (&h, obj->lock_mtu); - nm_hash_update_uint (&h, obj->window); - nm_hash_update_uint (&h, obj->cwnd); - nm_hash_update_uint (&h, obj->initcwnd); - nm_hash_update_uint (&h, obj->initrwnd); - nm_hash_update_uint (&h, obj->mtu); + nm_hash_update_val (&h, obj->tos); + nm_hash_update_vals (&h, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu); + nm_hash_update_bools (&h, obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); break; } } @@ -5701,65 +5708,65 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT NMHashState h; nm_hash_init (&h, 1053326051u); - nm_hash_update_uint (&h, cmp_type); + nm_hash_update_val (&h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); - nm_hash_update_uint (&h, obj->plen); - nm_hash_update_uint (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_val (&h, obj->plen); + nm_hash_update_val (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); - nm_hash_update_uint (&h, obj->src_plen); + nm_hash_update_val (&h, obj->src_plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_val (&h, obj->ifindex); nm_hash_update_in6addr (&h, &obj->gateway); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_uint (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - nm_hash_update_uint (&h, obj->table_coerced); - nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_val (&h, obj->table_coerced); + nm_hash_update_val (&h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); else nm_hash_update_in6addr (&h, &obj->network); - nm_hash_update_uint (&h, obj->plen); + nm_hash_update_val (&h, obj->plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_uint (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_val (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); else - nm_hash_update_uint (&h, obj->metric); + nm_hash_update_val (&h, obj->metric); nm_hash_update_in6addr (&h, &obj->gateway); nm_hash_update_in6addr (&h, &obj->pref_src); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); - nm_hash_update_uint (&h, obj->src_plen); - nm_hash_update_uint (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_val (&h, obj->src_plen); + nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); } else { nm_hash_update_in6addr (&h, &obj->src); - nm_hash_update_uint (&h, obj->src_plen); - nm_hash_update_uint (&h, obj->rt_source); + nm_hash_update_val (&h, obj->src_plen); + nm_hash_update_val (&h, obj->rt_source); } - nm_hash_update_uint (&h, obj->mss); - nm_hash_update_uint (&h, obj->rt_cloned); - nm_hash_update_uint (&h, obj->lock_window); - nm_hash_update_uint (&h, obj->lock_cwnd); - nm_hash_update_uint (&h, obj->lock_initcwnd); - nm_hash_update_uint (&h, obj->lock_initrwnd); - nm_hash_update_uint (&h, obj->lock_mtu); - nm_hash_update_uint (&h, obj->window); - nm_hash_update_uint (&h, obj->cwnd); - nm_hash_update_uint (&h, obj->initcwnd); - nm_hash_update_uint (&h, obj->initrwnd); - nm_hash_update_uint (&h, obj->mtu); + nm_hash_update_val (&h, obj->mss); + nm_hash_update_bools (&h, obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); + nm_hash_update_val (&h, obj->window); + nm_hash_update_val (&h, obj->cwnd); + nm_hash_update_val (&h, obj->initcwnd); + nm_hash_update_val (&h, obj->initrwnd); + nm_hash_update_val (&h, obj->mtu); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_uint (&h, _route_pref_normalize (obj->rt_pref)); + nm_hash_update_val (&h, _route_pref_normalize (obj->rt_pref)); else - nm_hash_update_uint (&h, obj->rt_pref); + nm_hash_update_val (&h, obj->rt_pref); break; } } diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 731c81f0f2..bec3f44a37 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -162,8 +162,9 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, NMHashState h; nm_hash_init (&h, 487703243u); - nm_hash_update_uint (&h, idx_type->cache_id_type); - nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); + nm_hash_update_vals (&h, + idx_type->cache_id_type, + NMP_OBJECT_GET_TYPE (obj_a)); return _HASH_NON_ZERO (&h); } return 1; @@ -185,7 +186,7 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, /* we request a hash from obj_a. Hash the relevant parts. */ nm_hash_init (&h, 2126752699u); - nm_hash_update_uint (&h, idx_type->cache_id_type); + nm_hash_update_val (&h, idx_type->cache_id_type); nm_hash_update_strarr (&h, obj_a->link.name); return _HASH_NON_ZERO (&h); } @@ -207,8 +208,9 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, NMHashState h; nm_hash_init (&h, 4278960223u); - nm_hash_update_uint (&h, idx_type->cache_id_type); - nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); + nm_hash_update_vals (&h, + idx_type->cache_id_type, + NMP_OBJECT_GET_TYPE (obj_a)); return _HASH_NON_ZERO (&h); } return 1; @@ -230,9 +232,9 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, NMHashState h; nm_hash_init (&h, 920415631u); - nm_hash_update_uint (&h, idx_type->cache_id_type); - nm_hash_update_uint (&h, NMP_OBJECT_GET_TYPE (obj_a)); - nm_hash_update_uint (&h, obj_a->object.ifindex); + nm_hash_update_vals (&h, + idx_type->cache_id_type, + obj_a->object.ifindex); return _HASH_NON_ZERO (&h); } return 1; @@ -252,13 +254,16 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, } if (request_hash) { NMHashState h; + guint h2; + + h2 = (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) + ? nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) + : nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID); nm_hash_init (&h, 778646573u); - nm_hash_update_uint (&h, idx_type->cache_id_type); - if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) - nm_hash_update_uint (&h, nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); - else - nm_hash_update_uint (&h, nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID)); + nm_hash_update_vals (&h, + idx_type->cache_id_type, + h2); return _HASH_NON_ZERO (&h); } return 1; @@ -325,13 +330,12 @@ _vlan_xgress_qos_mappings_hash_update (guint n_map, const NMVlanQosMapping *map, NMHashState *h) { - guint i; + /* ensure no padding. */ + G_STATIC_ASSERT (sizeof (NMVlanQosMapping) == 2 * sizeof (guint32)); - nm_hash_update_uint (h, 1453577309u); - for (i = 0; i < n_map; i++) { - nm_hash_update_uint (h, map[i].from); - nm_hash_update_uint (h, map[i].to); - } + nm_hash_update_val (h, n_map); + if (n_map) + nm_hash_update (h, map, n_map * sizeof (*map)); } static int @@ -781,13 +785,13 @@ nmp_object_hash (const NMPObject *obj) klass = NMP_OBJECT_GET_CLASS (obj); nm_hash_init (&h, 816200863u); - nm_hash_update_uint (&h, klass->obj_type); + nm_hash_update_val (&h, klass->obj_type); if (klass->cmd_obj_hash) - nm_hash_update_uint (&h, klass->cmd_obj_hash (obj)); + nm_hash_update_val (&h, klass->cmd_obj_hash (obj)); else if (klass->cmd_plobj_hash) - nm_hash_update_uint (&h, klass->cmd_plobj_hash (&obj->object)); + nm_hash_update_val (&h, klass->cmd_plobj_hash (&obj->object)); else - nm_hash_update_ptr (&h, obj); + nm_hash_update_val (&h, obj); return nm_hash_complete (&h); } @@ -800,11 +804,11 @@ _vt_cmd_obj_hash_link (const NMPObject *obj) nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK); nm_hash_init (&h, 3448776161u); - nm_hash_update_uint (&h, nm_platform_link_hash (&obj->link)); - nm_hash_update_uint (&h, obj->_link.netlink.is_in_netlink); + nm_hash_update_val (&h, nm_platform_link_hash (&obj->link)); + nm_hash_update_val (&h, obj->_link.netlink.is_in_netlink); if (obj->_link.netlink.lnk) - nm_hash_update_uint (&h, nmp_object_hash (obj->_link.netlink.lnk)); - nm_hash_update_ptr (&h, obj->_link.udev.device); + nm_hash_update_val (&h, nmp_object_hash (obj->_link.netlink.lnk)); + nm_hash_update_val (&h, obj->_link.udev.device); return nm_hash_complete (&h); } @@ -816,7 +820,7 @@ _vt_cmd_obj_hash_lnk_vlan (const NMPObject *obj) nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_VLAN); nm_hash_init (&h, 914932607u); - nm_hash_update_uint (&h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); + nm_hash_update_val (&h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_ingress_qos_map, obj->_lnk_vlan.ingress_qos_map, &h); @@ -1125,25 +1129,27 @@ _vt_cmd_plobj_id_hash_##type (const NMPlatformObject *_obj) \ return nm_hash_complete (&h); \ } _vt_cmd_plobj_id_hash (link, NMPlatformLink, 3982791431u, { - nm_hash_update_uint (&h, obj->ifindex); + nm_hash_update_val (&h, obj->ifindex); }) _vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, 3591309853u, { - nm_hash_update_uint (&h, obj->ifindex); - nm_hash_update_uint (&h, obj->plen); - nm_hash_update_uint (&h, obj->address); - /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ - nm_hash_update_uint (&h, nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen)); + nm_hash_update_vals (&h, + obj->ifindex, + obj->plen, + obj->address, + /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ + nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen)); }) _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, 2907861637u, { - nm_hash_update_uint (&h, obj->ifindex); - /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ - nm_hash_update_in6addr (&h, &obj->address); + nm_hash_update_vals (&h, + obj->ifindex, + /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ + obj->address); }) _vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, 1038302471u, { - nm_hash_update_uint (&h, nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); + nm_hash_update_val (&h, nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); }) _vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, 1233384151u, { - nm_hash_update_uint (&h, nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); + nm_hash_update_val (&h, nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); }) gboolean From cfe8546df992e7725b3b3b28c594e6ec2bc49221 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 11:53:08 +0200 Subject: [PATCH 10/12] all: extend hash functions with an NMHashState argument We often want to cascade hashing, meaning, to combine the outcome of various hash functions in a larger hash. Instead of having each hash function return a guint hash value, accept a hash state argument. This saves the overhead of initializing and completing the intermediate hash states. It also avoids loosing entropy when we reduce the larger hash state into the intermediate guint hash value. --- libnm-core/tests/test-general.c | 36 +-- shared/nm-utils/nm-dedup-multi.c | 16 +- shared/nm-utils/nm-dedup-multi.h | 17 +- src/nm-ip4-config.c | 11 +- src/platform/nm-platform.c | 468 ++++++++++++++----------------- src/platform/nm-platform.h | 40 +-- src/platform/nmp-object.c | 334 ++++++++++------------ src/platform/nmp-object.h | 9 +- 8 files changed, 415 insertions(+), 516 deletions(-) diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 1f4aa21702..8c4d120d11 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -420,13 +420,15 @@ _dedup_obj_destroy (NMDedupMultiObj *obj) g_slice_free (DedupObj, o); } -static guint -_dedup_obj_full_hash (const NMDedupMultiObj *obj) +static void +_dedup_obj_full_hash_update (const NMDedupMultiObj *obj, NMHashState *h) { const DedupObj *o; o = _dedup_obj_assert (obj); - return (o->val * 33) + o->other; + nm_hash_update_vals (h, + o->val, + o->other); } static gboolean @@ -443,7 +445,7 @@ _dedup_obj_full_equal (const NMDedupMultiObj *obj_a, static const NMDedupMultiObjClass dedup_obj_class = { .obj_clone = _dedup_obj_clone, .obj_destroy = _dedup_obj_destroy, - .obj_full_hash = _dedup_obj_full_hash, + .obj_full_hash_update = _dedup_obj_full_hash_update, .obj_full_equal = _dedup_obj_full_equal, }; @@ -478,20 +480,19 @@ _dedup_idx_assert (const NMDedupMultiIdxType *idx_type) return t; } -static guint -_dedup_idx_obj_id_hash (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +static void +_dedup_idx_obj_id_hash_update (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + NMHashState *h) { const DedupIdxType *t; const DedupObj *o; - guint h; t = _dedup_idx_assert (idx_type); o = _dedup_obj_assert (obj); - h = o->val / t->partition_size; - h = (h * 33) + (o->val % t->val_mod); - return h; + nm_hash_update_val (h, o->val / t->partition_size); + nm_hash_update_val (h, o->val % t->val_mod); } static gboolean @@ -511,9 +512,10 @@ _dedup_idx_obj_id_equal (const NMDedupMultiIdxType *idx_type, && (o_a->val % t->val_mod) == (o_b->val % t->val_mod); } -static guint -_dedup_idx_obj_partition_hash (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +static void +_dedup_idx_obj_partition_hash_update (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + NMHashState *h) { const DedupIdxType *t; const DedupObj *o; @@ -521,7 +523,7 @@ _dedup_idx_obj_partition_hash (const NMDedupMultiIdxType *idx_type, t = _dedup_idx_assert (idx_type); o = _dedup_obj_assert (obj); - return o->val / t->partition_size; + nm_hash_update_val (h, o->val / t->partition_size); } static gboolean @@ -541,9 +543,9 @@ _dedup_idx_obj_partition_equal (const NMDedupMultiIdxType *idx_type, } static const NMDedupMultiIdxTypeClass dedup_idx_type_class = { - .idx_obj_id_hash = _dedup_idx_obj_id_hash, + .idx_obj_id_hash_update = _dedup_idx_obj_id_hash_update, .idx_obj_id_equal = _dedup_idx_obj_id_equal, - .idx_obj_partition_hash = _dedup_idx_obj_partition_hash, + .idx_obj_partition_hash_update = _dedup_idx_obj_partition_hash_update, .idx_obj_partition_equal = _dedup_idx_obj_partition_equal, }; diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c index fb57f6c1ad..8a59f1c466 100644 --- a/shared/nm-utils/nm-dedup-multi.c +++ b/shared/nm-utils/nm-dedup-multi.c @@ -55,9 +55,9 @@ ASSERT_idx_type (const NMDedupMultiIdxType *idx_type) nm_assert (idx_type); #if NM_MORE_ASSERTS > 10 nm_assert (idx_type->klass); - nm_assert (idx_type->klass->idx_obj_id_hash); + nm_assert (idx_type->klass->idx_obj_id_hash_update); nm_assert (idx_type->klass->idx_obj_id_equal); - nm_assert (!!idx_type->klass->idx_obj_partition_hash == !!idx_type->klass->idx_obj_partition_equal); + nm_assert (!!idx_type->klass->idx_obj_partition_hash_update == !!idx_type->klass->idx_obj_partition_equal); nm_assert (idx_type->lst_idx_head.next); #endif } @@ -181,13 +181,13 @@ _dict_idx_entries_hash (const NMDedupMultiEntry *entry) _entry_unpack (entry, &idx_type, &obj, &lookup_head); nm_hash_init (&h, 1914869417u); - if (idx_type->klass->idx_obj_partition_hash) { + if (idx_type->klass->idx_obj_partition_hash_update) { nm_assert (obj); - nm_hash_update_val (&h, idx_type->klass->idx_obj_partition_hash (idx_type, obj)); + idx_type->klass->idx_obj_partition_hash_update (idx_type, obj, &h); } if (!lookup_head) - nm_hash_update_val (&h, idx_type->klass->idx_obj_id_hash (idx_type, obj)); + idx_type->klass->idx_obj_id_hash_update (idx_type, obj, &h); nm_hash_update_val (&h, idx_type); return nm_hash_complete (&h); @@ -797,7 +797,11 @@ nm_dedup_multi_index_dirty_remove_idx (NMDedupMultiIndex *self, static guint _dict_idx_objs_hash (const NMDedupMultiObj *obj) { - return obj->klass->obj_full_hash (obj); + NMHashState h; + + nm_hash_init (&h, 1748638583u); + obj->klass->obj_full_hash_update (obj, &h); + return nm_hash_complete (&h); } static gboolean diff --git a/shared/nm-utils/nm-dedup-multi.h b/shared/nm-utils/nm-dedup-multi.h index ecce791d42..bebfe43d32 100644 --- a/shared/nm-utils/nm-dedup-multi.h +++ b/shared/nm-utils/nm-dedup-multi.h @@ -27,6 +27,8 @@ /*****************************************************************************/ +struct _NMHashState; + typedef struct _NMDedupMultiObj NMDedupMultiObj; typedef struct _NMDedupMultiObjClass NMDedupMultiObjClass; typedef struct _NMDedupMultiIdxType NMDedupMultiIdxType; @@ -69,9 +71,10 @@ struct _NMDedupMultiObjClass { void (*obj_destroy) (NMDedupMultiObj *obj); - /* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash() + /* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash_update() * and obj_full_equal() compare *all* fields of the object, even minor ones. */ - guint (*obj_full_hash) (const NMDedupMultiObj *obj); + void (*obj_full_hash_update) (const NMDedupMultiObj *obj, + struct _NMHashState *h); gboolean (*obj_full_equal) (const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b); }; @@ -152,8 +155,9 @@ void nm_dedup_multi_idx_type_init (NMDedupMultiIdxType *idx_type, struct _NMDedupMultiIdxTypeClass { NMObjBaseClass parent; - guint (*idx_obj_id_hash) (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj); + void (*idx_obj_id_hash_update) (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + struct _NMHashState *h); gboolean (*idx_obj_id_equal) (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b); @@ -167,8 +171,9 @@ struct _NMDedupMultiIdxTypeClass { * object is not partitionable, it is never added to the NMDedupMultiIndex. */ gboolean (*idx_obj_partitionable) (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj); - guint (*idx_obj_partition_hash) (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj); + void (*idx_obj_partition_hash_update) (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + struct _NMHashState *h); gboolean (*idx_obj_partition_equal) (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 657ea6346b..e2f99e24d0 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -57,11 +57,12 @@ _route_valid (const NMPlatformIP4Route *r) /*****************************************************************************/ -static guint -_idx_obj_id_hash (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +static void +_idx_obj_id_hash_update (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + NMHashState *h) { - return nmp_object_id_hash ((NMPObject *) obj); + nmp_object_id_hash_update ((NMPObject *) obj, h); } static gboolean @@ -77,7 +78,7 @@ nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type, NMPObjectType obj_type) { static const NMDedupMultiIdxTypeClass idx_type_class = { - .idx_obj_id_hash = _idx_obj_id_hash, + .idx_obj_id_hash_update = _idx_obj_id_hash_update, .idx_obj_id_equal = _idx_obj_id_equal, }; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 83b6744ced..cd0e474a61 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5123,36 +5123,32 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi return buf; } -guint -nm_platform_link_hash (const NMPlatformLink *obj) +void +nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 99413953u); - nm_hash_update_vals (&h, + nm_hash_update_vals (h, obj->ifindex, obj->master, obj->parent); - nm_hash_update_val (&h, obj->type); - nm_hash_update_strarr (&h, obj->name); - nm_hash_update_vals (&h, + nm_hash_update_val (h, obj->type); + nm_hash_update_strarr (h, obj->name); + nm_hash_update_vals (h, obj->n_ifi_flags, obj->mtu); - nm_hash_update_bools (&h, obj->connected, - obj->initialized); - nm_hash_update_val (&h, obj->arptype); - nm_hash_update_val (&h, obj->inet6_addr_gen_mode_inv); - nm_hash_update_str0 (&h, obj->kind); - nm_hash_update_str0 (&h, obj->driver); + nm_hash_update_bools (h, obj->connected, + obj->initialized); + nm_hash_update_val (h, obj->arptype); + nm_hash_update_val (h, obj->inet6_addr_gen_mode_inv); + nm_hash_update_str0 (h, obj->kind); + nm_hash_update_str0 (h, obj->driver); /* nm_hash_update_mem() also hashes the length obj->addr.len */ - nm_hash_update_mem (&h, obj->addr.data, obj->addr.len); - nm_hash_update (&h, &obj->inet6_token, sizeof (obj->inet6_token)); - nm_hash_update_vals (&h, + nm_hash_update_mem (h, obj->addr.data, obj->addr.len); + nm_hash_update (h, &obj->inet6_token, sizeof (obj->inet6_token)); + nm_hash_update_vals (h, obj->rx_packets, obj->rx_bytes, obj->tx_packets, obj->tx_bytes); - return nm_hash_complete (&h); } int @@ -5183,23 +5179,19 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) return 0; } -guint -nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj) +void +nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1887023311u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_val (&h, obj->input_flags); - nm_hash_update_val (&h, obj->output_flags); - nm_hash_update_val (&h, obj->input_key); - nm_hash_update_val (&h, obj->output_key); - nm_hash_update_val (&h, obj->local); - nm_hash_update_val (&h, obj->remote); - nm_hash_update_val (&h, obj->ttl); - nm_hash_update_val (&h, obj->tos); - nm_hash_update_bool (&h, obj->path_mtu_discovery); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_val (h, obj->input_flags); + nm_hash_update_val (h, obj->output_flags); + nm_hash_update_val (h, obj->input_key); + nm_hash_update_val (h, obj->output_key); + nm_hash_update_val (h, obj->local); + nm_hash_update_val (h, obj->remote); + nm_hash_update_val (h, obj->ttl); + nm_hash_update_val (h, obj->tos); + nm_hash_update_bool (h, obj->path_mtu_discovery); } int @@ -5219,15 +5211,11 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) return 0; } -guint -nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj) +void +nm_platform_lnk_infiniband_hash_update (const NMPlatformLnkInfiniband *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1748638583u); - nm_hash_update_val (&h, obj->p_key); - nm_hash_update_str0 (&h, obj->mode); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->p_key); + nm_hash_update_str0 (h, obj->mode); } int @@ -5239,21 +5227,17 @@ nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatfo return 0; } -guint -nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj) +void +nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1651660009u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_in6addr (&h, &obj->local); - nm_hash_update_in6addr (&h, &obj->remote); - nm_hash_update_val (&h, obj->ttl); - nm_hash_update_val (&h, obj->tclass); - nm_hash_update_val (&h, obj->encap_limit); - nm_hash_update_val (&h, obj->flow_label); - nm_hash_update_val (&h, obj->proto); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_in6addr (h, &obj->local); + nm_hash_update_in6addr (h, &obj->remote); + nm_hash_update_val (h, obj->ttl); + nm_hash_update_val (h, obj->tclass); + nm_hash_update_val (h, obj->encap_limit); + nm_hash_update_val (h, obj->flow_label); + nm_hash_update_val (h, obj->proto); } int @@ -5271,19 +5255,15 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6 return 0; } -guint -nm_platform_lnk_ipip_hash (const NMPlatformLnkIpIp *obj) +void +nm_platform_lnk_ipip_hash_update (const NMPlatformLnkIpIp *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 861934429u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_val (&h, obj->local); - nm_hash_update_val (&h, obj->remote); - nm_hash_update_val (&h, obj->ttl); - nm_hash_update_val (&h, obj->tos); - nm_hash_update_bool (&h, obj->path_mtu_discovery); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_val (h, obj->local); + nm_hash_update_val (h, obj->remote); + nm_hash_update_val (h, obj->ttl); + nm_hash_update_val (h, obj->tos); + nm_hash_update_bool (h, obj->path_mtu_discovery); } int @@ -5299,28 +5279,24 @@ nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b return 0; } -guint -nm_platform_lnk_macsec_hash (const NMPlatformLnkMacsec *obj) +void +nm_platform_lnk_macsec_hash_update (const NMPlatformLnkMacsec *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 226984267u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_val (&h, obj->window); - nm_hash_update_vals (&h, + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_val (h, obj->window); + nm_hash_update_vals (h, obj->cipher_suite, obj->sci); - nm_hash_update_vals (&h, + nm_hash_update_vals (h, obj->icv_length, obj->encoding_sa, obj->validation); - nm_hash_update_bools (&h, obj->encrypt, - obj->protect, - obj->include_sci, - obj->es, - obj->scb, - obj->replay_protect); - return nm_hash_complete (&h); + nm_hash_update_bools (h, obj->encrypt, + obj->protect, + obj->include_sci, + obj->es, + obj->scb, + obj->replay_protect); } int @@ -5343,16 +5319,12 @@ nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMac return 0; } -guint -nm_platform_lnk_macvlan_hash (const NMPlatformLnkMacvlan *obj) +void +nm_platform_lnk_macvlan_hash_update (const NMPlatformLnkMacvlan *obj, NMHashState *h ) { - NMHashState h; - - nm_hash_init (&h, 771014989u); - nm_hash_update_val (&h, obj->mode); - nm_hash_update_bools (&h, obj->no_promisc, - obj->tap); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->mode); + nm_hash_update_bools (h, obj->no_promisc, + obj->tap); } int @@ -5365,21 +5337,17 @@ nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkM return 0; } -guint -nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj) +void +nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1690154969u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_val (&h, obj->local); - nm_hash_update_val (&h, obj->remote); - nm_hash_update_val (&h, obj->ttl); - nm_hash_update_val (&h, obj->tos); - nm_hash_update_bool (&h, obj->path_mtu_discovery); - nm_hash_update_val (&h, obj->flags); - nm_hash_update_val (&h, obj->proto); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_val (h, obj->local); + nm_hash_update_val (h, obj->remote); + nm_hash_update_val (h, obj->ttl); + nm_hash_update_val (h, obj->tos); + nm_hash_update_bool (h, obj->path_mtu_discovery); + nm_hash_update_val (h, obj->flags); + nm_hash_update_val (h, obj->proto); } int @@ -5397,15 +5365,11 @@ nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) return 0; } -guint -nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj) +void +nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 58751383u); - nm_hash_update_val (&h, obj->id); - nm_hash_update_val (&h, obj->flags); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->id); + nm_hash_update_val (h, obj->flags); } int @@ -5417,31 +5381,27 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b return 0; } -guint -nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj) +void +nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 461041297u); - nm_hash_update_val (&h, obj->parent_ifindex); - nm_hash_update_val (&h, obj->id); - nm_hash_update_val (&h, obj->group); - nm_hash_update_val (&h, obj->local); - nm_hash_update_in6addr (&h, &obj->group6); - nm_hash_update_in6addr (&h, &obj->local6); - nm_hash_update_val (&h, obj->tos); - nm_hash_update_val (&h, obj->ttl); - nm_hash_update_val (&h, obj->ageing); - nm_hash_update_val (&h, obj->limit); - nm_hash_update_val (&h, obj->dst_port); - nm_hash_update_val (&h, obj->src_port_min); - nm_hash_update_val (&h, obj->src_port_max); - nm_hash_update_bools (&h, obj->learning, - obj->proxy, - obj->rsc, - obj->l2miss, - obj->l3miss); - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->parent_ifindex); + nm_hash_update_val (h, obj->id); + nm_hash_update_val (h, obj->group); + nm_hash_update_val (h, obj->local); + nm_hash_update_in6addr (h, &obj->group6); + nm_hash_update_in6addr (h, &obj->local6); + nm_hash_update_val (h, obj->tos); + nm_hash_update_val (h, obj->ttl); + nm_hash_update_val (h, obj->ageing); + nm_hash_update_val (h, obj->limit); + nm_hash_update_val (h, obj->dst_port); + nm_hash_update_val (h, obj->src_port_min); + nm_hash_update_val (h, obj->src_port_max); + nm_hash_update_bools (h, obj->learning, + obj->proxy, + obj->rsc, + obj->l2miss, + obj->l3miss); } int @@ -5469,25 +5429,19 @@ nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan return 0; } -guint -nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj) +void +nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 469681301u); - if (obj) { - nm_hash_update_val (&h, obj->ifindex); - nm_hash_update_val (&h, obj->address); - nm_hash_update_val (&h, obj->plen); - nm_hash_update_val (&h, obj->peer_address); - nm_hash_update_val (&h, obj->addr_source); - nm_hash_update_val (&h, obj->timestamp); - nm_hash_update_val (&h, obj->lifetime); - nm_hash_update_val (&h, obj->preferred); - nm_hash_update_val (&h, obj->n_ifa_flags); - nm_hash_update_strarr (&h, obj->label); - } - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->ifindex); + nm_hash_update_val (h, obj->address); + nm_hash_update_val (h, obj->plen); + nm_hash_update_val (h, obj->peer_address); + nm_hash_update_val (h, obj->addr_source); + nm_hash_update_val (h, obj->timestamp); + nm_hash_update_val (h, obj->lifetime); + nm_hash_update_val (h, obj->preferred); + nm_hash_update_val (h, obj->n_ifa_flags); + nm_hash_update_strarr (h, obj->label); } int @@ -5507,24 +5461,18 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A return 0; } -guint -nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj) +void +nm_platform_ip6_address_hash_update (const NMPlatformIP6Address *obj, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 605908909u); - if (obj) { - nm_hash_update_val (&h, obj->ifindex); - nm_hash_update_in6addr (&h, &obj->address); - nm_hash_update_val (&h, obj->plen); - nm_hash_update_in6addr (&h, &obj->peer_address); - nm_hash_update_val (&h, obj->addr_source); - nm_hash_update_val (&h, obj->timestamp); - nm_hash_update_val (&h, obj->lifetime); - nm_hash_update_val (&h, obj->preferred); - nm_hash_update_val (&h, obj->n_ifa_flags); - } - return nm_hash_complete (&h); + nm_hash_update_val (h, obj->ifindex); + nm_hash_update_in6addr (h, &obj->address); + nm_hash_update_val (h, obj->plen); + nm_hash_update_in6addr (h, &obj->peer_address); + nm_hash_update_val (h, obj->addr_source); + nm_hash_update_val (h, obj->timestamp); + nm_hash_update_val (h, obj->lifetime); + nm_hash_update_val (h, obj->preferred); + nm_hash_update_val (h, obj->n_ifa_flags); } int @@ -5547,65 +5495,62 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A return 0; } -guint -nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type) +void +nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1228913327u); - nm_hash_update_val (&h, cmp_type); + nm_hash_update_val (h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - nm_hash_update_val (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); - nm_hash_update_val (&h, obj->plen); - nm_hash_update_val (&h, obj->metric); - nm_hash_update_val (&h, obj->tos); + nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_val (h, obj->plen); + nm_hash_update_val (h, obj->metric); + nm_hash_update_val (h, obj->tos); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_val (&h, obj->ifindex); - nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_val (&h, _ip_route_scope_inv_get_normalized (obj)); - nm_hash_update_val (&h, obj->gateway); - nm_hash_update_val (&h, obj->mss); - nm_hash_update_val (&h, obj->pref_src); - nm_hash_update_vals (&h, + nm_hash_update_val (h, obj->ifindex); + nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_val (h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_val (h, obj->gateway); + nm_hash_update_val (h, obj->mss); + nm_hash_update_val (h, obj->pref_src); + nm_hash_update_vals (h, obj->window, obj->cwnd, obj->initcwnd, obj->initrwnd, obj->mtu); - nm_hash_update_bools (&h, obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); + nm_hash_update_bools (h, obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - nm_hash_update_val (&h, obj->table_coerced); - nm_hash_update_val (&h, obj->ifindex); + nm_hash_update_val (h, obj->table_coerced); + nm_hash_update_val (h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (&h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); + nm_hash_update_val (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); else - nm_hash_update_val (&h, obj->network); - nm_hash_update_val (&h, obj->plen); - nm_hash_update_val (&h, obj->metric); - nm_hash_update_val (&h, obj->gateway); + nm_hash_update_val (h, obj->network); + nm_hash_update_val (h, obj->plen); + nm_hash_update_val (h, obj->metric); + nm_hash_update_val (h, obj->gateway); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_val (&h, _ip_route_scope_inv_get_normalized (obj)); + nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_val (h, _ip_route_scope_inv_get_normalized (obj)); } else { - nm_hash_update_val (&h, obj->rt_source); - nm_hash_update_val (&h, obj->scope_inv); + nm_hash_update_val (h, obj->rt_source); + nm_hash_update_val (h, obj->scope_inv); } - nm_hash_update_val (&h, obj->tos); - nm_hash_update_vals (&h, + nm_hash_update_val (h, obj->tos); + nm_hash_update_vals (h, obj->mss, obj->pref_src, obj->window, @@ -5613,16 +5558,15 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT obj->initcwnd, obj->initrwnd, obj->mtu); - nm_hash_update_bools (&h, obj->rt_cloned, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); + nm_hash_update_bools (h, obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); break; } } - return nm_hash_complete (&h); } int @@ -5702,75 +5646,71 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route return 0; } -guint -nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type) +void +nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) { - NMHashState h; - - nm_hash_init (&h, 1053326051u); - nm_hash_update_val (&h, cmp_type); + nm_hash_update_val (h, cmp_type); if (obj) { switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); - nm_hash_update_val (&h, obj->plen); - nm_hash_update_val (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); - nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); - nm_hash_update_val (&h, obj->src_plen); + nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_in6addr_prefix (h, &obj->network, obj->plen); + nm_hash_update_val (h, obj->plen); + nm_hash_update_val (h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_in6addr_prefix (h, &obj->src, obj->src_plen); + nm_hash_update_val (h, obj->src_plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_val (&h, obj->ifindex); - nm_hash_update_in6addr (&h, &obj->gateway); + nm_hash_update_val (h, obj->ifindex); + nm_hash_update_in6addr (h, &obj->gateway); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (&h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); + nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); else - nm_hash_update_val (&h, obj->table_coerced); - nm_hash_update_val (&h, obj->ifindex); + nm_hash_update_val (h, obj->table_coerced); + nm_hash_update_val (h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_in6addr_prefix (&h, &obj->network, obj->plen); + nm_hash_update_in6addr_prefix (h, &obj->network, obj->plen); else - nm_hash_update_in6addr (&h, &obj->network); - nm_hash_update_val (&h, obj->plen); + nm_hash_update_in6addr (h, &obj->network); + nm_hash_update_val (h, obj->plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (&h, nm_utils_ip6_route_metric_normalize (obj->metric)); + nm_hash_update_val (h, nm_utils_ip6_route_metric_normalize (obj->metric)); else - nm_hash_update_val (&h, obj->metric); - nm_hash_update_in6addr (&h, &obj->gateway); - nm_hash_update_in6addr (&h, &obj->pref_src); + nm_hash_update_val (h, obj->metric); + nm_hash_update_in6addr (h, &obj->gateway); + nm_hash_update_in6addr (h, &obj->pref_src); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - nm_hash_update_in6addr_prefix (&h, &obj->src, obj->src_plen); - nm_hash_update_val (&h, obj->src_plen); - nm_hash_update_val (&h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); + nm_hash_update_in6addr_prefix (h, &obj->src, obj->src_plen); + nm_hash_update_val (h, obj->src_plen); + nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); } else { - nm_hash_update_in6addr (&h, &obj->src); - nm_hash_update_val (&h, obj->src_plen); - nm_hash_update_val (&h, obj->rt_source); + nm_hash_update_in6addr (h, &obj->src); + nm_hash_update_val (h, obj->src_plen); + nm_hash_update_val (h, obj->rt_source); } - nm_hash_update_val (&h, obj->mss); - nm_hash_update_bools (&h, obj->rt_cloned, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); - nm_hash_update_val (&h, obj->window); - nm_hash_update_val (&h, obj->cwnd); - nm_hash_update_val (&h, obj->initcwnd); - nm_hash_update_val (&h, obj->initrwnd); - nm_hash_update_val (&h, obj->mtu); + nm_hash_update_val (h, obj->mss); + nm_hash_update_bools (h, obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu); + nm_hash_update_val (h, obj->window); + nm_hash_update_val (h, obj->cwnd); + nm_hash_update_val (h, obj->initcwnd); + nm_hash_update_val (h, obj->initrwnd); + nm_hash_update_val (h, obj->mtu); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (&h, _route_pref_normalize (obj->rt_pref)); + nm_hash_update_val (h, _route_pref_normalize (obj->rt_pref)); else - nm_hash_update_val (&h, obj->rt_pref); + nm_hash_update_val (h, obj->rt_pref); break; } } - return nm_hash_complete (&h); } int diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index ee08a40f4e..b01c54447d 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -1300,32 +1300,20 @@ nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6 return nm_platform_ip6_route_cmp (a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL); } -guint nm_platform_link_hash (const NMPlatformLink *obj); -guint nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj); -guint nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj); -guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type); -guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type); -guint nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj); -guint nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj); -guint nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj); -guint nm_platform_lnk_ipip_hash (const NMPlatformLnkIpIp *obj); -guint nm_platform_lnk_macsec_hash (const NMPlatformLnkMacsec *obj); -guint nm_platform_lnk_macvlan_hash (const NMPlatformLnkMacvlan *obj); -guint nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj); -guint nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj); -guint nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj); - -static inline guint -nm_platform_ip4_route_hash_full (const NMPlatformIP4Route *obj) -{ - return nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL); -} - -static inline guint -nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *obj) -{ - return nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL); -} +void nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h); +void nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h); +void nm_platform_ip6_address_hash_update (const NMPlatformIP6Address *obj, NMHashState *h); +void nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h); +void nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h); +void nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h); +void nm_platform_lnk_infiniband_hash_update (const NMPlatformLnkInfiniband *obj, NMHashState *h); +void nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState *h); +void nm_platform_lnk_ipip_hash_update (const NMPlatformLnkIpIp *obj, NMHashState *h); +void nm_platform_lnk_macsec_hash_update (const NMPlatformLnkMacsec *obj, NMHashState *h); +void nm_platform_lnk_macvlan_hash_update (const NMPlatformLnkMacvlan *obj, NMHashState *h); +void nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState *h); +void nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h); +void nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h); NMPlatformKernelSupportFlags nm_platform_check_kernel_support (NMPlatform *self, NMPlatformKernelSupportFlags request_flags); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index bec3f44a37..376bb24c31 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -86,16 +86,17 @@ struct _NMPCache { static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class; -static guint -_idx_obj_id_hash (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +static void +_idx_obj_id_hash_update (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + NMHashState *h) { const NMPObject *o = (NMPObject *) obj; nm_assert (idx_type && idx_type->klass == &_dedup_multi_idx_type_class); nm_assert (NMP_OBJECT_GET_TYPE (o) != NMP_OBJECT_TYPE_UNKNOWN); - return nmp_object_id_hash (o); + nmp_object_id_hash_update (o, h); } static gboolean @@ -113,33 +114,11 @@ _idx_obj_id_equal (const NMDedupMultiIdxType *idx_type, return nmp_object_id_equal (o_a, o_b); } -/* the return value of _idx_obj_part() encodes 3 things: - * 1) for idx_obj_partitionable(), it returns 0 or non-zero. - * 2) for idx_obj_partition_hash(), it returns the hash value (which - * must never be zero not to clash with idx_obj_partitionable(). - * 3) for idx_obj_partition_equal(), returns 0 or 1 depending - * on whether the objects are equal. - * - * _HASH_NON_ZERO() is used to for case 2), to avoid that the a zero hash value - * is returned. - * - * Actually, nm_hash_complete() never returns zero. This code is only - * here as a safeguard and a reminder that the has MUST not be zero. */ -static inline guint -_HASH_NON_ZERO (NMHashState *h) -{ - guint v; - - v = nm_hash_complete (h); - nm_assert (v != 0); - return v; -} - static guint _idx_obj_part (const DedupMultiIdxType *idx_type, - gboolean request_hash, const NMPObject *obj_a, - const NMPObject *obj_b) + const NMPObject *obj_b, + NMHashState *h) { NMPObjectType obj_type; @@ -151,21 +130,17 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, nm_assert (obj_a); nm_assert (NMP_OBJECT_GET_TYPE (obj_a) != NMP_OBJECT_TYPE_UNKNOWN); nm_assert (!obj_b || (NMP_OBJECT_GET_TYPE (obj_b) != NMP_OBJECT_TYPE_UNKNOWN)); - nm_assert (!request_hash || !obj_b); + nm_assert (!h || !obj_b); switch (idx_type->cache_id_type) { case NMP_CACHE_ID_TYPE_OBJECT_TYPE: if (obj_b) return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b); - if (request_hash) { - NMHashState h; - - nm_hash_init (&h, 487703243u); - nm_hash_update_vals (&h, + if (h) { + nm_hash_update_vals (h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE (obj_a)); - return _HASH_NON_ZERO (&h); } return 1; @@ -174,6 +149,8 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, /* first check, whether obj_a is suitable for this idx_type. * If not, return 0 (which is correct for partitionable(), hash() and equal() * functions. */ + if (h) + nm_hash_update_val (h, obj_a); return 0; } if (obj_b) { @@ -181,14 +158,9 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, return NMP_OBJECT_GET_TYPE (obj_b) == NMP_OBJECT_TYPE_LINK && nm_streq (obj_a->link.name, obj_b->link.name); } - if (request_hash) { - NMHashState h; - - /* we request a hash from obj_a. Hash the relevant parts. */ - nm_hash_init (&h, 2126752699u); - nm_hash_update_val (&h, idx_type->cache_id_type); - nm_hash_update_strarr (&h, obj_a->link.name); - return _HASH_NON_ZERO (&h); + if (h) { + nm_hash_update_val (h, idx_type->cache_id_type); + nm_hash_update_strarr (h, obj_a->link.name); } /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ return 1; @@ -197,21 +169,20 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, if ( !NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_a), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) || !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (&obj_a->ip_route) - || !nmp_object_is_visible (obj_a)) + || !nmp_object_is_visible (obj_a)) { + if (h) + nm_hash_update_val (h, obj_a); return 0; + } if (obj_b) { return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b) && NM_PLATFORM_IP_ROUTE_IS_DEFAULT (&obj_b->ip_route) && nmp_object_is_visible (obj_b); } - if (request_hash) { - NMHashState h; - - nm_hash_init (&h, 4278960223u); - nm_hash_update_vals (&h, + if (h) { + nm_hash_update_vals (h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE (obj_a)); - return _HASH_NON_ZERO (&h); } return 1; @@ -220,22 +191,21 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, NMP_OBJECT_TYPE_IP6_ADDRESS, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) - || !nmp_object_is_visible (obj_a)) + || !nmp_object_is_visible (obj_a)) { + if (h) + nm_hash_update_val (h, obj_a); return 0; + } nm_assert (obj_a->object.ifindex > 0); if (obj_b) { return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b) && obj_a->object.ifindex == obj_b->object.ifindex && nmp_object_is_visible (obj_b); } - if (request_hash) { - NMHashState h; - - nm_hash_init (&h, 920415631u); - nm_hash_update_vals (&h, + if (h) { + nm_hash_update_vals (h, idx_type->cache_id_type, obj_a->object.ifindex); - return _HASH_NON_ZERO (&h); } return 1; @@ -243,8 +213,11 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, obj_type = NMP_OBJECT_GET_TYPE (obj_a); if ( !NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) - || obj_a->object.ifindex <= 0) + || obj_a->object.ifindex <= 0) { + if (h) + nm_hash_update_val (h, obj_a); return 0; + } if (obj_b) { return obj_type == NMP_OBJECT_GET_TYPE (obj_b) && obj_b->object.ifindex > 0 @@ -252,19 +225,12 @@ _idx_obj_part (const DedupMultiIdxType *idx_type, ? (nm_platform_ip4_route_cmp (&obj_a->ip4_route, &obj_b->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0) : (nm_platform_ip6_route_cmp (&obj_a->ip6_route, &obj_b->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0)); } - if (request_hash) { - NMHashState h; - guint h2; - - h2 = (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) - ? nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) - : nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID); - - nm_hash_init (&h, 778646573u); - nm_hash_update_vals (&h, - idx_type->cache_id_type, - h2); - return _HASH_NON_ZERO (&h); + if (h) { + nm_hash_update_val (h, idx_type->cache_id_type); + if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) + nm_platform_ip4_route_hash_update (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, h); + else + nm_platform_ip6_route_hash_update (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, h); } return 1; @@ -281,19 +247,20 @@ _idx_obj_partitionable (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj) { return _idx_obj_part ((DedupMultiIdxType *) idx_type, - FALSE, (NMPObject *) obj, + NULL, NULL) != 0; } -static guint -_idx_obj_partition_hash (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +static void +_idx_obj_partition_hash_update (const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj *obj, + NMHashState *h) { - return _idx_obj_part ((DedupMultiIdxType *) idx_type, - TRUE, - (NMPObject *) obj, - NULL); + _idx_obj_part ((DedupMultiIdxType *) idx_type, + (NMPObject *) obj, + NULL, + h); } static gboolean @@ -302,16 +269,16 @@ _idx_obj_partition_equal (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj_b) { return _idx_obj_part ((DedupMultiIdxType *) idx_type, - FALSE, (NMPObject *) obj_a, - (NMPObject *) obj_b); + (NMPObject *) obj_b, + NULL); } static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = { - .idx_obj_id_hash = _idx_obj_id_hash, + .idx_obj_id_hash_update = _idx_obj_id_hash_update, .idx_obj_id_equal = _idx_obj_id_equal, .idx_obj_partitionable = _idx_obj_partitionable, - .idx_obj_partition_hash = _idx_obj_partition_hash, + .idx_obj_partition_hash_update = _idx_obj_partition_hash_update, .idx_obj_partition_equal = _idx_obj_partition_equal, }; @@ -771,63 +738,48 @@ _vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s", obj->peer_address != obj->address ? nm_utils_inet4_ntop (nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen), buf2) : ""); _vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1)); -guint -nmp_object_hash (const NMPObject *obj) +void +nmp_object_hash_update (const NMPObject *obj, NMHashState *h) { const NMPClass *klass; - NMHashState h; - if (!obj) - return 0; - - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), 0); + g_return_if_fail (NMP_OBJECT_IS_VALID (obj)); klass = NMP_OBJECT_GET_CLASS (obj); - nm_hash_init (&h, 816200863u); - nm_hash_update_val (&h, klass->obj_type); - if (klass->cmd_obj_hash) - nm_hash_update_val (&h, klass->cmd_obj_hash (obj)); - else if (klass->cmd_plobj_hash) - nm_hash_update_val (&h, klass->cmd_plobj_hash (&obj->object)); + nm_hash_update_val (h, klass->obj_type); + if (klass->cmd_obj_hash_update) + klass->cmd_obj_hash_update (obj, h); + else if (klass->cmd_plobj_hash_update) + klass->cmd_plobj_hash_update (&obj->object, h); else - nm_hash_update_val (&h, obj); - - return nm_hash_complete (&h); + nm_hash_update_val (h, obj); } -static guint -_vt_cmd_obj_hash_link (const NMPObject *obj) +static void +_vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h) { - NMHashState h; - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK); - nm_hash_init (&h, 3448776161u); - nm_hash_update_val (&h, nm_platform_link_hash (&obj->link)); - nm_hash_update_val (&h, obj->_link.netlink.is_in_netlink); + nm_platform_link_hash_update (&obj->link, h); + nm_hash_update_val (h, obj->_link.netlink.is_in_netlink); if (obj->_link.netlink.lnk) - nm_hash_update_val (&h, nmp_object_hash (obj->_link.netlink.lnk)); - nm_hash_update_val (&h, obj->_link.udev.device); - return nm_hash_complete (&h); + nmp_object_hash_update (obj->_link.netlink.lnk, h); + nm_hash_update_val (h, obj->_link.udev.device); } -static guint -_vt_cmd_obj_hash_lnk_vlan (const NMPObject *obj) +static void +_vt_cmd_obj_hash_update_lnk_vlan (const NMPObject *obj, NMHashState *h) { - NMHashState h; - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_VLAN); - nm_hash_init (&h, 914932607u); - nm_hash_update_val (&h, nm_platform_lnk_vlan_hash (&obj->lnk_vlan)); + nm_platform_lnk_vlan_hash_update (&obj->lnk_vlan, h); _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_ingress_qos_map, obj->_lnk_vlan.ingress_qos_map, - &h); + h); _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_egress_qos_map, obj->_lnk_vlan.egress_qos_map, - &h); - return nm_hash_complete (&h); + h); } int @@ -1033,7 +985,7 @@ nmp_object_id_cmp (const NMPObject *obj1, const NMPObject *obj2) g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), FALSE); klass = NMP_OBJECT_GET_CLASS (obj1); - nm_assert (!klass->cmd_plobj_id_hash == !klass->cmd_plobj_id_cmp); + nm_assert (!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); klass2 = NMP_OBJECT_GET_CLASS (obj2); nm_assert (klass); @@ -1095,63 +1047,84 @@ _vt_cmd_plobj_id_cmp_ip6_route (const NMPlatformObject *obj1, const NMPlatformOb return nm_platform_ip6_route_cmp ((NMPlatformIP6Route *) obj1, (NMPlatformIP6Route *) obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); } +void +nmp_object_id_hash_update (const NMPObject *obj, NMHashState *h) +{ + const NMPClass *klass; + + g_return_if_fail (NMP_OBJECT_IS_VALID (obj)); + + klass = NMP_OBJECT_GET_CLASS (obj); + + nm_assert (!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); + + if (!klass->cmd_plobj_id_hash_update) { + /* The klass doesn't implement ID compare. It means, to use pointer + * equality. */ + nm_hash_update_val (h, obj); + return; + } + + nm_hash_update_val (h, klass->obj_type); + klass->cmd_plobj_id_hash_update (&obj->object, h); +} + guint nmp_object_id_hash (const NMPObject *obj) { - const NMPClass *klass; + NMHashState h; if (!obj) return 0; - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), 0); - - klass = NMP_OBJECT_GET_CLASS (obj); - - nm_assert (!klass->cmd_plobj_id_hash == !klass->cmd_plobj_id_cmp); - - if (!klass->cmd_plobj_id_hash) { - /* The klass doesn't implement ID compare. It means, to use pointer - * equality. */ - return nm_hash_ptr (obj); - } - - return klass->cmd_plobj_id_hash (&obj->object); + nm_hash_init (&h, 914932607u); + nmp_object_id_hash_update (obj, &h); + return nm_hash_complete (&h); } -#define _vt_cmd_plobj_id_hash(type, plat_type, hash_seed, cmd) \ -static guint \ -_vt_cmd_plobj_id_hash_##type (const NMPlatformObject *_obj) \ +#define _vt_cmd_plobj_id_hash_update(type, plat_type, cmd) \ +static void \ +_vt_cmd_plobj_id_hash_update_##type (const NMPlatformObject *_obj, NMHashState *h) \ { \ const plat_type *const obj = (const plat_type *) _obj; \ - NMHashState h; \ - nm_hash_init (&h, (hash_seed)); \ { cmd; } \ - return nm_hash_complete (&h); \ } -_vt_cmd_plobj_id_hash (link, NMPlatformLink, 3982791431u, { - nm_hash_update_val (&h, obj->ifindex); +_vt_cmd_plobj_id_hash_update (link, NMPlatformLink, { + nm_hash_update_val (h, obj->ifindex); }) -_vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, 3591309853u, { - nm_hash_update_vals (&h, +_vt_cmd_plobj_id_hash_update (ip4_address, NMPlatformIP4Address, { + nm_hash_update_vals (h, obj->ifindex, obj->plen, obj->address, /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen)); }) -_vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, 2907861637u, { - nm_hash_update_vals (&h, +_vt_cmd_plobj_id_hash_update (ip6_address, NMPlatformIP6Address, { + nm_hash_update_vals (h, obj->ifindex, /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ obj->address); }) -_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, 1038302471u, { - nm_hash_update_val (&h, nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); +_vt_cmd_plobj_id_hash_update (ip4_route, NMPlatformIP4Route, { + nm_platform_ip4_route_hash_update (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); }) -_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, 1233384151u, { - nm_hash_update_val (&h, nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)); +_vt_cmd_plobj_id_hash_update (ip6_route, NMPlatformIP6Route, { + nm_platform_ip6_route_hash_update (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); }) +static inline void +_vt_cmd_plobj_hash_update_ip4_route (const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_ip4_route_hash_update ((const NMPlatformIP4Route *) obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, h); +} + +static inline void +_vt_cmd_plobj_hash_update_ip6_route (const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_ip6_route_hash_update ((const NMPlatformIP6Route *) obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, h); +} + gboolean nmp_object_is_alive (const NMPObject *obj) { @@ -1271,26 +1244,12 @@ _vt_dedup_obj_clone (const NMDedupMultiObj *obj) return (const NMDedupMultiObj *) nmp_object_clone ((const NMPObject *) obj, FALSE); } -static guint -_vt_dedup_obj_full_hash (const NMDedupMultiObj *obj) -{ - return nmp_object_hash ((NMPObject *) obj); -} - -static gboolean -_vt_dedup_obj_full_equal (const NMDedupMultiObj *obj_a, - const NMDedupMultiObj *obj_b) -{ - return nmp_object_equal ((NMPObject *) obj_a, - (NMPObject *) obj_b); -} - #define DEDUP_MULTI_OBJ_CLASS_INIT() \ { \ .obj_clone = _vt_dedup_obj_clone, \ .obj_destroy = _vt_dedup_obj_destroy, \ - .obj_full_hash = _vt_dedup_obj_full_hash, \ - .obj_full_equal = _vt_dedup_obj_full_equal, \ + .obj_full_hash_update = (void (*)(const NMDedupMultiObj *obj, NMHashState *h)) nmp_object_hash_update, \ + .obj_full_equal = (gboolean (*)(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b)) nmp_object_equal, \ } /*****************************************************************************/ @@ -1523,7 +1482,6 @@ _L (const NMPLookup *lookup) nm_assert (lookup); _dedup_multi_idx_type_init (&idx_type, lookup->cache_id_type); nm_assert (idx_type.parent.klass->idx_obj_partitionable ((NMDedupMultiIdxType *) &idx_type, (NMDedupMultiObj *) &lookup->selector_obj)); - nm_assert (idx_type.parent.klass->idx_obj_partition_hash ((NMDedupMultiIdxType *) &idx_type, (NMDedupMultiObj *) &lookup->selector_obj) > 0); #endif return lookup; } @@ -2515,7 +2473,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK, .signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED, .supported_cache_ids = _supported_cache_ids_link, - .cmd_obj_hash = _vt_cmd_obj_hash_link, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_link, .cmd_obj_cmp = _vt_cmd_obj_cmp_link, .cmd_obj_copy = _vt_cmd_obj_copy_link, .cmd_obj_dispose = _vt_cmd_obj_dispose_link, @@ -2524,10 +2482,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_to_string = _vt_cmd_obj_to_string_link, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_link, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_link, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_link, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_link, .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_link, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_link_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_link_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_link_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_link_cmp, }, [NMP_OBJECT_TYPE_IP4_ADDRESS - 1] = { @@ -2544,10 +2502,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_address, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_address, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_address, .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_address, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_address_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_address_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_ip4_address_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_address_cmp, }, [NMP_OBJECT_TYPE_IP6_ADDRESS - 1] = { @@ -2564,10 +2522,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_address, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_address, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address, .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_address, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_address_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_address_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_ip6_address_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_address_cmp }, [NMP_OBJECT_TYPE_IP4_ROUTE - 1] = { @@ -2584,10 +2542,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route, .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash_full, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip4_route, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp_full, }, [NMP_OBJECT_TYPE_IP6_ROUTE - 1] = { @@ -2604,10 +2562,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route, .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash_full, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip6_route, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp_full, }, [NMP_OBJECT_TYPE_LNK_GRE - 1] = { @@ -2618,7 +2576,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "gre", .lnk_link_type = NM_LINK_TYPE_GRE, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_gre_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, }, [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = { @@ -2629,7 +2587,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "infiniband", .lnk_link_type = NM_LINK_TYPE_INFINIBAND, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_infiniband_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_infiniband_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_infiniband_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_infiniband_cmp, }, [NMP_OBJECT_TYPE_LNK_IP6TNL - 1] = { @@ -2640,7 +2598,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "ip6tnl", .lnk_link_type = NM_LINK_TYPE_IP6TNL, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_ip6tnl_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, }, [NMP_OBJECT_TYPE_LNK_IPIP - 1] = { @@ -2651,7 +2609,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "ipip", .lnk_link_type = NM_LINK_TYPE_IPIP, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ipip_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_ipip_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ipip_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ipip_cmp, }, [NMP_OBJECT_TYPE_LNK_MACSEC - 1] = { @@ -2662,7 +2620,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "macsec", .lnk_link_type = NM_LINK_TYPE_MACSEC, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macsec_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_macsec_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macsec_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macsec_cmp, }, [NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = { @@ -2673,7 +2631,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "macvlan", .lnk_link_type = NM_LINK_TYPE_MACVLAN, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_macvlan_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macvlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp, }, [NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = { @@ -2684,7 +2642,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "macvtap", .lnk_link_type = NM_LINK_TYPE_MACVTAP, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_macvlan_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macvlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp, }, [NMP_OBJECT_TYPE_LNK_SIT - 1] = { @@ -2695,7 +2653,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "sit", .lnk_link_type = NM_LINK_TYPE_SIT, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_sit_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_sit_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_sit_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_sit_cmp, }, [NMP_OBJECT_TYPE_LNK_VLAN - 1] = { @@ -2705,13 +2663,13 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .sizeof_public = sizeof (NMPlatformLnkVlan), .obj_type_name = "vlan", .lnk_link_type = NM_LINK_TYPE_VLAN, - .cmd_obj_hash = _vt_cmd_obj_hash_lnk_vlan, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_vlan, .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_vlan, .cmd_obj_copy = _vt_cmd_obj_copy_lnk_vlan, .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_vlan, .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_vlan, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vlan_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_vlan_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp, }, [NMP_OBJECT_TYPE_LNK_VXLAN - 1] = { @@ -2722,7 +2680,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .obj_type_name = "vxlan", .lnk_link_type = NM_LINK_TYPE_VXLAN, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vxlan_to_string, - .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_lnk_vxlan_hash, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vxlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp, }, }; diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 48c27fa120..41fd08cb7c 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -115,7 +115,7 @@ typedef struct { /* Only for NMPObjectLnk* types. */ NMLinkType lnk_link_type; - guint (*cmd_obj_hash) (const NMPObject *obj); + void (*cmd_obj_hash_update) (const NMPObject *obj, NMHashState *h); int (*cmd_obj_cmp) (const NMPObject *obj1, const NMPObject *obj2); void (*cmd_obj_copy) (NMPObject *dst, const NMPObject *src); void (*cmd_obj_dispose) (NMPObject *obj); @@ -126,10 +126,10 @@ typedef struct { /* functions that operate on NMPlatformObject */ void (*cmd_plobj_id_copy) (NMPlatformObject *dst, const NMPlatformObject *src); int (*cmd_plobj_id_cmp) (const NMPlatformObject *obj1, const NMPlatformObject *obj2); - guint (*cmd_plobj_id_hash) (const NMPlatformObject *obj); + void (*cmd_plobj_id_hash_update) (const NMPlatformObject *obj, NMHashState *h); const char *(*cmd_plobj_to_string_id) (const NMPlatformObject *obj, char *buf, gsize buf_size); const char *(*cmd_plobj_to_string) (const NMPlatformObject *obj, char *buf, gsize len); - guint (*cmd_plobj_hash) (const NMPlatformObject *obj); + void (*cmd_plobj_hash_update) (const NMPlatformObject *obj, NMHashState *h); int (*cmd_plobj_cmp) (const NMPlatformObject *obj1, const NMPlatformObject *obj2); } NMPClass; @@ -469,13 +469,14 @@ const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifinde const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address); const char *nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); -guint nmp_object_hash (const NMPObject *obj); +void nmp_object_hash_update (const NMPObject *obj, NMHashState *h); int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2); gboolean nmp_object_equal (const NMPObject *obj1, const NMPObject *obj2); void nmp_object_copy (NMPObject *dst, const NMPObject *src, gboolean id_only); NMPObject *nmp_object_clone (const NMPObject *obj, gboolean id_only); int nmp_object_id_cmp (const NMPObject *obj1, const NMPObject *obj2); +void nmp_object_id_hash_update (const NMPObject *obj, NMHashState *h); guint nmp_object_id_hash (const NMPObject *obj); static inline gboolean From f17a20c568c77c737a36aa908b3940d4bbfdf287 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 13:28:25 +0200 Subject: [PATCH 11/12] core: refactor hashing to use reduce calls to siphash24_compress() This makes for example nm_platform_link_hash_update() by roughly 25% faster. --- src/devices/nm-device.c | 5 +- src/platform/nm-platform.c | 510 ++++++++++++++++++++----------------- src/platform/nm-platform.h | 2 +- src/platform/nmp-object.c | 5 +- 4 files changed, 289 insertions(+), 233 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index a6a0fb35bc..e7e076ec23 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2861,8 +2861,9 @@ _v4_has_shadowed_routes_detect_hash (const IP4RPFilterData *d) NMHashState h; nm_hash_init (&h, 1105201169u); - nm_hash_update_val (&h, d->network); - nm_hash_update_val (&h, d->plen); + nm_hash_update_vals (&h, + d->network, + d->plen); return nm_hash_complete (&h); } diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index cd0e474a61..56c36c2630 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5129,26 +5129,25 @@ nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h) nm_hash_update_vals (h, obj->ifindex, obj->master, - obj->parent); - nm_hash_update_val (h, obj->type); - nm_hash_update_strarr (h, obj->name); - nm_hash_update_vals (h, + obj->parent, obj->n_ifi_flags, - obj->mtu); - nm_hash_update_bools (h, obj->connected, - obj->initialized); - nm_hash_update_val (h, obj->arptype); - nm_hash_update_val (h, obj->inet6_addr_gen_mode_inv); + obj->mtu, + obj->type, + obj->arptype, + obj->inet6_addr_gen_mode_inv, + obj->inet6_token, + obj->rx_packets, + obj->rx_bytes, + obj->tx_packets, + obj->tx_bytes, + NM_HASH_COMBINE_BOOLS (guint8, + obj->connected, + obj->initialized)); + nm_hash_update_strarr (h, obj->name); nm_hash_update_str0 (h, obj->kind); nm_hash_update_str0 (h, obj->driver); /* nm_hash_update_mem() also hashes the length obj->addr.len */ nm_hash_update_mem (h, obj->addr.data, obj->addr.len); - nm_hash_update (h, &obj->inet6_token, sizeof (obj->inet6_token)); - nm_hash_update_vals (h, - obj->rx_packets, - obj->rx_bytes, - obj->tx_packets, - obj->tx_bytes); } int @@ -5182,16 +5181,17 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) void nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_val (h, obj->input_flags); - nm_hash_update_val (h, obj->output_flags); - nm_hash_update_val (h, obj->input_key); - nm_hash_update_val (h, obj->output_key); - nm_hash_update_val (h, obj->local); - nm_hash_update_val (h, obj->remote); - nm_hash_update_val (h, obj->ttl); - nm_hash_update_val (h, obj->tos); - nm_hash_update_bool (h, obj->path_mtu_discovery); + nm_hash_update_vals (h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->input_flags, + obj->output_flags, + obj->input_key, + obj->output_key, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery); } int @@ -5230,14 +5230,15 @@ nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatfo void nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_in6addr (h, &obj->local); - nm_hash_update_in6addr (h, &obj->remote); - nm_hash_update_val (h, obj->ttl); - nm_hash_update_val (h, obj->tclass); - nm_hash_update_val (h, obj->encap_limit); - nm_hash_update_val (h, obj->flow_label); - nm_hash_update_val (h, obj->proto); + nm_hash_update_vals (h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tclass, + obj->encap_limit, + obj->proto, + obj->flow_label); } int @@ -5258,12 +5259,13 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6 void nm_platform_lnk_ipip_hash_update (const NMPlatformLnkIpIp *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_val (h, obj->local); - nm_hash_update_val (h, obj->remote); - nm_hash_update_val (h, obj->ttl); - nm_hash_update_val (h, obj->tos); - nm_hash_update_bool (h, obj->path_mtu_discovery); + nm_hash_update_vals (h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery); } int @@ -5282,21 +5284,21 @@ nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b void nm_platform_lnk_macsec_hash_update (const NMPlatformLnkMacsec *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_val (h, obj->window); nm_hash_update_vals (h, + obj->parent_ifindex, + obj->sci, obj->cipher_suite, - obj->sci); - nm_hash_update_vals (h, + obj->window, obj->icv_length, obj->encoding_sa, - obj->validation); - nm_hash_update_bools (h, obj->encrypt, - obj->protect, - obj->include_sci, - obj->es, - obj->scb, - obj->replay_protect); + obj->validation, + NM_HASH_COMBINE_BOOLS (guint8, + obj->encrypt, + obj->protect, + obj->include_sci, + obj->es, + obj->scb, + obj->replay_protect)); } int @@ -5322,9 +5324,11 @@ nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMac void nm_platform_lnk_macvlan_hash_update (const NMPlatformLnkMacvlan *obj, NMHashState *h ) { - nm_hash_update_val (h, obj->mode); - nm_hash_update_bools (h, obj->no_promisc, - obj->tap); + nm_hash_update_vals (h, + obj->mode, + NM_HASH_COMBINE_BOOLS (guint8, + obj->no_promisc, + obj->tap)); } int @@ -5340,14 +5344,15 @@ nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkM void nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_val (h, obj->local); - nm_hash_update_val (h, obj->remote); - nm_hash_update_val (h, obj->ttl); - nm_hash_update_val (h, obj->tos); - nm_hash_update_bool (h, obj->path_mtu_discovery); - nm_hash_update_val (h, obj->flags); - nm_hash_update_val (h, obj->proto); + nm_hash_update_vals (h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->flags, + obj->ttl, + obj->tos, + obj->proto, + (bool) obj->path_mtu_discovery); } int @@ -5368,8 +5373,9 @@ nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) void nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h) { - nm_hash_update_val (h, obj->id); - nm_hash_update_val (h, obj->flags); + nm_hash_update_vals (h, + obj->id, + obj->flags); } int @@ -5384,24 +5390,26 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b void nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h) { - nm_hash_update_val (h, obj->parent_ifindex); - nm_hash_update_val (h, obj->id); - nm_hash_update_val (h, obj->group); - nm_hash_update_val (h, obj->local); - nm_hash_update_in6addr (h, &obj->group6); - nm_hash_update_in6addr (h, &obj->local6); - nm_hash_update_val (h, obj->tos); - nm_hash_update_val (h, obj->ttl); - nm_hash_update_val (h, obj->ageing); - nm_hash_update_val (h, obj->limit); - nm_hash_update_val (h, obj->dst_port); - nm_hash_update_val (h, obj->src_port_min); - nm_hash_update_val (h, obj->src_port_max); - nm_hash_update_bools (h, obj->learning, - obj->proxy, - obj->rsc, - obj->l2miss, - obj->l3miss); + nm_hash_update_vals (h, + obj->group6, + obj->local6, + obj->group, + obj->local, + obj->parent_ifindex, + obj->id, + obj->ageing, + obj->limit, + obj->dst_port, + obj->src_port_min, + obj->src_port_max, + obj->tos, + obj->ttl, + NM_HASH_COMBINE_BOOLS (guint8, + obj->learning, + obj->proxy, + obj->rsc, + obj->l2miss, + obj->l3miss)); } int @@ -5432,15 +5440,16 @@ nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan void nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h) { - nm_hash_update_val (h, obj->ifindex); - nm_hash_update_val (h, obj->address); - nm_hash_update_val (h, obj->plen); - nm_hash_update_val (h, obj->peer_address); - nm_hash_update_val (h, obj->addr_source); - nm_hash_update_val (h, obj->timestamp); - nm_hash_update_val (h, obj->lifetime); - nm_hash_update_val (h, obj->preferred); - nm_hash_update_val (h, obj->n_ifa_flags); + nm_hash_update_vals (h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address); nm_hash_update_strarr (h, obj->label); } @@ -5464,15 +5473,16 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A void nm_platform_ip6_address_hash_update (const NMPlatformIP6Address *obj, NMHashState *h) { - nm_hash_update_val (h, obj->ifindex); - nm_hash_update_in6addr (h, &obj->address); - nm_hash_update_val (h, obj->plen); - nm_hash_update_in6addr (h, &obj->peer_address); - nm_hash_update_val (h, obj->addr_source); - nm_hash_update_val (h, obj->timestamp); - nm_hash_update_val (h, obj->lifetime); - nm_hash_update_val (h, obj->preferred); - nm_hash_update_val (h, obj->n_ifa_flags); + nm_hash_update_vals (h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address); } int @@ -5498,74 +5508,97 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A void nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) { - nm_hash_update_val (h, cmp_type); - if (obj) { - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - nm_hash_update_val (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); - nm_hash_update_val (h, obj->plen); - nm_hash_update_val (h, obj->metric); - nm_hash_update_val (h, obj->tos); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_val (h, obj->ifindex); - nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_val (h, _ip_route_scope_inv_get_normalized (obj)); - nm_hash_update_val (h, obj->gateway); - nm_hash_update_val (h, obj->mss); - nm_hash_update_val (h, obj->pref_src); - nm_hash_update_vals (h, - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu); - nm_hash_update_bools (h, obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); - } - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - else - nm_hash_update_val (h, obj->table_coerced); - nm_hash_update_val (h, obj->ifindex); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); - else - nm_hash_update_val (h, obj->network); - nm_hash_update_val (h, obj->plen); - nm_hash_update_val (h, obj->metric); - nm_hash_update_val (h, obj->gateway); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - nm_hash_update_val (h, _ip_route_scope_inv_get_normalized (obj)); - } else { - nm_hash_update_val (h, obj->rt_source); - nm_hash_update_val (h, obj->scope_inv); - } - nm_hash_update_val (h, obj->tos); - nm_hash_update_vals (h, - obj->mss, - obj->pref_src, - obj->window, - obj->cwnd, - obj->initcwnd, - obj->initrwnd, - obj->mtu); - nm_hash_update_bools (h, obj->rt_cloned, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); - break; - } + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), + obj->plen, + obj->metric, + obj->tos); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), + obj->plen, + obj->metric, + obj->tos, + /* on top of WEAK_ID: */ + obj->ifindex, + nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), + _ip_route_scope_inv_get_normalized (obj), + obj->gateway, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + NM_HASH_COMBINE_BOOLS (guint8, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + obj->ifindex, + nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), + obj->plen, + obj->metric, + obj->gateway, + nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), + _ip_route_scope_inv_get_normalized (obj), + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + NM_HASH_COMBINE_BOOLS (guint8, + obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals (h, + cmp_type, + obj->table_coerced, + obj->ifindex, + obj->network, + obj->plen, + obj->metric, + obj->gateway, + obj->rt_source, + obj->scope_inv, + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + NM_HASH_COMBINE_BOOLS (guint8, + obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; } } @@ -5649,67 +5682,88 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route void nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h) { - nm_hash_update_val (h, cmp_type); - if (obj) { - switch (cmp_type) { - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: - nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - nm_hash_update_in6addr_prefix (h, &obj->network, obj->plen); - nm_hash_update_val (h, obj->plen); - nm_hash_update_val (h, nm_utils_ip6_route_metric_normalize (obj->metric)); - nm_hash_update_in6addr_prefix (h, &obj->src, obj->src_plen); - nm_hash_update_val (h, obj->src_plen); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { - nm_hash_update_val (h, obj->ifindex); - nm_hash_update_in6addr (h, &obj->gateway); - } - break; - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: - case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (h, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE)); - else - nm_hash_update_val (h, obj->table_coerced); - nm_hash_update_val (h, obj->ifindex); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_in6addr_prefix (h, &obj->network, obj->plen); - else - nm_hash_update_in6addr (h, &obj->network); - nm_hash_update_val (h, obj->plen); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (h, nm_utils_ip6_route_metric_normalize (obj->metric)); - else - nm_hash_update_val (h, obj->metric); - nm_hash_update_in6addr (h, &obj->gateway); - nm_hash_update_in6addr (h, &obj->pref_src); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { - nm_hash_update_in6addr_prefix (h, &obj->src, obj->src_plen); - nm_hash_update_val (h, obj->src_plen); - nm_hash_update_val (h, nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source)); - } else { - nm_hash_update_in6addr (h, &obj->src); - nm_hash_update_val (h, obj->src_plen); - nm_hash_update_val (h, obj->rt_source); - } - nm_hash_update_val (h, obj->mss); - nm_hash_update_bools (h, obj->rt_cloned, - obj->lock_window, - obj->lock_cwnd, - obj->lock_initcwnd, - obj->lock_initrwnd, - obj->lock_mtu); - nm_hash_update_val (h, obj->window); - nm_hash_update_val (h, obj->cwnd); - nm_hash_update_val (h, obj->initcwnd); - nm_hash_update_val (h, obj->initrwnd); - nm_hash_update_val (h, obj->mtu); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) - nm_hash_update_val (h, _route_pref_normalize (obj->rt_pref)); - else - nm_hash_update_val (h, obj->rt_pref); - break; - } + struct in6_addr a1, a2; + + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), + obj->plen, + nm_utils_ip6_route_metric_normalize (obj->metric), + *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), + obj->src_plen); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), + obj->plen, + nm_utils_ip6_route_metric_normalize (obj->metric), + *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), + obj->src_plen, + /* on top of WEAK_ID: */ + obj->ifindex, + obj->gateway); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals (h, + cmp_type, + nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), + obj->ifindex, + *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), + obj->plen, + nm_utils_ip6_route_metric_normalize (obj->metric), + obj->gateway, + obj->pref_src, + *nm_utils_ip6_address_clear_host_address (&a2, &obj->src, obj->src_plen), + obj->src_plen, + nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source), + obj->mss, + NM_HASH_COMBINE_BOOLS (guint8, + obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + _route_pref_normalize (obj->rt_pref)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals (h, + cmp_type, + obj->table_coerced, + obj->ifindex, + obj->network, + obj->plen, + obj->metric, + obj->gateway, + obj->pref_src, + obj->src, + obj->src_plen, + obj->rt_source, + obj->mss, + NM_HASH_COMBINE_BOOLS (guint8, + obj->rt_cloned, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->rt_pref); + break; } } diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index b01c54447d..bdf5dbc2c5 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -616,11 +616,11 @@ typedef struct { in_addr_t local; in_addr_t remote; int parent_ifindex; + guint16 flags; guint8 ttl; guint8 tos; guint8 proto; bool path_mtu_discovery:1; - guint16 flags; } NMPlatformLnkSit; typedef struct { diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 376bb24c31..d82d0f76b8 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -762,10 +762,11 @@ _vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h) nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK); nm_platform_link_hash_update (&obj->link, h); - nm_hash_update_val (h, obj->_link.netlink.is_in_netlink); + nm_hash_update_vals (h, + obj->_link.netlink.is_in_netlink, + obj->_link.udev.device); if (obj->_link.netlink.lnk) nmp_object_hash_update (obj->_link.netlink.lnk, h); - nm_hash_update_val (h, obj->_link.udev.device); } static void From 1410c6376e3bbb7a29c140eed702b01551cd6d95 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Oct 2017 19:44:27 +0200 Subject: [PATCH 12/12] platform: don't hash the compare type in nm_platform_ip4_route_hash_update() We don't need this extra distinguisher. It makes no sense to ever compare two routes with a different compare-type. Also, the number of fields that is hashed already differs between each compare type. If we have a good hashing algorithm, this already suffices that the hash value looks largely different. --- src/platform/nm-platform.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 56c36c2630..1773b15ad2 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5511,7 +5511,6 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), obj->plen, @@ -5520,7 +5519,6 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), obj->plen, @@ -5547,7 +5545,6 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), obj->ifindex, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), @@ -5574,7 +5571,6 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: nm_hash_update_vals (h, - cmp_type, obj->table_coerced, obj->ifindex, obj->network, @@ -5687,7 +5683,6 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo switch (cmp_type) { case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), obj->plen, @@ -5697,7 +5692,6 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), obj->plen, @@ -5710,7 +5704,6 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: nm_hash_update_vals (h, - cmp_type, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), obj->ifindex, *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), @@ -5738,7 +5731,6 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: nm_hash_update_vals (h, - cmp_type, obj->table_coerced, obj->ifindex, obj->network,