diff options
Diffstat (limited to 'libnm-core')
35 files changed, 943 insertions, 808 deletions
diff --git a/libnm-core/meson.build b/libnm-core/meson.build index 89acaf72ad..0509deaa54 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -196,12 +196,6 @@ links = [ libnm_core_c_args = common_c_flags -if enable_json_validation - libnm_core_sources += files('nm-json.c') - deps += jansson_dep - libnm_core_c_args += ['-fcommon'] -endif - libnm_core = static_library( 'nm-core', sources: libnm_core_sources + libnm_core_enum_sources + nm_meta_setting_source + [nm_version_macro_header], diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 5f18b651cb..b1eff83e7c 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -2089,7 +2089,7 @@ _clear_secrets_by_secret_flags_cb (NMSetting *setting, /* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */ remove_secret = (flags != NM_SETTING_SECRET_FLAG_NONE); } else { - /* Otherwise if the secret has at least one of the desired flags keep it */ + /* Otherwise, if the secret has at least one of the desired flags keep it */ remove_secret = !NM_FLAGS_ANY (flags, filter_flags); } @@ -2101,7 +2101,7 @@ _clear_secrets_by_secret_flags_cb (NMSetting *setting, * @self: the #NMConnection to filter (will be modified) * @filter_flags: the secret flags to control whether to drop/remove * a secret or to keep it. The meaning of the filter flags is to - * preseve the secrets. The secrets that have matching (see below) + * preserve the secrets. The secrets that have matching (see below) * flags are kept, the others are dropped. * * Removes/drops secrets from @self according to @filter_flags. @@ -2370,8 +2370,8 @@ nm_connection_for_each_setting_value (NMConnection *connection, /** * _nm_connection_aggregate: - * @connecition: the #NMConnection for which values are to be aggregated. - * @type: one of the supported aggrate types. + * @connection: the #NMConnection for which values are to be aggregated. + * @type: one of the supported aggregate types. * @arg: the input/output argument that depends on @type. * * For example, with %NM_CONNECTION_AGGREGATE_ANY_SECRETS and diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 3a15d2e956..053b5384c3 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -879,10 +879,6 @@ gboolean nm_utils_base64secret_normalize (const char *base64_key, /*****************************************************************************/ -void _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, - GString *string, - gboolean leading_space); - gboolean nm_utils_connection_is_adhoc_wpa (NMConnection *connection); const char *nm_utils_wifi_freq_to_band (guint32 freq); diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index 4c85dae470..c55b1a5383 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -1024,7 +1024,7 @@ typedef enum { /*< flags >*/ * @NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES: The master has any slave devices attached. * This only makes sense if the device is a master. * @NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY: the lifetime - * of the activation is bound to the visilibity of the connection profile, + * of the activation is bound to the visibility of the connection profile, * which in turn depends on "connection.permissions" and whether a session * for the user exists. Since: 1.16 * @NM_ACTIVATION_STATE_FLAG_EXTERNAL: the active connection was generated to @@ -1087,7 +1087,7 @@ typedef enum { /*< flags >*/ * as %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, with one difference: when later deleting * the profile, the original profile will not be deleted. Instead a nmmeta * file is written to /run to indicate that the profile is gone. - * Note that if such a nmmeta tombstone file exists and hides a file in persistant + * Note that if such a nmmeta tombstone file exists and hides a file in persistent * storage, then when re-adding the profile with the same UUID, then the original * storage is taken over again. * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY: this is like %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, diff --git a/libnm-core/nm-dbus-utils.c b/libnm-core/nm-dbus-utils.c index 72b9fe1f44..c099ff472c 100644 --- a/libnm-core/nm-dbus-utils.c +++ b/libnm-core/nm-dbus-utils.c @@ -201,7 +201,7 @@ _nm_dbus_typecheck_response (GVariant *response, * will also check that the response matches that type signature, and return * an error if not. * - * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * Returns: %NULL if @error is set. Otherwise, a #GVariant tuple with * return values. Free with g_variant_unref(). */ GVariant * diff --git a/libnm-core/nm-json.c b/libnm-core/nm-json.c deleted file mode 100644 index 001d53dbb6..0000000000 --- a/libnm-core/nm-json.c +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1+ -/* - * Copyright (C) 2017, 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#define NM_JANSSON_C -#include "nm-json.h" - -#include <dlfcn.h> - -void *_nm_jansson_json_object_iter_value; -void *_nm_jansson_json_object_key_to_iter; -void *_nm_jansson_json_integer; -void *_nm_jansson_json_object_del; -void *_nm_jansson_json_array_get; -void *_nm_jansson_json_array_size; -void *_nm_jansson_json_array_append_new; -void *_nm_jansson_json_string; -void *_nm_jansson_json_object_iter_next; -void *_nm_jansson_json_loads; -void *_nm_jansson_json_dumps; -void *_nm_jansson_json_object_iter_key; -void *_nm_jansson_json_object; -void *_nm_jansson_json_object_get; -void *_nm_jansson_json_array; -void *_nm_jansson_json_false; -void *_nm_jansson_json_delete; -void *_nm_jansson_json_true; -void *_nm_jansson_json_object_size; -void *_nm_jansson_json_object_set_new; -void *_nm_jansson_json_object_iter; -void *_nm_jansson_json_integer_value; -void *_nm_jansson_json_string_value; - -#define TRY_BIND_SYMBOL(symbol) \ - G_STMT_START { \ - void *sym = dlsym (handle, #symbol); \ - if (_nm_jansson_ ## symbol && sym != _nm_jansson_ ## symbol) \ - return FALSE; \ - _nm_jansson_ ## symbol = sym; \ - } G_STMT_END - -static gboolean -bind_symbols (void *handle) -{ - TRY_BIND_SYMBOL (json_object_iter_value); - TRY_BIND_SYMBOL (json_object_key_to_iter); - TRY_BIND_SYMBOL (json_integer); - TRY_BIND_SYMBOL (json_object_del); - TRY_BIND_SYMBOL (json_array_get); - TRY_BIND_SYMBOL (json_array_size); - TRY_BIND_SYMBOL (json_array_append_new); - TRY_BIND_SYMBOL (json_string); - TRY_BIND_SYMBOL (json_object_iter_next); - TRY_BIND_SYMBOL (json_loads); - TRY_BIND_SYMBOL (json_dumps); - TRY_BIND_SYMBOL (json_object_iter_key); - TRY_BIND_SYMBOL (json_object); - TRY_BIND_SYMBOL (json_object_get); - TRY_BIND_SYMBOL (json_array); - TRY_BIND_SYMBOL (json_false); - TRY_BIND_SYMBOL (json_delete); - TRY_BIND_SYMBOL (json_true); - TRY_BIND_SYMBOL (json_object_size); - TRY_BIND_SYMBOL (json_object_set_new); - TRY_BIND_SYMBOL (json_object_iter); - TRY_BIND_SYMBOL (json_integer_value); - TRY_BIND_SYMBOL (json_string_value); - - return TRUE; -} - -gboolean -nm_jansson_load (void) -{ - static enum { - UNKNOWN, - AVAILABLE, - MISSING, - } state = UNKNOWN; - void *handle; - int mode; - - if (G_LIKELY (state != UNKNOWN)) - goto out; - - /* First just resolve the symbols to see if there's a conflict already. */ - if (!bind_symbols (RTLD_DEFAULT)) - goto out; - - mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND; -#if defined (ASAN_BUILD) - /* Address sanitizer is incompatible with RTLD_DEEPBIND. */ - mode &= ~RTLD_DEEPBIND; -#endif - handle = dlopen (JANSSON_SONAME, mode); - - if (!handle) - goto out; - - /* Now do the actual binding. */ - if (!bind_symbols (handle)) - goto out; - - state = AVAILABLE; -out: - return state == AVAILABLE; -} diff --git a/libnm-core/nm-json.h b/libnm-core/nm-json.h deleted file mode 100644 index d857fe0275..0000000000 --- a/libnm-core/nm-json.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1+ -/* - * Copyright (C) 2017, 2018 Red Hat, Inc. - */ - -#ifndef __NM_JSON_H__ -#define __NM_JSON_H__ - -gboolean nm_jansson_load (void); - -#ifndef NM_JANSSON_C -#define json_object_iter_value (*_nm_jansson_json_object_iter_value) -#define json_object_key_to_iter (*_nm_jansson_json_object_key_to_iter) -#define json_integer (*_nm_jansson_json_integer) -#define json_object_del (*_nm_jansson_json_object_del) -#define json_array_get (*_nm_jansson_json_array_get) -#define json_array_size (*_nm_jansson_json_array_size) -#define json_array_append_new (*_nm_jansson_json_array_append_new) -#define json_string (*_nm_jansson_json_string) -#define json_object_iter_next (*_nm_jansson_json_object_iter_next) -#define json_loads (*_nm_jansson_json_loads) -#define json_dumps (*_nm_jansson_json_dumps) -#define json_object_iter_key (*_nm_jansson_json_object_iter_key) -#define json_object (*_nm_jansson_json_object) -#define json_object_get (*_nm_jansson_json_object_get) -#define json_array (*_nm_jansson_json_array) -#define json_false (*_nm_jansson_json_false) -#define json_delete (*_nm_jansson_json_delete) -#define json_true (*_nm_jansson_json_true) -#define json_object_size (*_nm_jansson_json_object_size) -#define json_object_set_new (*_nm_jansson_json_object_set_new) -#define json_object_iter (*_nm_jansson_json_object_iter) -#define json_integer_value (*_nm_jansson_json_integer_value) -#define json_string_value (*_nm_jansson_json_string_value) - -#include "nm-glib-aux/nm-jansson.h" -#endif - -#endif /* __NM_JSON_H__ */ diff --git a/libnm-core/nm-keyfile/nm-keyfile-utils.c b/libnm-core/nm-keyfile/nm-keyfile-utils.c index 0ffce40b96..0e88609fd0 100644 --- a/libnm-core/nm-keyfile/nm-keyfile-utils.c +++ b/libnm-core/nm-keyfile/nm-keyfile-utils.c @@ -504,8 +504,9 @@ static const char * _keyfile_key_encode (const char *name, char **out_to_free) { - gsize len, i; - GString *str; + NMStrBuf str; + gsize len; + gsize i; nm_assert (name); nm_assert (out_to_free && !*out_to_free); @@ -525,7 +526,7 @@ _keyfile_key_encode (const char *name, */ if (!name[0]) { - /* empty keys are are backslash encoded. Note that usually + /* empty keys are backslash encoded. Note that usually * \\00 is not a valid encode, the only exception is the empty * word. */ return "\\00"; @@ -555,14 +556,15 @@ _keyfile_key_encode (const char *name, len = i + strlen (&name[i]); nm_assert (len == strlen (name)); - str = g_string_sized_new (len + 15); + + nm_str_buf_init (&str, len + 15u, FALSE); if (name[0] == ' ') { nm_assert (i == 0); - g_string_append (str, "\\20"); + nm_str_buf_append (&str, "\\20"); i = 1; } else - g_string_append_len (str, name, i); + nm_str_buf_append_len (&str, name, i); for (;; i++) { const guchar ch = (guchar) name[i]; @@ -577,21 +579,24 @@ _keyfile_key_encode (const char *name, && g_ascii_isxdigit (name[i + 1]) && g_ascii_isxdigit (name[i + 2])) || ( ch == ' ' - && name[i + 1] == '\0')) - g_string_append_printf (str, "\\%02X", ch); - else - g_string_append_c (str, (char) ch); + && name[i + 1] == '\0')) { + nm_str_buf_append_c (&str, '\\'); + nm_str_buf_append_c_hex (&str, ch, TRUE); + } else + nm_str_buf_append_c (&str, (char) ch); } - return (*out_to_free = g_string_free (str, FALSE)); + return (*out_to_free = nm_str_buf_finalize (&str, NULL)); } static const char * _keyfile_key_decode (const char *key, char **out_to_free) { - gsize i, len; - GString *str; + char *out; + gsize len; + gsize i; + gsize j; nm_assert (key); nm_assert (out_to_free && !*out_to_free); @@ -617,9 +622,12 @@ _keyfile_key_decode (const char *key, return ""; nm_assert (len == strlen (key)); - str = g_string_sized_new (len + 3); - g_string_append_len (str, key, i); + out = g_new (char, len + 1u); + + memcpy (out, key, sizeof (char) * i); + + j = i; for (;;) { const char ch = key[i]; char ch1, ch2; @@ -633,16 +641,18 @@ _keyfile_key_decode (const char *key, && g_ascii_isxdigit ((ch2 = key[i + 2]))) { v = (g_ascii_xdigit_value (ch1) << 4) + g_ascii_xdigit_value (ch2); if (v != 0) { - g_string_append_c (str, (char) v); + out[j++] = (char) v; i += 3; continue; } } - g_string_append_c (str, ch); + out[j++] = ch; i++; } - return (*out_to_free = g_string_free (str, FALSE)); + nm_assert (j <= len); + out[j] = '\0'; + return (*out_to_free = out); } /*****************************************************************************/ @@ -689,7 +699,7 @@ nm_keyfile_key_decode (const char *key, const char *key2; key2 = _keyfile_key_encode (name, &to_free2); - /* key2, the result of decode+encode may not be idential + /* key2, the result of decode+encode may not be identical * to the original key. That is, decode() is a surjective * function mapping different keys to the same name. * However, decode() behaves injective for input that diff --git a/libnm-core/nm-keyfile/nm-keyfile.c b/libnm-core/nm-keyfile/nm-keyfile.c index 77af2b6492..05c8044556 100644 --- a/libnm-core/nm-keyfile/nm-keyfile.c +++ b/libnm-core/nm-keyfile/nm-keyfile.c @@ -16,6 +16,7 @@ #include <arpa/inet.h> #include <linux/pkt_sched.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-glib-aux/nm-secret-utils.h" #include "systemd/nm-sd-utils-shared.h" #include "nm-libnm-core-intern/nm-common-macros.h" @@ -472,7 +473,7 @@ openconnect_fix_secret_flags (NMSetting *setting) /* Huge hack. There were some openconnect changes that needed to happen * pretty late, too late to get into distros. Migration has already * happened for many people, and their secret flags are wrong. But we - * don't want to requrie re-migration, so we have to fix it up here. Ugh. + * don't want to require re-migration, so we have to fix it up here. Ugh. */ if (!NM_IS_SETTING_VPN (setting)) @@ -2107,79 +2108,81 @@ write_ip_values (GKeyFile *file, const char *gateway, gboolean is_route) { - nm_auto_free_gstring GString *output = NULL; - int addr_family; - guint i; - const char *addr; - const char *gw; - guint32 plen; - char key_name[64]; - char *key_name_idx; - - if (!array->len) - return; - - addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) - ? AF_INET - : AF_INET6; - - strcpy (key_name, is_route ? "route" : "address"); - key_name_idx = key_name + strlen (key_name); - - output = g_string_sized_new (2*INET_ADDRSTRLEN + 10); - for (i = 0; i < array->len; i++) { - gint64 metric = -1; - - if (is_route) { - NMIPRoute *route = array->pdata[i]; + if (array->len > 0) { + nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT (2*INET_ADDRSTRLEN + 10, FALSE); + int addr_family; + guint i; + const char *addr; + const char *gw; + guint32 plen; + char key_name[64]; + char *key_name_idx; + + addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) + ? AF_INET + : AF_INET6; + + strcpy (key_name, is_route ? "route" : "address"); + key_name_idx = key_name + strlen (key_name); + + for (i = 0; i < array->len; i++) { + gint64 metric = -1; + + if (is_route) { + NMIPRoute *route = array->pdata[i]; + + addr = nm_ip_route_get_dest (route); + plen = nm_ip_route_get_prefix (route); + gw = nm_ip_route_get_next_hop (route); + metric = nm_ip_route_get_metric (route); + } else { + NMIPAddress *address = array->pdata[i]; - addr = nm_ip_route_get_dest (route); - plen = nm_ip_route_get_prefix (route); - gw = nm_ip_route_get_next_hop (route); - metric = nm_ip_route_get_metric (route); - } else { - NMIPAddress *address = array->pdata[i]; + addr = nm_ip_address_get_address (address); + plen = nm_ip_address_get_prefix (address); + gw = (i == 0) + ? gateway + : NULL; + } - addr = nm_ip_address_get_address (address); - plen = nm_ip_address_get_prefix (address); - gw = (i == 0) - ? gateway - : NULL; - } + nm_str_buf_set_size (&output, 0, FALSE, FALSE); + nm_str_buf_append_printf (&output, "%s/%u", addr, plen); + if ( metric != -1 + || gw) { + /* Older versions of the plugin do not support the form + * "a.b.c.d/plen,,metric", so, we always have to write the + * gateway, even if there isn't one. + * The current version supports reading of the above form. + */ + if (!gw) { + if (addr_family == AF_INET) + gw = "0.0.0.0"; + else + gw = "::"; + } - g_string_set_size (output, 0); - g_string_append_printf (output, "%s/%u", addr, plen); - if ( metric != -1 - || gw) { - /* Older versions of the plugin do not support the form - * "a.b.c.d/plen,,metric", so, we always have to write the - * gateway, even if there isn't one. - * The current version supports reading of the above form. - */ - if (!gw) { - if (addr_family == AF_INET) - gw = "0.0.0.0"; - else - gw = "::"; + nm_str_buf_append_c (&output, ','); + nm_str_buf_append (&output, gw); + if ( is_route + && metric != -1) + nm_str_buf_append_printf (&output, ",%lu", (unsigned long) metric); } - g_string_append_printf (output, ",%s", gw); - if ( is_route - && metric != -1) - g_string_append_printf (output, ",%lu", (unsigned long) metric); - } - - sprintf (key_name_idx, "%u", i + 1); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); + sprintf (key_name_idx, "%u", i + 1); + nm_keyfile_plugin_kf_set_string (file, + setting_name, + key_name, + nm_str_buf_get_str (&output)); - if (is_route) { - gs_free char *attributes = NULL; + if (is_route) { + gs_free char *attributes = NULL; - attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]), - ',', '='); - if (attributes) { - g_strlcat (key_name, "_options", sizeof (key_name)); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes); + attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]), + ',', '='); + if (attributes) { + g_strlcat (key_name, "_options", sizeof (key_name)); + nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes); + } } } } @@ -2220,34 +2223,29 @@ bridge_vlan_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - NMBridgeVlan *vlan; GPtrArray *vlans; - GString *string; - guint i; - - vlans = (GPtrArray *) g_value_get_boxed (value); - if (!vlans || !vlans->len) - return; - string = g_string_new (""); - for (i = 0; i < vlans->len; i++) { - gs_free char *vlan_str = NULL; + vlans = g_value_get_boxed (value); + if ( vlans + && vlans->len > 0) { + const guint string_initial_size = vlans->len * 10u; + nm_auto_str_buf NMStrBuf string = NM_STR_BUF_INIT (string_initial_size, FALSE); + guint i; - vlan = vlans->pdata[i]; - vlan_str = nm_bridge_vlan_to_str (vlan, NULL); - if (!vlan_str) - continue; - if (string->len > 0) - g_string_append (string, ","); - nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string); - } + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; - nm_keyfile_plugin_kf_set_string (info->keyfile, - nm_setting_get_name (setting), - "vlans", - string->str); + vlan_str = nm_bridge_vlan_to_str (vlans->pdata[i], NULL); + if (i > 0) + nm_str_buf_append_c (&string, ','); + nm_utils_escaped_tokens_escape_strbuf_assert (vlan_str, ",", &string); + } - g_string_free (string, TRUE); + nm_keyfile_plugin_kf_set_string (info->keyfile, + nm_setting_get_name (setting), + "vlans", + nm_str_buf_get_str (&string)); + } } @@ -2348,17 +2346,21 @@ qdisc_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - gsize i; + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; GPtrArray *array; + guint i; - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) + array = g_value_get_boxed (value); + if ( !array + || !array->len) return; for (i = 0; i < array->len; i++) { NMTCQdisc *qdisc = array->pdata[i]; - GString *key_name = g_string_sized_new (16); - GString *value_str = g_string_sized_new (60); + + nm_gstring_prepare (&key_name); + nm_gstring_prepare (&value_str); g_string_append (key_name, "qdisc."); _nm_utils_string_append_tc_parent (key_name, NULL, @@ -2369,9 +2371,6 @@ qdisc_writer (KeyfileWriterInfo *info, NM_SETTING_TC_CONFIG_SETTING_NAME, key_name->str, value_str->str); - - g_string_free (key_name, TRUE); - g_string_free (value_str, TRUE); } } @@ -2381,17 +2380,21 @@ tfilter_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - gsize i; + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; GPtrArray *array; + guint i; - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) + array = g_value_get_boxed (value); + if ( !array + || !array->len) return; for (i = 0; i < array->len; i++) { NMTCTfilter *tfilter = array->pdata[i]; - GString *key_name = g_string_sized_new (16); - GString *value_str = g_string_sized_new (60); + + nm_gstring_prepare (&key_name); + nm_gstring_prepare (&value_str); g_string_append (key_name, "tfilter."); _nm_utils_string_append_tc_parent (key_name, NULL, @@ -2402,9 +2405,6 @@ tfilter_writer (KeyfileWriterInfo *info, NM_SETTING_TC_CONFIG_SETTING_NAME, key_name->str, value_str->str); - - g_string_free (key_name, TRUE); - g_string_free (value_str, TRUE); } } @@ -4309,46 +4309,53 @@ char * nm_keyfile_utils_create_filename (const char *name, gboolean with_extension) { - GString *str; - const char *f = name; /* keyfile used to escape with '*', do not change that behavior. * * But for newly added escapings, use '_' instead. * Also, @with_extension is new-style. */ const char ESCAPE_CHAR = with_extension ? '_' : '*'; const char ESCAPE_CHAR2 = '_'; + NMStrBuf str; + char *p; + gsize len; + gsize i; g_return_val_if_fail (name && name[0], NULL); - str = g_string_sized_new (60); + nm_str_buf_init (&str, 0, FALSE); + + len = strlen (name); + + p = nm_str_buf_append_len0 (&str, name, len); /* Convert '/' to ESCAPE_CHAR */ - for (f = name; f[0]; f++) { - if (f[0] == '/') - g_string_append_c (str, ESCAPE_CHAR); - else - g_string_append_c (str, f[0]); + for (i = 0; i < len; i++) { + if (p[i] == '/') + p[i] = ESCAPE_CHAR; } /* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject. - * We can escape here more aggressivly then what we would read back. */ - if (str->str[0] == '.') - str->str[0] = ESCAPE_CHAR2; - if (str->str[str->len - 1] == '~') - str->str[str->len - 1] = ESCAPE_CHAR2; - if ( check_mkstemp_suffix (str->str) - || check_suffix (str->str, PEM_TAG) - || check_suffix (str->str, DER_TAG)) - g_string_append_c (str, ESCAPE_CHAR2); + * We can escape here more aggressively then what we would read back. */ + if (p[0] == '.') + p[0] = ESCAPE_CHAR2; + if (p[str.len - 1] == '~') + p[str.len - 1] = ESCAPE_CHAR2; + + if ( check_mkstemp_suffix (p) + || check_suffix (p, PEM_TAG) + || check_suffix (p, DER_TAG)) + nm_str_buf_append_c (&str, ESCAPE_CHAR2); if (with_extension) - g_string_append (str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION); + nm_str_buf_append (&str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION); + + p = nm_str_buf_finalize (&str, NULL); /* nm_keyfile_utils_create_filename() must mirror ignore_filename() */ - nm_assert (!strchr (str->str, '/')); - nm_assert (!nm_keyfile_utils_ignore_filename (str->str, with_extension)); + nm_assert (!strchr (p, '/')); + nm_assert (!nm_keyfile_utils_ignore_filename (p, with_extension)); - return g_string_free (str, FALSE);; + return p; } /*****************************************************************************/ diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index f6dbda6341..93478c22e3 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -990,7 +990,7 @@ nm_setting_802_1x_get_ca_cert_path (NMSetting8021x *setting) * nm_setting_802_1x_get_ca_cert_blob() and * nm_setting_802_1x_get_ca_cert_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * @@ -1321,7 +1321,7 @@ nm_setting_802_1x_get_client_cert_path (NMSetting8021x *setting) * nm_setting_802_1x_get_client_cert_blob() and * nm_setting_802_1x_get_client_cert_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * @@ -1583,7 +1583,7 @@ nm_setting_802_1x_get_phase2_ca_cert_path (NMSetting8021x *setting) * nm_setting_802_1x_get_phase2_ca_cert_blob() and * nm_setting_802_1x_get_phase2_ca_cert_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * @@ -1918,7 +1918,7 @@ nm_setting_802_1x_get_phase2_client_cert_path (NMSetting8021x *setting) * nm_setting_802_1x_get_phase2_ca_cert_blob() and * nm_setting_802_1x_get_phase2_ca_cert_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * @@ -2154,7 +2154,7 @@ nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting) * nm_setting_802_1x_get_private_key_blob() and * nm_setting_802_1x_get_private_key_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * @@ -2357,7 +2357,7 @@ nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting) * nm_setting_802_1x_get_phase2_private_key_blob() and * nm_setting_802_1x_get_phase2_private_key_path(). * - * Currently it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC * 7512), but may be extended to other schemes in future (such as 'file' URIs * for local files and 'data' URIs for inline certificate data). * diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 6e0a5e5b3a..651cd4532f 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -370,7 +370,7 @@ static void _ensure_options_idx_cache (NMSettingBondPrivate *priv) { if (!G_UNLIKELY (priv->options_idx_cache)) - priv->options_idx_cache = nm_utils_named_values_from_str_dict_with_sort (priv->options, NULL, _get_option_sort, NULL); + priv->options_idx_cache = nm_utils_named_values_from_strdict_full (priv->options, NULL, _get_option_sort, NULL, NULL, 0, NULL); } /** diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 2ead27393e..02ad4f010c 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -10,6 +10,7 @@ #include <ctype.h> #include <stdlib.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-connection-private.h" #include "nm-utils.h" #include "nm-utils-private.h" @@ -407,25 +408,6 @@ nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan) return copy; } -void -_nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, - GString *string, - gboolean leading_space) -{ - if (nm_bridge_vlan_is_pvid (vlan)) { - if (leading_space) - g_string_append_c (string, ' '); - g_string_append (string, "pvid"); - leading_space = TRUE; - } - if (nm_bridge_vlan_is_untagged (vlan)) { - if (leading_space) - g_string_append_c (string, ' '); - g_string_append (string, "untagged"); - leading_space = TRUE; - } -} - /** * nm_bridge_vlan_to_str: * @vlan: the %NMBridgeVlan @@ -440,7 +422,7 @@ _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, char * nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error) { - GString *string; + NMStrBuf string; g_return_val_if_fail (vlan, NULL); g_return_val_if_fail (!error || !*error, NULL); @@ -449,16 +431,19 @@ nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error) * future if more parameters are added to the object that could * make it invalid. */ - string = g_string_sized_new (28); + nm_str_buf_init (&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (vlan->vid_start == vlan->vid_end) - g_string_append_printf (string, "%u", vlan->vid_start); + nm_str_buf_append_printf (&string, "%u", vlan->vid_start); else - g_string_append_printf (string, "%u-%u", vlan->vid_start, vlan->vid_end); + nm_str_buf_append_printf (&string, "%u-%u", vlan->vid_start, vlan->vid_end); - _nm_bridge_vlan_str_append_rest (vlan, string, TRUE); + if (nm_bridge_vlan_is_pvid (vlan)) + nm_str_buf_append (&string, " pvid"); + if (nm_bridge_vlan_is_untagged (vlan)) + nm_str_buf_append (&string, " untagged"); - return g_string_free (string, FALSE); + return nm_str_buf_finalize (&string, NULL); } /** @@ -1988,8 +1973,9 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) * Sets bridge's multicast router. Multicast-snooping must be enabled * for this option to work. * - * Supported values are: 'auto', 'disabled', 'enabled'. - * If not specified the default value is 'auto'. + * Supported values are: 'auto', 'disabled', 'enabled' to which kernel + * assigns the numbers 1, 0, and 2, respectively. + * If not specified the default value is 'auto' (1). **/ /* ---ifcfg-rh--- * property: multicast-router diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 018129bef2..ff3f516365 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -808,7 +808,7 @@ nm_setting_connection_add_secondary (NMSettingConnection *setting, * @setting: the #NMSettingConnection * @idx: index number of the secondary connection UUID * - * Removes the secondary coonnection UUID at index @idx. + * Removes the secondary connection UUID at index @idx. **/ void nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 idx) @@ -832,7 +832,7 @@ nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 id * @setting: the #NMSettingConnection * @sec_uuid: the secondary connection UUID to remove * - * Removes the secondary coonnection UUID @sec_uuid. + * Removes the secondary connection UUID @sec_uuid. * * Returns: %TRUE if the secondary connection UUID was found and removed; %FALSE if it was not. **/ @@ -1758,7 +1758,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * name is included, so that different interfaces yield different addresses. * * The '$' character is treated special to perform dynamic substitutions - * at runtime. Currently supported are "${CONNECTION}", "${DEVICE}", "${MAC}", + * at runtime. Currently, supported are "${CONNECTION}", "${DEVICE}", "${MAC}", * "${BOOT}", "${RANDOM}". * These effectively create unique IDs per-connection, per-device, per-boot, * or every time. Note that "${DEVICE}" corresponds to the interface name of the @@ -2128,7 +2128,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * NMSettingConnection:secondaries: * * List of connection UUIDs that should be activated when the base - * connection itself is activated. Currently only VPN connections are + * connection itself is activated. Currently, only VPN connections are * supported. **/ /* ---ifcfg-rh--- @@ -2222,7 +2222,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * to use a global default. If the global default is not set, the authentication * retries for 3 times before failing the connection. * - * Currently this only applies to 802-1x authentication. + * Currently, this only applies to 802-1x authentication. * * Since: 1.10 **/ @@ -2252,7 +2252,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * If unspecified, "default" ultimately depends on the DNS plugin (which * for systemd-resolved currently means "no"). * - * This feature requires a plugin which supports mDNS. Otherwise the + * This feature requires a plugin which supports mDNS. Otherwise, the * setting has no effect. One such plugin is dns-systemd-resolved. * * Since: 1.12 @@ -2287,7 +2287,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * If unspecified, "default" ultimately depends on the DNS plugin (which * for systemd-resolved currently means "yes"). * - * This feature requires a plugin which supports LLMNR. Otherwise the + * This feature requires a plugin which supports LLMNR. Otherwise, the * setting has no effect. One such plugin is dns-systemd-resolved. * * Since: 1.14 diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index bfce580eda..777f1feebe 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -97,7 +97,7 @@ nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting) * @setting: the #NMSettingInfiniband * * Returns the P_Key to use for this device. A value of -1 means to - * use the default P_Key (aka "the P_Key at index 0"). Otherwise it is + * use the default P_Key (aka "the P_Key at index 0"). Otherwise, it is * a 16-bit unsigned integer. * * Returns: the IPoIB P_Key @@ -448,7 +448,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *klass) * NMSettingInfiniband:p-key: * * The InfiniBand P_Key to use for this device. A value of -1 means to use - * the default P_Key (aka "the P_Key at index 0"). Otherwise it is a 16-bit + * the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit * unsigned integer, whose high bit is set if it is a "full membership" * P_Key. **/ diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index bc81129177..a843ba99f7 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -11,6 +11,7 @@ #include <arpa/inet.h> #include <linux/fib_rules.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-utils.h" @@ -745,7 +746,7 @@ nm_ip_route_unref (NMIPRoute *route) * nm_ip_route_equal_full: * @route: the #NMIPRoute * @other: the #NMIPRoute to compare @route to. - * @cmp_flags: tune how to compare attributes. Currently only + * @cmp_flags: tune how to compare attributes. Currently, only * NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE (0) and NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS (1) * is supported. * @@ -1363,9 +1364,12 @@ nm_ip_route_attribute_validate (const char *name, gboolean _nm_ip_route_attribute_validate_all (const NMIPRoute *route, GError **error) { - GHashTableIter iter; - const char *key; + NMUtilsNamedValue attrs_static[G_N_ELEMENTS (ip_route_attribute_spec)]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue *attrs; + guint attrs_len; GVariant *val; + guint i; guint8 u8; g_return_val_if_fail (route, FALSE); @@ -1374,9 +1378,15 @@ _nm_ip_route_attribute_validate_all (const NMIPRoute *route, GError **error) if (!route->attributes) return TRUE; - g_hash_table_iter_init (&iter, route->attributes); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) { - if (!nm_ip_route_attribute_validate (key, val, route->family, NULL, error)) + attrs = nm_utils_named_values_from_strdict (route->attributes, + &attrs_len, + attrs_static, + &attrs_free); + for (i = 0; i < attrs_len; i++) { + const char *key = attrs[i].name; + GVariant *val2 = attrs[i].value_ptr; + + if (!nm_ip_route_attribute_validate (key, val2, route->family, NULL, NULL)) return FALSE; } @@ -3021,7 +3031,7 @@ _rr_string_addr_family_from_flags (NMIPRoutingRuleAsStringFlags to_string_flags) * @to_string_flags: #NMIPRoutingRuleAsStringFlags for controlling the * string conversion. * @extra_args: (allow-none): extra arguments for controlling the string - * conversion. Currently not extra arguments are supported. + * conversion. Currently, not extra arguments are supported. * @error: (allow-none) (out): the error reason. * * Returns: (transfer full): the new #NMIPRoutingRule or %NULL on error. @@ -3081,7 +3091,7 @@ nm_ip_routing_rule_from_string (const char *str, * - iproute2 in may regards is flexible about the command lines. For example * - for tables it accepts table names from /etc/iproute2/rt_tables. We only * accept the special aliases "main", "local", and "default". - * - key names like "preference" can be abbreviated to "prefe", we don't do that. + * - key names like "preference" can be abbreviated to "pref", we don't do that. * - the "preference"/"priority" may be unspecified, in which kernel automatically * chooses an unused priority (during `ip rule add`). We don't allow for that, the * priority must be explicitly set. @@ -3117,7 +3127,7 @@ nm_ip_routing_rule_from_string (const char *str, } /* iproute2 matches keywords with any partial prefix. We don't allow - * for that flexiblity. */ + * for that flexibility. */ if (NM_IN_STRSET (word0, "from")) { if (!word1) @@ -3395,7 +3405,7 @@ next_words_consumed: } static void -_rr_string_append_inet_addr (GString *str, +_rr_string_append_inet_addr (NMStrBuf *str, gboolean is_from /* or else is-to */, gboolean required, int addr_family, @@ -3406,26 +3416,26 @@ _rr_string_append_inet_addr (GString *str, if (addr_len == 0) { if (required) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "%s %s/0", - is_from ? "from" : "to", - (addr_family == AF_INET) - ? "0.0.0.0" - : "::"); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '), + "%s %s/0", + is_from ? "from" : "to", + (addr_family == AF_INET) + ? "0.0.0.0" + : "::"); } return; } - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "%s %s", - is_from ? "from" : "to", - nm_utils_inet_ntop (addr_family, - addr_bin, - addr_str)); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '), + "%s %s", + is_from ? "from" : "to", + nm_utils_inet_ntop (addr_family, + addr_bin, + addr_str)); if (addr_len != nm_utils_addr_family_to_size (addr_family) * 8) { - g_string_append_printf (str, - "/%u", - addr_len); + nm_str_buf_append_printf (str, + "/%u", + addr_len); } } @@ -3435,7 +3445,7 @@ _rr_string_append_inet_addr (GString *str, * @to_string_flags: #NMIPRoutingRuleAsStringFlags for controlling the * string conversion. * @extra_args: (allow-none): extra arguments for controlling the string - * conversion. Currently not extra arguments are supported. + * conversion. Currently, not extra arguments are supported. * @error: (allow-none) (out): the error reason. * * Returns: (transfer full): the string representation or %NULL on error. @@ -3448,8 +3458,8 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, GHashTable *extra_args, GError **error) { - nm_auto_free_gstring GString *str = NULL; int addr_family; + NMStrBuf str; g_return_val_if_fail (NM_IS_IP_ROUTING_RULE (self, TRUE), NULL); @@ -3485,18 +3495,18 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, } } - str = g_string_sized_new (30); + nm_str_buf_init (&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (self->priority_has) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "priority %u", - (guint) self->priority); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "priority %u", + (guint) self->priority); } if (self->invert) - g_string_append (nm_gstring_add_space_delimiter (str), "not"); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), "not"); - _rr_string_append_inet_addr (str, + _rr_string_append_inet_addr (&str, TRUE, ( !self->to_has || !self->to_valid), @@ -3506,7 +3516,7 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, ? self->from_len : 0); - _rr_string_append_inet_addr (str, + _rr_string_append_inet_addr (&str, FALSE, FALSE, addr_family, @@ -3516,88 +3526,88 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, : 0); if (self->tos != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "tos 0x%02x", - (guint) self->tos); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "tos 0x%02x", + (guint) self->tos); } if (self->ipproto != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "ipproto %u", - (guint) self->ipproto); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "ipproto %u", + (guint) self->ipproto); } if ( self->fwmark != 0 || self->fwmask != 0) { if (self->fwmark != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "fwmark 0x%x", - self->fwmark); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "fwmark 0x%x", + self->fwmark); } else { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "fwmark 0"); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "fwmark 0"); } if (self->fwmask != 0xFFFFFFFFu) { if (self->fwmask != 0) - g_string_append_printf (str, "/0x%x", self->fwmask); + nm_str_buf_append_printf (&str, "/0x%x", self->fwmask); else - g_string_append_printf (str, "/0"); + nm_str_buf_append_printf (&str, "/0"); } } if ( self->sport_start != 0 || self->sport_end != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "sport %u", - self->sport_start); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "sport %u", + self->sport_start); if (self->sport_start != self->sport_end) { - g_string_append_printf (str, - "-%u", - self->sport_end); + nm_str_buf_append_printf (&str, + "-%u", + self->sport_end); } } if ( self->dport_start != 0 || self->dport_end != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "dport %u", - self->dport_start); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "dport %u", + self->dport_start); if (self->dport_start != self->dport_end) { - g_string_append_printf (str, - "-%u", - self->dport_end); + nm_str_buf_append_printf (&str, + "-%u", + self->dport_end); } } if (self->iifname) { - g_string_append (nm_gstring_add_space_delimiter (str), - "iif "); - nm_utils_escaped_tokens_escape_gstr (self->iifname, - NM_ASCII_SPACES, - str); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), + "iif "); + nm_utils_escaped_tokens_escape_strbuf (self->iifname, + NM_ASCII_SPACES, + &str); } if (self->oifname) { - g_string_append (nm_gstring_add_space_delimiter (str), - "oif "); - nm_utils_escaped_tokens_escape_gstr (self->oifname, - NM_ASCII_SPACES, - str); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), + "oif "); + nm_utils_escaped_tokens_escape_strbuf (self->oifname, + NM_ASCII_SPACES, + &str); } if (self->table != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "table %u", - (guint) self->table); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "table %u", + (guint) self->table); } if (self->suppress_prefixlength != -1) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "suppress_prefixlength %d", - (int) self->suppress_prefixlength); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "suppress_prefixlength %d", + (int) self->suppress_prefixlength); } - return g_string_free (g_steal_pointer (&str), FALSE); + return nm_str_buf_finalize (&str, NULL); } /*****************************************************************************/ @@ -5967,7 +5977,7 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) * * Flags for the DHCP hostname and FQDN. * - * Currently this property only includes flags to control the FQDN flags + * Currently, this property only includes flags to control the FQDN flags * set in the DHCP FQDN option. Supported FQDN flags are * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE, * %NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED and diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 5db2dde59b..543fd4366c 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -816,7 +816,7 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass) /** * NMSettingIPTunnel:flags: * - * Tunnel flags. Currently the following values are supported: + * Tunnel flags. Currently, the following values are supported: * %NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS, * %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL, %NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV, * %NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK. diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 31c822202b..b8e0f8e3cb 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -197,7 +197,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) if ( NM_FLAGS_ANY (nm_setting_ip_config_get_dhcp_hostname_flags (s_ip), NM_DHCP_HOSTNAME_FLAGS_FQDN_MASK) && !priv->dhcp_fqdn) { - /* Currently we send a FQDN option only when ipv4.dhcp-fqdn is set */ + /* Currently, we send a FQDN option only when ipv4.dhcp-fqdn is set */ g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c index 3c52dc6cc8..70d4bac81a 100644 --- a/libnm-core/nm-setting-sriov.c +++ b/libnm-core/nm-setting-sriov.c @@ -1305,7 +1305,7 @@ nm_setting_sriov_class_init (NMSettingSriovClass *klass) * "2 mac=00:11:22:33:44:55 spoof-check=true". * * Multiple VFs can be specified using a comma as separator. - * Currently the following attributes are supported: mac, + * Currently, the following attributes are supported: mac, * spoof-check, trust, min-tx-rate, max-tx-rate, vlans. * * The "vlans" attribute is represented as a semicolon-separated diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index 8658231562..2ece266976 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -174,13 +174,14 @@ nm_tc_qdisc_equal (NMTCQdisc *qdisc, NMTCQdisc *other) static guint _nm_tc_qdisc_hash (NMTCQdisc *qdisc) { - gs_free const char **names = NULL; - GVariant *variant; + NMUtilsNamedValue attrs_static[30]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue *attrs; NMHashState h; guint length; guint i; - names = nm_utils_strdict_get_keys (qdisc->attributes, TRUE, &length); + attrs = nm_utils_named_values_from_strdict (qdisc->attributes, &length, attrs_static, &attrs_free); nm_hash_init (&h, 43869703); nm_hash_update_vals (&h, @@ -189,13 +190,13 @@ _nm_tc_qdisc_hash (NMTCQdisc *qdisc) length); nm_hash_update_str0 (&h, qdisc->kind); for (i = 0; i < length; i++) { + const char *key = attrs[i].name; + GVariant *variant = attrs[i].value_ptr; const GVariantType *vtype; - variant = g_hash_table_lookup (qdisc->attributes, names[i]); - vtype = g_variant_get_type (variant); - nm_hash_update_str (&h, names[i]); + nm_hash_update_str (&h, key); nm_hash_update_str (&h, (const char *) vtype); if (g_variant_type_is_basic (vtype)) nm_hash_update_val (&h, g_variant_hash (variant)); @@ -585,6 +586,8 @@ nm_tc_action_get_kind (NMTCAction *action) * Gets an array of attribute names defined on @action. * * Returns: (transfer full): a %NULL-terminated array of attribute names, + * + * Since: 1.12 **/ char ** nm_tc_action_get_attribute_names (NMTCAction *action) @@ -614,6 +617,8 @@ _nm_tc_action_get_attributes (NMTCAction *action) * * Returns: (transfer none): the value of the attribute with name @name on * @action, or %NULL if @action has no such attribute. + * + * Since: 1.12 **/ GVariant * nm_tc_action_get_attribute (NMTCAction *action, const char *name) @@ -634,6 +639,8 @@ nm_tc_action_get_attribute (NMTCAction *action, const char *name) * @value: (transfer none) (allow-none): the value * * Sets or clears the named attribute on @action to the given value. + * + * Since: 1.12 **/ void nm_tc_action_set_attribute (NMTCAction *action, const char *name, GVariant *value) @@ -792,24 +799,31 @@ nm_tc_tfilter_equal (NMTCTfilter *tfilter, NMTCTfilter *other) static guint _nm_tc_tfilter_hash (NMTCTfilter *tfilter) { - gs_free const char **names = NULL; - guint i, attr_hash; - GVariant *variant; NMHashState h; - guint length; nm_hash_init (&h, 63624437); nm_hash_update_vals (&h, tfilter->handle, tfilter->parent); nm_hash_update_str0 (&h, tfilter->kind); + if (tfilter->action) { + gs_free NMUtilsNamedValue *attrs_free = NULL; + NMUtilsNamedValue attrs_static[30]; + const NMUtilsNamedValue *attrs; + guint length; + guint i; + nm_hash_update_str0 (&h, tfilter->action->kind); - names = nm_utils_strdict_get_keys (tfilter->action->attributes, TRUE, &length); + + attrs = nm_utils_named_values_from_strdict (tfilter->action->attributes, &length, attrs_static, &attrs_free); for (i = 0; i < length; i++) { - nm_hash_update_str (&h, names[i]); - variant = g_hash_table_lookup (tfilter->action->attributes, names[i]); + GVariant *variant = attrs[i].value_ptr; + + nm_hash_update_str (&h, attrs[i].name); if (g_variant_type_is_basic (g_variant_get_type (variant))) { + guint attr_hash; + /* g_variant_hash() works only for basic types, thus * we ignore any non-basic attribute. Actions differing * only for non-basic attributes will collide. */ @@ -818,6 +832,7 @@ _nm_tc_tfilter_hash (NMTCTfilter *tfilter) } } } + return nm_hash_complete (&h); } @@ -1374,9 +1389,11 @@ _qdiscs_to_variant (GPtrArray *qdiscs) if (qdiscs) { for (i = 0; i < qdiscs->len; i++) { + NMUtilsNamedValue attrs_static[30]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue *attrs; NMTCQdisc *qdisc = qdiscs->pdata[i]; guint length; - gs_free const char **attrs = nm_utils_strdict_get_keys (qdisc->attributes, TRUE, &length); GVariantBuilder qdisc_builder; guint y; @@ -1391,9 +1408,12 @@ _qdiscs_to_variant (GPtrArray *qdiscs) g_variant_builder_add (&qdisc_builder, "{sv}", "parent", g_variant_new_uint32 (nm_tc_qdisc_get_parent (qdisc))); + attrs = nm_utils_named_values_from_strdict (qdisc->attributes, &length, attrs_static, &attrs_free); for (y = 0; y < length; y++) { - g_variant_builder_add (&qdisc_builder, "{sv}", attrs[y], - g_hash_table_lookup (qdisc->attributes, attrs[y])); + g_variant_builder_add (&qdisc_builder, + "{sv}", + attrs[y].name, + attrs[y].value_ptr); } g_variant_builder_add (&builder, "a{sv}", &qdisc_builder); diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index b4bbdd644e..5270a36ab1 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -272,7 +272,7 @@ nm_setting_vlan_get_num_priorities (NMSettingVlan *setting, NMVlanPriorityMap ma * Retrieve one of the entries of the #NMSettingVlan:ingress_priority_map * or #NMSettingVlan:egress_priority_map properties of this setting. * - * Returns: returns %TRUE if @idx is in range. Otherwise %FALSE. + * Returns: returns %TRUE if @idx is in range. Otherwise, %FALSE. **/ gboolean nm_setting_vlan_get_priority (NMSettingVlan *setting, diff --git a/libnm-core/nm-setting-wifi-p2p.c b/libnm-core/nm-setting-wifi-p2p.c index 065f6e327f..97f0a87d93 100644 --- a/libnm-core/nm-setting-wifi-p2p.c +++ b/libnm-core/nm-setting-wifi-p2p.c @@ -240,7 +240,7 @@ nm_setting_wifi_p2p_class_init (NMSettingWifiP2PClass *setting_wifi_p2p_class) /** * NMSettingWifiP2P:peer: * - * The P2P device that should be connected to. Currently this is the only + * The P2P device that should be connected to. Currently, this is the only * way to create or join a group. * * Since: 1.16 diff --git a/libnm-core/nm-setting-wireguard.c b/libnm-core/nm-setting-wireguard.c index 2bd633cecb..00e37a1f21 100644 --- a/libnm-core/nm-setting-wireguard.c +++ b/libnm-core/nm-setting-wireguard.c @@ -30,7 +30,7 @@ G_DEFINE_BOXED_TYPE (NMWireGuardPeer, nm_wireguard_peer, _wireguard_peer_dup, nm /* NMWireGuardPeer can also track invalid allowed-ip settings, and only reject * them later during is_valid(). Such values are marked by a leading 'X' character - * in the @allowed_ips. It is expected, that such values are the expception, and + * in the @allowed_ips. It is expected, that such values are the exception, and * commonly not present. */ #define ALLOWED_IP_INVALID_X 'X' #define ALLOWED_IP_INVALID_X_STR "X" @@ -157,7 +157,7 @@ nm_wireguard_peer_ref (NMWireGuardPeer *self) * @self: (allow-none): the #NMWireGuardPeer instance * * Drop a reference to @self. If the last reference is dropped, - * the instance is freed and all accociate data released. + * the instance is freed and all associate data released. * * This is not thread-safe. * @@ -737,9 +737,9 @@ nm_wireguard_peer_remove_allowed_ip (NMWireGuardPeer *self, * nm_wireguard_peer_is_valid: * @self: the #NMWireGuardPeer instance * @check_secrets: if %TRUE, non-secret properties are validated. - * Otherwise they are ignored for this purpose. + * Otherwise, they are ignored for this purpose. * @check_non_secrets: if %TRUE, secret properties are validated. - * Otherwise they are ignored for this purpose. + * Otherwise, they are ignored for this purpose. * @error: the #GError location for returning the failure reason. * * Returns: %TRUE if the peer is valid or fails with an error @@ -2458,7 +2458,7 @@ nm_setting_wireguard_class_init (NMSettingWireGuardClass *klass) * NMSettingWireGuard:fwmark: * * The use of fwmark is optional and is by default off. Setting it to 0 - * disables it. Otherwise it is a 32-bit fwmark for outgoing packets. + * disables it. Otherwise, it is a 32-bit fwmark for outgoing packets. * * Note that "ip4-auto-default-route" or "ip6-auto-default-route" enabled, * implies to automatically choose a fwmark. diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 036434cc3c..267920ac0e 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -665,7 +665,7 @@ nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, gu * @setting: the #NMSettingWirelessSecurity * @idx: the index of the key (0..3 inclusive) * @key: the WEP key as a string, in either hexadecimal, ASCII, or passphrase - * form as determiend by the value of the #NMSettingWirelessSecurity:wep-key-type + * form as determined by the value of the #NMSettingWirelessSecurity:wep-key-type * property. * * Sets a WEP key in the given index. diff --git a/libnm-core/nm-setting-wireless-security.h b/libnm-core/nm-setting-wireless-security.h index c9e921af06..1ca0c280fb 100644 --- a/libnm-core/nm-setting-wireless-security.h +++ b/libnm-core/nm-setting-wireless-security.h @@ -78,7 +78,7 @@ typedef enum { * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT: Attempt whichever method AP supports * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED: WPS can not be used. * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO: Use WPS, any method - * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC: use WPS push-buthon method + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC: use WPS push-button method * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN: use PIN method * * Configure the use of WPS by a connection while it activates. diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 124f9c45cf..39bcda6813 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -43,6 +43,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingWireless, PROP_POWERSAVE, PROP_MAC_ADDRESS_RANDOMIZATION, PROP_WAKE_ON_WLAN, + PROP_AP_ISOLATION, ); typedef struct { @@ -55,13 +56,14 @@ typedef struct { char *device_mac_address; char *cloned_mac_address; char *generate_mac_address_mask; + NMSettingMacRandomization mac_address_randomization; + NMTernary ap_isolation; guint32 channel; guint32 rate; guint32 tx_power; guint32 mtu; guint32 powersave; guint32 wowl; - NMSettingMacRandomization mac_address_randomization; bool hidden:1; } NMSettingWirelessPrivate; @@ -739,6 +741,22 @@ _to_dbus_fcn_seen_bssids (const NMSettInfoSetting *sett_info, return g_variant_new_strv ((const char *const*) priv->seen_bssids->pdata, priv->seen_bssids->len); } +/** + * nm_setting_wireless_get_ap_isolation: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:ap-isolation property of the setting + * + * Since: 1.28 + */ +NMTernary +nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NM_TERNARY_DEFAULT); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ap_isolation; +} + /*****************************************************************************/ static gboolean @@ -934,6 +952,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if ( priv->ap_isolation != NM_TERNARY_DEFAULT + && !nm_streq0 (priv->mode, NM_SETTING_WIRELESS_MODE_AP)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("AP isolation can be set only in AP mode")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_AP_ISOLATION); + return FALSE; + } + /* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */ if (priv->cloned_mac_address) { @@ -1094,6 +1123,9 @@ get_property (GObject *object, guint prop_id, case PROP_WAKE_ON_WLAN: g_value_set_uint (value, nm_setting_wireless_get_wake_on_wlan (setting)); break; + case PROP_AP_ISOLATION: + g_value_set_enum (value, priv->ap_isolation); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1203,6 +1235,9 @@ set_property (GObject *object, guint prop_id, case PROP_WAKE_ON_WLAN: priv->wowl = g_value_get_uint (value); break; + case PROP_AP_ISOLATION: + priv->ap_isolation = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1221,6 +1256,7 @@ nm_setting_wireless_init (NMSettingWireless *setting) g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); priv->wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + priv->ap_isolation = NM_TERNARY_DEFAULT; } /** @@ -1769,6 +1805,44 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingWireless:ap-isolation + * + * Configures AP isolation, which prevents communication between + * wireless devices connected to this AP. This property can be set + * to a value different from %NM_TERNARY_DEFAULT only when the + * interface is configured in AP mode. + * + * If set to %NM_TERNARY_TRUE, devices are not able to communicate + * with each other. This increases security because it protects + * devices against attacks from other clients in the network. At + * the same time, it prevents devices to access resources on the + * same wireless networks as file shares, printers, etc. + * + * If set to %NM_TERNARY_FALSE, devices can talk to each other. + * + * When set to %NM_TERNARY_DEFAULT, the global default is used; in + * case the global default is unspecified it is assumed to be + * %NM_TERNARY_FALSE. + * + * Since: 1.28 + **/ + /* ---ifcfg-rh--- + * property: ap-isolation + * variable: AP_ISOLATION(+) + * values: "yes", "no" + * default: missing variable means global default + * description: Whether AP isolation is enabled + * ---end--- + */ + obj_properties[PROP_AP_ISOLATION] = + g_param_spec_enum (NM_SETTING_WIRELESS_AP_ISOLATION, "", "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS, diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h index 093e2ef085..0ae64486f4 100644 --- a/libnm-core/nm-setting-wireless.h +++ b/libnm-core/nm-setting-wireless.h @@ -84,6 +84,7 @@ typedef enum { /*< flags >*/ #define NM_SETTING_WIRELESS_POWERSAVE "powersave" #define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization" #define NM_SETTING_WIRELESS_WAKE_ON_WLAN "wake-on-wlan" +#define NM_SETTING_WIRELESS_AP_ISOLATION "ap-isolation" /** * NM_SETTING_WIRELESS_MODE_ADHOC: @@ -205,6 +206,9 @@ gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless NM_AVAILABLE_IN_1_12 NMSettingWirelessWakeOnWLan nm_setting_wireless_get_wake_on_wlan (NMSettingWireless *setting); +NM_AVAILABLE_IN_1_28 +NMTernary nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting); + G_END_DECLS #endif /* __NM_SETTING_WIRELESS_H__ */ diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index dfb2bed958..06c3d988ee 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -2661,7 +2661,7 @@ nm_setting_option_get_uint32 (NMSetting *setting, * * Note that not all setting types support options. It is a bug * setting a variant to a setting that doesn't support it. - * Currently only #NMSettingEthtool supports it. + * Currently, only #NMSettingEthtool supports it. * * Since: 1.26 */ diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c index 084547c8f8..ca18c7d6a0 100644 --- a/libnm-core/nm-team-utils.c +++ b/libnm-core/nm-team-utils.c @@ -11,7 +11,6 @@ #include "nm-errors.h" #include "nm-utils-private.h" -#include "nm-json.h" #include "nm-glib-aux/nm-json-aux.h" #include "nm-core-internal.h" #include "nm-setting-team.h" @@ -460,9 +459,9 @@ _team_attr_data_to_json (const TeamAttrData *attr_data, _team_attr_data_ASSERT (attr_data); nm_assert (p_field); - nm_json_aux_gstr_append_obj_name (gstr, - attr_data->js_keys[attr_data->js_keys_len - 1], - '\0'); + nm_json_gstr_append_obj_name (gstr, + attr_data->js_keys[attr_data->js_keys_len - 1], + '\0'); if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) { nm_value_type_to_json (attr_data->value_type, gstr, p_field); @@ -482,7 +481,7 @@ _team_attr_data_to_json (const TeamAttrData *attr_data, g_string_append (gstr, "[ "); for (i = 0; i < v_ptrarray->len; i++) { if (i > 0) - nm_json_aux_gstr_append_delimiter (gstr); + nm_json_gstr_append_delimiter (gstr); _link_watcher_to_json (v_ptrarray->pdata[i], gstr); } g_string_append (gstr, " ]"); @@ -500,8 +499,8 @@ _team_attr_data_to_json (const TeamAttrData *attr_data, g_string_append (gstr, "[ "); for (i = 0; i < v_ptrarray->len; i++) { if (i > 0) - nm_json_aux_gstr_append_delimiter (gstr); - nm_json_aux_gstr_append_string (gstr, v_ptrarray->pdata[i]); + nm_json_gstr_append_delimiter (gstr); + nm_json_gstr_append_string (gstr, v_ptrarray->pdata[i]); } g_string_append (gstr, i > 0 ? " ]" : "]"); } @@ -671,7 +670,7 @@ _team_setting_field_to_json (const NMTeamSetting *self, return FALSE; if (prepend_delimiter) - nm_json_aux_gstr_append_delimiter (gstr); + nm_json_gstr_append_delimiter (gstr); _team_attr_data_to_json (attr_data, self->d.is_port, gstr, @@ -1108,29 +1107,29 @@ _link_watcher_to_json (const NMTeamLinkWatcher *link_watcher, if (is_first) is_first = FALSE; else - nm_json_aux_gstr_append_delimiter (gstr); - nm_json_aux_gstr_append_obj_name (gstr, attr_data->js_key, '\0'); + nm_json_gstr_append_delimiter (gstr); + nm_json_gstr_append_obj_name (gstr, attr_data->js_key, '\0'); nm_value_type_to_json (attr_data->value_type, gstr, &p_val->val); } g_string_append (gstr, " }"); } -#if WITH_JSON_VALIDATION static NMTeamLinkWatcher * -_link_watcher_from_json (const json_t *root_js_obj, +_link_watcher_from_json (const NMJsonVt *vt, + const nm_json_t *root_js_obj, gboolean *out_unrecognized_content) { NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)] = { }; const char *j_key; - json_t *j_val; + nm_json_t *j_val; const char *v_name; NMTeamLinkWatcher *result = NULL; - if (!json_is_object (root_js_obj)) + if (!nm_json_is_object (root_js_obj)) goto fail; - json_object_foreach ((json_t *) root_js_obj, j_key, j_val) { + nm_json_object_foreach (vt, (nm_json_t *) root_js_obj, j_key, j_val) { const LinkWatcherAttrData *attr_data = NULL; NMValueTypUnioMaybe *parse_result; @@ -1154,7 +1153,7 @@ _link_watcher_from_json (const json_t *root_js_obj, if (parse_result->has) *out_unrecognized_content = TRUE; - if (!nm_value_type_from_json (attr_data->value_type, j_val, &parse_result->val)) + if (!nm_value_type_from_json (vt, attr_data->value_type, j_val, &parse_result->val)) *out_unrecognized_content = TRUE; else parse_result->has = TRUE; @@ -1218,7 +1217,6 @@ fail: *out_unrecognized_content = TRUE; return NULL; } -#endif /*****************************************************************************/ @@ -1575,15 +1573,15 @@ nm_team_setting_config_get (const NMTeamSetting *self) nm_assert (list_is_empty); - nm_json_aux_gstr_append_obj_name (gstr, "runner", '{'); + nm_json_gstr_append_obj_name (gstr, "runner", '{'); if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1))) list_is_empty2 = FALSE; if (_team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))) { if (!list_is_empty2) - nm_json_aux_gstr_append_delimiter (gstr); - nm_json_aux_gstr_append_obj_name (gstr, "tx_balancer", '{'); + nm_json_gstr_append_delimiter (gstr); + nm_json_gstr_append_obj_name (gstr, "tx_balancer", '{'); if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))) nm_assert_not_reached (); g_string_append (gstr, " }"); @@ -1600,8 +1598,8 @@ nm_team_setting_config_get (const NMTeamSetting *self) if (_team_setting_has_fields_any_v (self, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers))) { if (!list_is_empty) - nm_json_aux_gstr_append_delimiter (gstr); - nm_json_aux_gstr_append_obj_name (gstr, "notify_peers", '{'); + nm_json_gstr_append_delimiter (gstr); + nm_json_gstr_append_obj_name (gstr, "notify_peers", '{'); if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers))) nm_assert_not_reached (); g_string_append (gstr, " }"); @@ -1610,8 +1608,8 @@ nm_team_setting_config_get (const NMTeamSetting *self) if (_team_setting_has_fields_any_v (self, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin))) { if (!list_is_empty) - nm_json_aux_gstr_append_delimiter (gstr); - nm_json_aux_gstr_append_obj_name (gstr, "mcast_rejoin", '{'); + nm_json_gstr_append_delimiter (gstr); + nm_json_gstr_append_obj_name (gstr, "mcast_rejoin", '{'); if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin))) nm_assert_not_reached (); g_string_append (gstr, " }"); @@ -1641,7 +1639,6 @@ nm_team_setting_config_get (const NMTeamSetting *self) /*****************************************************************************/ -#if WITH_JSON_VALIDATION static gboolean _attr_data_match_keys (const TeamAttrData *attr_data, const char *const*keys, @@ -1686,18 +1683,21 @@ _attr_data_find_by_json_key (gboolean is_port, } static void -_js_parse_locate_keys (NMTeamSetting *self, - json_t *root_js_obj, - json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM], +_js_parse_locate_keys (const NMJsonVt *vt, + NMTeamSetting *self, + nm_json_t *root_js_obj, + nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM], gboolean *out_unrecognized_content) { const char *keys[3]; const char *cur_key1; const char *cur_key2; const char *cur_key3; - json_t *cur_val1; - json_t *cur_val2; - json_t *cur_val3; + nm_json_t *cur_val1; + nm_json_t *cur_val2; + nm_json_t *cur_val3; + + nm_assert (vt); #define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content) \ ({ \ @@ -1713,18 +1713,18 @@ _js_parse_locate_keys (NMTeamSetting *self, (_found_keys)[_attr_data->team_attr] = (_cur_val); \ _handled = TRUE; \ } else if ( !_attr_data \ - || !json_is_object ((_cur_val))) { \ + || !nm_json_is_object ((_cur_val))) { \ *(_out_unrecognized_content) = TRUE; \ _handled = TRUE; \ } \ _handled; \ }) - json_object_foreach (root_js_obj, cur_key1, cur_val1) { + nm_json_object_foreach (vt, root_js_obj, cur_key1, cur_val1) { if (!_handle (self, cur_key1, cur_val1, keys, 1, found_keys, out_unrecognized_content)) { - json_object_foreach (cur_val1, cur_key2, cur_val2) { + nm_json_object_foreach (vt, cur_val1, cur_key2, cur_val2) { if (!_handle (self, cur_key2, cur_val2, keys, 2, found_keys, out_unrecognized_content)) { - json_object_foreach (cur_val2, cur_key3, cur_val3) { + nm_json_object_foreach (vt, cur_val2, cur_key3, cur_val3) { if (!_handle (self, cur_key3, cur_val3, keys, 3, found_keys, out_unrecognized_content)) *out_unrecognized_content = TRUE; } @@ -1737,8 +1737,9 @@ _js_parse_locate_keys (NMTeamSetting *self, } static void -_js_parse_unpack (gboolean is_port, - json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM], +_js_parse_unpack (const NMJsonVt *vt, + gboolean is_port, + nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM], bool out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM], NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM], gboolean *out_unrecognized_content, @@ -1747,10 +1748,12 @@ _js_parse_unpack (gboolean is_port, { const TeamAttrData *attr_data; + nm_assert (vt); + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) { NMValueTypUnion *p_out_val; gboolean valid = FALSE; - json_t *arg_js_obj; + nm_json_t *arg_js_obj; if (!_team_attr_data_is_relevant (attr_data, is_port)) continue; @@ -1764,25 +1767,27 @@ _js_parse_unpack (gboolean is_port, p_out_val = &out_val_lst[attr_data->team_attr]; if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) - valid = nm_value_type_from_json (attr_data->value_type, arg_js_obj, p_out_val); + valid = nm_value_type_from_json (vt, attr_data->value_type, arg_js_obj, p_out_val); else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { GPtrArray *link_watchers = NULL; NMTeamLinkWatcher *link_watcher; nm_assert (out_ptr_array_link_watchers_free && !*out_ptr_array_link_watchers_free); - if (json_is_array (arg_js_obj)) { + if (nm_json_is_array (arg_js_obj)) { gsize i, len; - len = json_array_size (arg_js_obj); + len = vt->nm_json_array_size (arg_js_obj); link_watchers = g_ptr_array_new_full (len, (GDestroyNotify) nm_team_link_watcher_unref); for (i = 0; i < len; i++) { - link_watcher = _link_watcher_from_json (json_array_get (arg_js_obj, i), + link_watcher = _link_watcher_from_json (vt, + vt->nm_json_array_get (arg_js_obj, i), out_unrecognized_content); if (link_watcher) g_ptr_array_add (link_watchers, link_watcher); } } else { - link_watcher = _link_watcher_from_json (arg_js_obj, + link_watcher = _link_watcher_from_json (vt, + arg_js_obj, out_unrecognized_content); if (link_watcher) { link_watchers = g_ptr_array_new_full (1, (GDestroyNotify) nm_team_link_watcher_unref); @@ -1799,16 +1804,17 @@ _js_parse_unpack (gboolean is_port, GPtrArray *strv = NULL; nm_assert (out_ptr_array_master_runner_tx_hash_free && !*out_ptr_array_master_runner_tx_hash_free); - if (json_is_array (arg_js_obj)) { + if (nm_json_is_array (arg_js_obj)) { gsize i, len; - len = json_array_size (arg_js_obj); + len = vt->nm_json_array_size (arg_js_obj); if (len > 0) { strv = g_ptr_array_sized_new (len); for (i = 0; i < len; i++) { const char *v_string; - if ( nm_jansson_json_as_string (json_array_get (arg_js_obj, i), + if ( nm_jansson_json_as_string (vt, + vt->nm_json_array_get (arg_js_obj, i), &v_string) <= 0 || !v_string || v_string[0] == '\0') { @@ -1832,11 +1838,11 @@ _js_parse_unpack (gboolean is_port, *out_unrecognized_content = TRUE; } } -#endif guint32 nm_team_setting_config_set (NMTeamSetting *self, const char *js_str) { + const NMJsonVt *vt; guint32 changed_flags = 0; gboolean do_set_default = TRUE; gboolean new_js_str_invalid = FALSE; @@ -1866,30 +1872,29 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str) } else changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG); -#if WITH_JSON_VALIDATION - { - nm_auto_decref_json json_t *root_js_obj = NULL; - - if (nm_jansson_load ()) - root_js_obj = json_loads (js_str, 0, NULL); + if ((vt = nm_json_vt ())) { + nm_auto_decref_json nm_json_t *root_js_obj = NULL; + root_js_obj = vt->nm_json_loads (js_str, 0, NULL); if ( !root_js_obj - || !json_is_object (root_js_obj)) + || !nm_json_is_object (root_js_obj)) new_js_str_invalid = TRUE; else { gboolean unrecognized_content = FALSE; bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { FALSE, }; NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM]; - json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, }; + nm_json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, }; gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL; gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL; - _js_parse_locate_keys (self, + _js_parse_locate_keys (vt, + self, root_js_obj, found_keys, &unrecognized_content); - _js_parse_unpack (self->d.is_port, + _js_parse_unpack (vt, + self->d.is_port, found_keys, has_lst, val_lst, @@ -1906,8 +1911,6 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str) } } -#endif - if (do_set_default) changed_flags |= _team_setting_set_default (self); @@ -2222,6 +2225,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self, GVariantIter iter; const char *v_key; GVariant *v_val; + const NMJsonVt *vt; *out_changed = 0; @@ -2271,10 +2275,12 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self, variants[attr_data->team_attr] = g_steal_pointer (&v_val_free); } + vt = nm_json_vt (); + if (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) { if ( variants[NM_TEAM_ATTRIBUTE_CONFIG] - && WITH_JSON_VALIDATION + && vt && !NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { /* we don't require the content of the "link-watchers" and we also * don't perform strict validation. No need to parse it. */ @@ -2282,7 +2288,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self, gs_free_error GError *local = NULL; /* We might need the parsed v_link_watchers array below (because there is no JSON - * "config" present or because we don't build WITH_JSON_VALIDATION). + * "config" present or because we don't have json support). * * Or we might run with NM_SETTING_PARSE_FLAGS_STRICT. In that mode, we may not necessarily * require that the entire setting as a whole validates (if a JSON config is present and @@ -2310,7 +2316,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self, ? g_variant_get_string (variants[NM_TEAM_ATTRIBUTE_CONFIG], NULL) : NULL); - if ( WITH_JSON_VALIDATION + if ( vt && variants[NM_TEAM_ATTRIBUTE_CONFIG]) { /* for team settings, the JSON must be able to express all possible options. That means, * if the GVariant contains both the JSON "config" and other options, then the other options diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index dd3785be0f..75e8b5bd86 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -13,16 +13,6 @@ #include "nm-setting-private.h" #include "nm-setting-ip-config.h" -struct _NMVariantAttributeSpec { - char *name; - const GVariantType *type; - bool v4:1; - bool v6:1; - bool no_value:1; - bool consumes_rest:1; - char str_type; -}; - #define NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(_name, _type, ...) \ (&((const NMVariantAttributeSpec) { \ .name = _name, \ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 425c302713..b633a5099c 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -16,10 +16,8 @@ #include <sys/stat.h> #include <linux/pkt_sched.h> -#if WITH_JSON_VALIDATION -#include "nm-json.h" -#endif - +#include "nm-glib-aux/nm-json-aux.h" +#include "nm-glib-aux/nm-str-buf.h" #include "nm-glib-aux/nm-enum-utils.h" #include "nm-glib-aux/nm-time-utils.h" #include "nm-glib-aux/nm-secret-utils.h" @@ -2067,8 +2065,8 @@ nm_utils_ip_addresses_from_variant (GVariant *value, g_variant_iter_init (&attrs_iter, addr_var); while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { - if ( strcmp (attr_name, "address") != 0 - && strcmp (attr_name, "prefix") != 0) + if (!NM_IN_STRSET (attr_name, "address", + "prefix")) nm_ip_address_set_attribute (addr, attr_name, attr_val); g_variant_unref (attr_val); } @@ -2193,10 +2191,10 @@ nm_utils_ip_routes_from_variant (GVariant *value, g_variant_iter_init (&attrs_iter, route_var); while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { - if ( strcmp (attr_name, "dest") != 0 - && strcmp (attr_name, "prefix") != 0 - && strcmp (attr_name, "next-hop") != 0 - && strcmp (attr_name, "metric") != 0) + if (!NM_IN_STRSET (attr_name, "dest", + "prefix", + "next-hop", + "metric")) nm_ip_route_set_attribute (route, attr_name, attr_val); g_variant_unref (attr_val); } @@ -2227,7 +2225,7 @@ _string_append_tc_handle (GString *string, guint32 handle) * * This is used to either write out the parent handle to the tc qdisc string * or to pretty-format (use symbolic name for root) the key in keyfile. - * The presence of prefix determnines which one is the case. + * The presence of prefix determines which one is the case. * * Private API due to general ugliness and overall uselessness for anything * sensible. @@ -2376,7 +2374,8 @@ _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc) const char *kind = nm_tc_qdisc_get_kind (qdisc); gs_free char *str = NULL; - if (handle != TC_H_UNSPEC && strcmp (kind, "ingress") != 0) { + if ( handle != TC_H_UNSPEC + && !nm_streq (kind, "ingress")) { g_string_append (string, "handle "); _string_append_tc_handle (string, handle); g_string_append_c (string, ' '); @@ -2468,7 +2467,7 @@ _tc_read_common_opts (const char *str, variant = g_hash_table_lookup (ht, "kind"); if (variant) { *kind = g_variant_dup_string (variant, NULL); - if (strcmp (*kind, "ingress") == 0) { + if (nm_streq (*kind, "ingress")) { if (*parent == TC_H_UNSPEC) *parent = TC_H_INGRESS; if (*handle == TC_H_UNSPEC) @@ -2524,7 +2523,7 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error) return NULL; for (i = 0; rest && tc_qdisc_attribute_spec[i]; i++) { - if (strcmp (tc_qdisc_attribute_spec[i]->kind, kind) == 0) { + if (nm_streq (tc_qdisc_attribute_spec[i]->kind, kind)) { options = nm_utils_parse_variant_attributes (rest, ' ', ' ', FALSE, tc_qdisc_attribute_spec[i]->attrs, @@ -2589,11 +2588,21 @@ _string_append_tc_action (GString *string, NMTCAction *action, GError **error) { const char *kind = nm_tc_action_get_kind (action); gs_free char *str = NULL; + const NMVariantAttributeSpec *const *attrs; + + if (nm_streq (kind, "simple")) + attrs = tc_action_simple_attribute_spec; + else if (nm_streq (kind, "mirred")) + attrs = tc_action_mirred_attribute_spec; + else + attrs = NULL; + g_string_append (string, kind); - str = nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action), - ' ', ' '); + str = _nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action), + attrs, + ' ', ' '); if (str) { g_string_append_c (string, ' '); g_string_append (string, str); @@ -2670,9 +2679,9 @@ nm_utils_tc_action_from_str (const char *str, GError **error) } kind = g_variant_get_string (variant, NULL); - if (strcmp (kind, "simple") == 0) + if (nm_streq (kind, "simple")) attrs = tc_action_simple_attribute_spec; - else if (strcmp (kind, "mirred") == 0) + else if (nm_streq (kind, "mirred")) attrs = tc_action_mirred_attribute_spec; else attrs = NULL; @@ -2893,7 +2902,7 @@ nm_utils_sriov_vf_to_str (const NMSriovVF *vf, gboolean omit_index, GError **err if (num_attrs > 0) { if (!omit_index) g_string_append_c (str, ' '); - _nm_utils_format_variant_attributes_full (str, values, num_attrs, ' ', '='); + _nm_utils_format_variant_attributes_full (str, values, num_attrs, NULL, ' ', '='); } vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans); @@ -3300,30 +3309,29 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g char * _nm_utils_uuid_generate_from_strings (const char *string1, ...) { - GString *str; - va_list args; - const char *s; - char *uuid; - if (!string1) return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS); - str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/ + { + nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); + va_list args; + const char *s; - g_string_append_len (str, string1, strlen (string1) + 1); + nm_str_buf_append_len (&str, string1, strlen (string1) + 1u); - va_start (args, string1); - s = va_arg (args, const char *); - while (s) { - g_string_append_len (str, s, strlen (s) + 1); + va_start (args, string1); s = va_arg (args, const char *); - } - va_end (args); - - uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS); + while (s) { + nm_str_buf_append_len (&str, s, strlen (s) + 1u); + s = va_arg (args, const char *); + } + va_end (args); - g_string_free (str, TRUE); - return uuid; + return nm_utils_uuid_generate_from_string (nm_str_buf_get_str_unsafe (&str), + str.len, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + } } /*****************************************************************************/ @@ -3571,9 +3579,6 @@ nm_utils_file_search_in_paths (const char *progname, gpointer user_data, GError **error) { - GString *tmp; - const char *ret; - g_return_val_if_fail (!error || !*error, NULL); g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL); g_return_val_if_fail (file_test_flags || predicate, NULL); @@ -3582,32 +3587,35 @@ nm_utils_file_search_in_paths (const char *progname, * it simpler to pass in a path from configure checks. */ if ( try_first && try_first[0] == '/' - && (file_test_flags == 0 || g_file_test (try_first, file_test_flags)) - && (!predicate || predicate (try_first, user_data))) + && ( file_test_flags == 0 + || g_file_test (try_first, file_test_flags)) + && ( !predicate + || predicate (try_first, user_data))) return g_intern_string (try_first); - if (!paths || !*paths) - goto NOT_FOUND; + if ( paths + && paths[0]) { + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); - tmp = g_string_sized_new (50); - for (; *paths; paths++) { - if (!*paths) - continue; - g_string_append (tmp, *paths); - if (tmp->str[tmp->len - 1] != '/') - g_string_append_c (tmp, '/'); - g_string_append (tmp, progname); - if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags)) - && (!predicate || predicate (tmp->str, user_data))) { - ret = g_intern_string (tmp->str); - g_string_free (tmp, TRUE); - return ret; + for (; *paths; paths++) { + const char *path = *paths; + const char *s; + + if (!path[0]) + continue; + + nm_str_buf_reset (&strbuf, path); + nm_str_buf_ensure_trailing_c (&strbuf, '/'); + s = nm_str_buf_append0 (&strbuf, progname); + + if ( ( file_test_flags == 0 + || g_file_test (s, file_test_flags)) + && ( !predicate + || predicate (s, user_data))) + return g_intern_string (s); } - g_string_set_size (tmp, 0); } - g_string_free (tmp, TRUE); -NOT_FOUND: g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname); return NULL; } @@ -3620,7 +3628,7 @@ struct cf_pair { guint32 freq; }; -static struct cf_pair a_table[] = { +static const struct cf_pair a_table[] = { /* A band */ { 7, 5035 }, { 8, 5040 }, @@ -3667,10 +3675,60 @@ static struct cf_pair a_table[] = { { 188, 4945 }, { 192, 4960 }, { 196, 4980 }, - { 0, -1 } + { 0, 0 } +}; + +static const guint a_table_freqs[G_N_ELEMENTS (a_table)] = { + /* A band */ + 5035, + 5040, + 5045, + 5055, + 5060, + 5080, + 5170, + 5180, + 5190, + 5200, + 5210, + 5220, + 5230, + 5240, + 5250, + 5260, + 5280, + 5290, + 5300, + 5320, + 5500, + 5520, + 5540, + 5560, + 5580, + 5600, + 5620, + 5640, + 5660, + 5680, + 5700, + 5745, + 5760, + 5765, + 5785, + 5800, + 5805, + 5825, + 4915, + 4920, + 4925, + 4935, + 4945, + 4960, + 4980, + 0, }; -static struct cf_pair bg_table[] = { +static const struct cf_pair bg_table[] = { /* B/G band */ { 1, 2412 }, { 2, 2417 }, @@ -3686,7 +3744,26 @@ static struct cf_pair bg_table[] = { { 12, 2467 }, { 13, 2472 }, { 14, 2484 }, - { 0, -1 } + { 0, 0 } +}; + +static const guint bg_table_freqs[G_N_ELEMENTS (bg_table)] = { + /* B/G band */ + 2412, + 2417, + 2422, + 2427, + 2432, + 2437, + 2442, + 2447, + 2452, + 2457, + 2462, + 2467, + 2472, + 2484, + 0, }; /** @@ -3703,16 +3780,16 @@ nm_utils_wifi_freq_to_channel (guint32 freq) int i = 0; if (freq > 4900) { - while (a_table[i].chan && (a_table[i].freq != freq)) + while ( a_table[i].freq + && (a_table[i].freq != freq)) i++; return a_table[i].chan; - } else { - while (bg_table[i].chan && (bg_table[i].freq != freq)) - i++; - return bg_table[i].chan; } - return 0; + while ( bg_table[i].freq + && (bg_table[i].freq != freq)) + i++; + return bg_table[i].chan; } /** @@ -3748,16 +3825,24 @@ nm_utils_wifi_freq_to_band (guint32 freq) guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) { - int i = 0; + int i; - if (!strcmp (band, "a")) { - while (a_table[i].chan && (a_table[i].chan != channel)) - i++; - return a_table[i].freq; - } else if (!strcmp (band, "bg")) { - while (bg_table[i].chan && (bg_table[i].chan != channel)) - i++; - return bg_table[i].freq; + g_return_val_if_fail (band, 0); + + if (nm_streq (band, "a")) { + for (i = 0; a_table[i].chan; i++) { + if (a_table[i].chan == channel) + return a_table[i].freq; + } + return ((guint32) -1); + } + + if (nm_streq (band, "bg")) { + for (i = 0; bg_table[i].chan; i++) { + if (bg_table[i].chan == channel) + return bg_table[i].freq; + } + return ((guint32) -1); } return 0; @@ -3776,26 +3861,24 @@ nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) { - size_t a_size = sizeof (a_table) / sizeof (struct cf_pair); - size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair); - struct cf_pair *pair = NULL; + size_t a_size = G_N_ELEMENTS (a_table); + size_t bg_size = G_N_ELEMENTS (bg_table); + const struct cf_pair *pair; - if (!strcmp (band, "a")) { + if (nm_streq (band, "a")) { if (channel < a_table[0].chan) return a_table[0].chan; if (channel > a_table[a_size - 2].chan) return a_table[a_size - 2].chan; pair = &a_table[0]; - } else if (!strcmp (band, "bg")) { + } else if (nm_streq (band, "bg")) { if (channel < bg_table[0].chan) return bg_table[0].chan; if (channel > bg_table[bg_size - 2].chan) return bg_table[bg_size - 2].chan; pair = &bg_table[0]; - } else { - g_assert_not_reached (); - return 0; - } + } else + g_return_val_if_reached (0); while (pair->chan) { if (channel == pair->chan) @@ -3823,49 +3906,32 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) { - struct cf_pair *table = NULL; - int i = 0; - - if (!strcmp (band, "a")) - table = a_table; - else if (!strcmp (band, "bg")) - table = bg_table; - else - return FALSE; - - while (table[i].chan && (table[i].chan != channel)) - i++; - - if (table[i].chan != 0) - return TRUE; - else - return FALSE; -} - -static const guint * -_wifi_freqs (gboolean bg_band) -{ - static guint *freqs_2ghz = NULL; - static guint *freqs_5ghz = NULL; - guint *freqs; - - freqs = bg_band ? freqs_2ghz : freqs_5ghz; - if (G_UNLIKELY (freqs == NULL)) { - struct cf_pair *table; - int i; + guint32 freq; - table = bg_band ? bg_table : a_table; - freqs = g_new0 (guint, bg_band ? G_N_ELEMENTS (bg_table) : G_N_ELEMENTS (a_table)); - for (i = 0; table[i].chan; i++) - freqs[i] = table[i].freq; - freqs[i] = 0; - if (bg_band) - freqs_2ghz = freqs; - else - freqs_5ghz = freqs; - } - return freqs; -} + freq = nm_utils_wifi_channel_to_freq (channel, band); + + return !NM_IN_SET (freq, 0u, (guint32) -1); +} + +#define _nm_assert_wifi_freqs(table, table_freqs) \ + G_STMT_START { \ + if (NM_MORE_ASSERT_ONCE (5)) { \ + int i, j; \ + \ + G_STATIC_ASSERT (G_N_ELEMENTS (table) > 0); \ + G_STATIC_ASSERT (G_N_ELEMENTS (table) == G_N_ELEMENTS (table_freqs)); \ + \ + for (i = 0; i < G_N_ELEMENTS (table); i++) { \ + nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].chan == 0)); \ + nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].freq == 0)); \ + nm_assert (table[i].freq == table_freqs[i]); \ + for (j = 0; j < i; j++) { \ + nm_assert (table[j].chan != table[i].chan); \ + nm_assert (table[j].freq != table[i].freq); \ + } \ + } \ + } \ + } G_STMT_END /** * nm_utils_wifi_2ghz_freqs: @@ -3879,7 +3945,8 @@ _wifi_freqs (gboolean bg_band) const guint * nm_utils_wifi_2ghz_freqs (void) { - return _wifi_freqs (TRUE); + _nm_assert_wifi_freqs (bg_table, bg_table_freqs); + return bg_table_freqs; } /** @@ -3894,7 +3961,8 @@ nm_utils_wifi_2ghz_freqs (void) const guint * nm_utils_wifi_5ghz_freqs (void) { - return _wifi_freqs (FALSE); + _nm_assert_wifi_freqs (a_table, a_table_freqs); + return a_table_freqs; } /** @@ -4019,7 +4087,7 @@ fail: * @out_length: the output length in case of success. * * Parses @asc and converts it to binary form in @buffer. - * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed. + * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed. * * It is like nm_utils_hwaddr_aton(), but contrary to that it * can parse addresses of any length. That is, you don't need @@ -4046,7 +4114,7 @@ _nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gs * the size of the buffer in bytes. * * Parses @asc and converts it to binary form in @buffer. - * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed. + * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed. * * Return value: @buffer, or %NULL if @asc couldn't be parsed * or would be shorter or longer than @length. @@ -5028,7 +5096,7 @@ typedef struct { const char *num; } BondMode; -static BondMode bond_mode_table[] = { +static const BondMode bond_mode_table[] = { [0] = { "balance-rr", "0" }, [1] = { "active-backup", "1" }, [2] = { "balance-xor", "2" }, @@ -5080,8 +5148,8 @@ nm_utils_bond_mode_string_to_int (const char *mode) return -1; for (i = 0; i < G_N_ELEMENTS (bond_mode_table); i++) { - if ( strcmp (mode, bond_mode_table[i].str) == 0 - || strcmp (mode, bond_mode_table[i].num) == 0) + if (NM_IN_STRSET (mode, bond_mode_table[i].str, + bond_mode_table[i].num)) return i; } return -1; @@ -5139,13 +5207,13 @@ _nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b) return FALSE; if (k1->type & STRSTRDICTKEY_ALL_SET) { - if (strcmp (k1->data, k2->data) != 0) + if (!nm_streq (k1->data, k2->data)) return FALSE; if (k1->type == STRSTRDICTKEY_ALL_SET) { gsize l = strlen (k1->data) + 1; - return strcmp (&k1->data[l], &k2->data[l]) == 0; + return nm_streq (&k1->data[l], &k2->data[l]); } } @@ -5196,7 +5264,7 @@ validate_dns_option (const char *name, return !!*name; for (desc = option_descs; desc->name; desc++) { - if (!strcmp (name, desc->name) && + if (nm_streq (name, desc->name) && numeric == desc->numeric && (!desc->ipv6_only || ipv6)) return TRUE; @@ -5286,26 +5354,21 @@ _nm_utils_dns_option_validate (const char *option, */ gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) { - gboolean ret; - char *option_name, *tmp_name; + gs_free char *option_name = NULL; guint i; if (!_nm_utils_dns_option_validate (option, &option_name, NULL, FALSE, NULL)) return -1; for (i = 0; i < array->len; i++) { + gs_free char *tmp_name = NULL; + if (_nm_utils_dns_option_validate (array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { - ret = strcmp (tmp_name, option_name); - g_free (tmp_name); - if (!ret) { - g_free (option_name); + if (nm_streq (tmp_name, option_name)) return i; - } } - } - g_free (option_name); return -1; } @@ -5427,9 +5490,9 @@ _nm_utils_is_json_object_no_validation (const char *str, GError **error) gboolean nm_utils_is_json_object (const char *str, GError **error) { -#if WITH_JSON_VALIDATION - nm_auto_decref_json json_t *json = NULL; - json_error_t jerror; + nm_auto_decref_json nm_json_t *json = NULL; + const NMJsonVt *vt; + nm_json_error_t jerror; g_return_val_if_fail (!error || !*error, FALSE); @@ -5441,10 +5504,10 @@ nm_utils_is_json_object (const char *str, GError **error) return FALSE; } - if (!nm_jansson_load ()) + if (!(vt = nm_json_vt ())) return _nm_utils_is_json_object_no_validation (str, error); - json = json_loads (str, JSON_REJECT_DUPLICATES, &jerror); + json = vt->nm_json_loads (str, NM_JSON_REJECT_DUPLICATES, &jerror); if (!json) { g_set_error (error, NM_CONNECTION_ERROR, @@ -5457,7 +5520,7 @@ nm_utils_is_json_object (const char *str, GError **error) /* valid JSON (depending on the definition) can also be a literal. * Here we only allow objects. */ - if (!json_is_object (json)) { + if (!nm_json_is_object (json)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -5466,19 +5529,6 @@ nm_utils_is_json_object (const char *str, GError **error) } return TRUE; -#else /* !WITH_JSON_VALIDATION */ - g_return_val_if_fail (!error || !*error, FALSE); - - if (!str || !str[0]) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - str ? _("value is NULL") : _("value is empty")); - return FALSE; - } - - return _nm_utils_is_json_object_no_validation (str, error); -#endif } static char * @@ -5752,6 +5802,7 @@ nm_utils_format_variant_attributes (GHashTable *attributes, char key_value_separator) { return _nm_utils_format_variant_attributes (attributes, + NULL, attr_separator, key_value_separator); } diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h index 203840376e..a43d710f9d 100644 --- a/libnm-core/nm-version.h +++ b/libnm-core/nm-version.h @@ -243,6 +243,20 @@ # define NM_AVAILABLE_IN_1_26 #endif +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_28 +# define NM_DEPRECATED_IN_1_28 G_DEPRECATED +# define NM_DEPRECATED_IN_1_28_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_1_28 +# define NM_DEPRECATED_IN_1_28_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_28 +# define NM_AVAILABLE_IN_1_28 G_UNAVAILABLE(1,28) +#else +# define NM_AVAILABLE_IN_1_28 +#endif + /* * Synchronous API for calling D-Bus in libnm is deprecated. See * https://developer.gnome.org/libnm/stable/usage.html#sync-api diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c index 7fbd89544c..881bd755ef 100644 --- a/libnm-core/nm-vpn-plugin-info.c +++ b/libnm-core/nm-vpn-plugin-info.c @@ -640,7 +640,7 @@ nm_vpn_plugin_info_list_find_service_type (GSList *list, const char *name) if (info) return g_strdup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (info)->service); - /* check the hard-coded list of short-names. They all have have the same + /* check the hard-coded list of short-names. They all have the same * well-known prefix org.freedesktop.NetworkManager and the name. */ if (nm_utils_strv_find_first ((char **) known_names, G_N_ELEMENTS (known_names), name) >= 0) return g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index f70a7d5a65..1e4efe2452 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -14,6 +14,7 @@ #include "nm-std-aux/c-list-util.h" #include "nm-glib-aux/nm-enum-utils.h" #include "nm-glib-aux/nm-str-buf.h" +#include "nm-glib-aux/nm-json-aux.h" #include "systemd/nm-sd-utils-shared.h" #include "nm-utils.h" @@ -269,7 +270,7 @@ _do_test_nm_utils_strsplit_set_f_one (NMUtilsStrsplitSetFlags flags, g_assert (!NM_FLAGS_ANY (flags, ~( NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY))); - /* assert that the epected words are valid (and don't contain unescaped delimiters). */ + /* assert that the expected words are valid (and don't contain unescaped delimiters). */ for (i = 0; i < words_len; i++) { const char *w = exp_words[i]; @@ -7125,17 +7126,19 @@ test_nm_utils_check_valid_json (void) { _json_config_check_valid (NULL, FALSE); _json_config_check_valid ("", FALSE); -#if WITH_JSON_VALIDATION - _json_config_check_valid ("{ }", TRUE); - _json_config_check_valid ("{ \"a\" : 1 }", TRUE); - _json_config_check_valid ("{ \"a\" : }", FALSE); -#else + /* Without JSON library everything except empty string is considered valid */ + nmtst_json_vt_reset (FALSE); _json_config_check_valid ("{ }", TRUE); _json_config_check_valid ("{'%!-a1} ", TRUE); _json_config_check_valid (" {'%!-a1}", TRUE); _json_config_check_valid ("{'%!-a1", FALSE); -#endif + + if (nmtst_json_vt_reset (TRUE)) { + _json_config_check_valid ("{ }", TRUE); + _json_config_check_valid ("{ \"a\" : 1 }", TRUE); + _json_config_check_valid ("{ \"a\" : }", FALSE); + } } static void @@ -7172,86 +7175,96 @@ _team_config_equal_check (const char *conf1, static void test_nm_utils_team_config_equal (void) { - _team_config_equal_check ("", - "", - TRUE, - TRUE); - _team_config_equal_check ("", - " ", - TRUE, - TRUE); - _team_config_equal_check ("{}", - "{ }", - TRUE, - TRUE); - _team_config_equal_check ("{}", - "{", - TRUE, - TRUE); - _team_config_equal_check ("{ \"a\": 1 }", - "{ \"a\": 1 }", - TRUE, - TRUE); - _team_config_equal_check ("{ \"a\": 1 }", - "{ \"a\": 1 }", - TRUE, - TRUE); - - /* team config */ - _team_config_equal_check ("{ }", - "{ \"runner\" : { \"name\" : \"random\"} }", - FALSE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }", - "{ \"runner\" : { \"name\" : \"random\"} }", - FALSE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"} }", - "{ \"runner\" : { \"name\" : \"random\"} }", - FALSE, - TRUE); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"loadbalance\"} }", - "{ \"runner\" : { \"name\" : \"loadbalance\"} }", - FALSE, - TRUE); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }", - "{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }", - FALSE, - TRUE); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }", - "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }", - FALSE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }", - "{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }", - FALSE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }", - "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\" ] } }", - FALSE, - !WITH_JSON_VALIDATION); - - /* team port config */ - _team_config_equal_check ("{ }", - "{ \"link_watch\" : { \"name\" : \"ethtool\"} }", - TRUE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ }", - "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", - TRUE, - TRUE); - _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }", - "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", - TRUE, - !WITH_JSON_VALIDATION); - _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", - "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", - TRUE, - TRUE); - _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }", - "{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }", - TRUE, - TRUE); + int with_json_vt; + + for (with_json_vt = 0; with_json_vt < 2; with_json_vt++) { + const NMJsonVt *vt; + + vt = nmtst_json_vt_reset (!!with_json_vt); + + _team_config_equal_check ("", + "", + TRUE, + TRUE); + _team_config_equal_check ("", + " ", + TRUE, + TRUE); + _team_config_equal_check ("{}", + "{ }", + TRUE, + TRUE); + _team_config_equal_check ("{}", + "{", + TRUE, + TRUE); + _team_config_equal_check ("{ \"a\": 1 }", + "{ \"a\": 1 }", + TRUE, + TRUE); + _team_config_equal_check ("{ \"a\": 1 }", + "{ \"a\": 1 }", + TRUE, + TRUE); + + /* team config */ + _team_config_equal_check ("{ }", + "{ \"runner\" : { \"name\" : \"random\"} }", + FALSE, + !vt); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }", + "{ \"runner\" : { \"name\" : \"random\"} }", + FALSE, + !vt); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"} }", + "{ \"runner\" : { \"name\" : \"random\"} }", + FALSE, + TRUE); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"loadbalance\"} }", + "{ \"runner\" : { \"name\" : \"loadbalance\"} }", + FALSE, + TRUE); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }", + "{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }", + FALSE, + TRUE); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }", + "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }", + FALSE, + !vt); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }", + "{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }", + FALSE, + !vt); + _team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }", + "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\" ] } }", + FALSE, + !vt); + + /* team port config */ + _team_config_equal_check ("{ }", + "{ \"link_watch\" : { \"name\" : \"ethtool\"} }", + TRUE, + !vt); + _team_config_equal_check ("{ }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + TRUE); + _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + !vt); + _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + TRUE); + _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }", + TRUE, + TRUE); + } + + nmtst_json_vt_reset (TRUE); } /*****************************************************************************/ @@ -7845,7 +7858,7 @@ _do_test_utils_str_utf8safe_unescape (const char *str, const char *expected, gsi if ( expected && l == strlen (expected)) { - /* there are no embeeded NULs. Check that nm_utils_str_utf8safe_unescape() yields the same result. */ + /* there are no embedded NULs. Check that nm_utils_str_utf8safe_unescape() yields the same result. */ s = nm_utils_str_utf8safe_unescape (str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_1); g_assert_cmpstr (s, ==, expected); if (strchr (str, '\\')) { @@ -9100,6 +9113,55 @@ test_strsplit_quoted (void) /*****************************************************************************/ +static void +_do_wifi_ghz_freqs (const guint *freqs, const char *band) +{ + int len; + int j; + int i; + + g_assert (NM_IN_STRSET (band, "a", "bg")); + g_assert (freqs); + g_assert (freqs[0] != 0); + + for (i = 0; freqs[i]; i++) { + for (j = 0; j < i; j++) + g_assert (freqs[i] != freqs[j]); + } + len = i; + + g_assert (nm_utils_wifi_freq_to_channel (0) == 0); + g_assert (nm_utils_wifi_channel_to_freq (0, "bg") == -1); + g_assert (nm_utils_wifi_channel_to_freq (0, "foo") == 0); + g_assert (!nm_utils_wifi_is_channel_valid (0, "bg")); + g_assert (!nm_utils_wifi_is_channel_valid (0, "foo")); + + for (i = 0; i < len; i++) { + guint freq = freqs[i]; + guint32 chan; + guint32 freq2; + + chan = nm_utils_wifi_freq_to_channel (freq); + g_assert (chan != 0); + + freq2 = nm_utils_wifi_channel_to_freq (chan, band); + g_assert (freq2 == freq); + + g_assert (nm_utils_wifi_is_channel_valid (chan, band)); + } + + g_assert (freqs[len] == 0); +} + +static void +test_nm_utils_wifi_ghz_freqs (void) +{ + _do_wifi_ghz_freqs (nm_utils_wifi_2ghz_freqs (), "bg"); + _do_wifi_ghz_freqs (nm_utils_wifi_5ghz_freqs (), "a"); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -9273,6 +9335,7 @@ int main (int argc, char **argv) g_test_add_data_func ("/core/general/test_integrate_maincontext/2", GUINT_TO_POINTER (2), test_integrate_maincontext); g_test_add_func ("/core/general/test_nm_ip_addr_zero", test_nm_ip_addr_zero); + g_test_add_func ("/core/general/test_nm_utils_wifi_ghz_freqs", test_nm_utils_wifi_ghz_freqs); g_test_add_func ("/core/general/test_strsplit_quoted", test_strsplit_quoted); diff --git a/libnm-core/tests/test-keyfile.c b/libnm-core/tests/test-keyfile.c index 23149b618d..c9ec51f01b 100644 --- a/libnm-core/tests/test-keyfile.c +++ b/libnm-core/tests/test-keyfile.c @@ -5,6 +5,7 @@ #include "nm-default.h" +#include "nm-glib-aux/nm-json-aux.h" #include "nm-keyfile/nm-keyfile-utils.h" #include "nm-keyfile/nm-keyfile-internal.h" #include "nm-simple-connection.h" @@ -627,7 +628,7 @@ test_team_conf_read_invalid (void) gs_unref_object NMConnection *con = NULL; NMSettingTeam *s_team; - if (!WITH_JSON_VALIDATION) { + if (!nm_json_vt ()) { g_test_skip ("team test requires JSON validation"); return; } diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index 359c20c43c..1b53baeda3 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -8,6 +8,7 @@ #include <linux/pkt_sched.h> #include <net/if.h> +#include "nm-glib-aux/nm-json-aux.h" #include "nm-core-internal.h" #include "nm-utils.h" #include "nm-utils-private.h" @@ -32,15 +33,6 @@ /*****************************************************************************/ -/* assert that the define is just a plain integer (boolean). */ - -G_STATIC_ASSERT ( (WITH_JSON_VALIDATION) == 1 - || (WITH_JSON_VALIDATION) == 0); - -_nm_unused static const int _with_json_validation = WITH_JSON_VALIDATION; - -/*****************************************************************************/ - /* converts @dict to a connection. In this case, @dict must be good, without warnings, so that * NM_SETTING_PARSE_FLAGS_STRICT and NM_SETTING_PARSE_FLAGS_BEST_EFFORT yield the exact same results. */ static NMConnection * @@ -979,6 +971,24 @@ test_dcb_bandwidth_sums (void) /*****************************************************************************/ static void +test_nm_json (void) +{ + g_assert (NM_IN_SET (WITH_JANSSON, 0, 1)); + +#if WITH_JANSSON + g_assert (nm_json_vt ()); +#else + g_assert (!nm_json_vt ()); +#endif + +#if WITH_JANSSON != defined (JANSSON_SONAME) +#error "WITH_JANSON and JANSSON_SONAME are defined inconsistently." +#endif +} + +/*****************************************************************************/ + +static void _test_team_config_sync (const char *team_config, int notify_peer_count, int notify_peers_interval, @@ -1000,7 +1010,7 @@ _test_team_config_sync (const char *team_config, guint i, j; gboolean found; - if (!WITH_JSON_VALIDATION) { + if (!nm_json_vt ()) { g_test_skip ("team test requires JSON validation"); return; } @@ -1265,7 +1275,7 @@ _test_team_port_config_sync (const char *team_port_config, guint i, j; gboolean found; - if (!WITH_JSON_VALIDATION) { + if (!nm_json_vt ()) { g_test_skip ("team test requires JSON validation"); return; } @@ -1397,7 +1407,7 @@ _check_team_setting (NMSetting *setting) : nm_setting_team_get_config (NM_SETTING_TEAM (setting)), NULL); - if (WITH_JSON_VALIDATION) + if (nm_json_vt ()) nmtst_assert_setting_is_equal (setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); g_clear_object (&setting2); @@ -2389,7 +2399,7 @@ test_tc_config_action (void) } static void -test_tc_config_tfilter (void) +test_tc_config_tfilter_matchall_sdata (void) { NMTCAction *action1; NMTCTfilter *tfilter1, *tfilter2; @@ -2444,6 +2454,50 @@ test_tc_config_tfilter (void) } static void +test_tc_config_tfilter_matchall_mirred (void) +{ + NMTCAction *action; + NMTCTfilter *tfilter1; + GError *error = NULL; + gs_strfreev char **attr_names = NULL; + gs_free char *str; + GVariant *variant; + + tfilter1 = nm_utils_tc_tfilter_from_str ("parent ffff: matchall action mirred ingress mirror dev eth0", &error); + nmtst_assert_success (tfilter1, error); + g_assert_cmpint (nm_tc_tfilter_get_parent (tfilter1), ==, TC_H_MAKE (0xffff << 16, 0)); + g_assert_cmpstr (nm_tc_tfilter_get_kind (tfilter1), ==, "matchall"); + + action = nm_tc_tfilter_get_action (tfilter1); + nm_assert (action); + g_assert_cmpstr (nm_tc_action_get_kind (action), ==, "mirred"); + attr_names = nm_tc_action_get_attribute_names (action); + g_assert (attr_names); + g_assert_cmpint (g_strv_length (attr_names), ==, 3); + + variant = nm_tc_action_get_attribute (action, "ingress"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert (g_variant_get_boolean (variant)); + + variant = nm_tc_action_get_attribute (action, "mirror"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert (g_variant_get_boolean (variant)); + + variant = nm_tc_action_get_attribute (action, "dev"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "eth0"); + + str = nm_utils_tc_tfilter_to_str (tfilter1, &error); + nmtst_assert_success (str, error); + g_assert_cmpstr (str, ==, "parent ffff: matchall action mirred dev eth0 ingress mirror"); + + nm_tc_tfilter_unref (tfilter1); +} + +static void test_tc_config_setting_valid (void) { gs_unref_object NMSettingTCConfig *s_tc = NULL; @@ -3977,10 +4031,10 @@ test_setting_metadata (void) || (pt == &nm_sett_info_propert_type_plain_u && pt_2 == &nm_sett_info_propert_type_deprecated_ignore_u) || (pt_2 == &nm_sett_info_propert_type_plain_u && pt == &nm_sett_info_propert_type_deprecated_ignore_u)) { /* These are known to be duplicated. This is the case for - * "gsm.network-type" and plain properies like "802-11-wireless-security.fils" ("i" D-Bus type) - * "gsm.allowed-bands" and plain properies like "802-11-olpc-mesh.channel" ("u" D-Bus type) + * "gsm.network-type" and plain properties like "802-11-wireless-security.fils" ("i" D-Bus type) + * "gsm.allowed-bands" and plain properties like "802-11-olpc-mesh.channel" ("u" D-Bus type) * While the content/behaviour of the property types are identical, their purpose - * is different. So allowe them. + * is different. So allow them. */ continue; } @@ -4040,7 +4094,10 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/tc_config/qdisc", test_tc_config_qdisc); g_test_add_func ("/libnm/settings/tc_config/action", test_tc_config_action); - g_test_add_func ("/libnm/settings/tc_config/tfilter", test_tc_config_tfilter); + g_test_add_func ("/libnm/settings/tc_config/tfilter/matchall_sdata", + test_tc_config_tfilter_matchall_sdata); + g_test_add_func ("/libnm/settings/tc_config/tfilter/matchall_mirred", + test_tc_config_tfilter_matchall_mirred); g_test_add_func ("/libnm/settings/tc_config/setting/valid", test_tc_config_setting_valid); g_test_add_func ("/libnm/settings/tc_config/setting/duplicates", test_tc_config_setting_duplicates); g_test_add_func ("/libnm/settings/tc_config/dbus", test_tc_config_dbus); @@ -4048,6 +4105,7 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/bridge/vlans", test_bridge_vlans); g_test_add_func ("/libnm/settings/bridge/verify", test_bridge_verify); + g_test_add_func ("/libnm/test_nm_json", test_nm_json); g_test_add_func ("/libnm/settings/team/sync_runner_from_config_roundrobin", test_runner_roundrobin_sync_from_config); g_test_add_func ("/libnm/settings/team/sync_runner_from_config_broadcast", |