diff options
| author | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
| commit | 2e5fa45ddfbb5cffa1e78221f1cea706e2f298af (patch) | |
| tree | 86f69d36c56de3074280456eddc854a780b8e04b /libnm-core/nm-utils.c | |
| parent | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff) | |
New upstream version 1.19.90 upstream/1.19.90
Diffstat (limited to 'libnm-core/nm-utils.c')
| -rw-r--r-- | libnm-core/nm-utils.c | 1236 |
1 files changed, 208 insertions, 1028 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 04d5b1b5..55b004c8 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +36,7 @@ #endif #include "nm-glib-aux/nm-enum-utils.h" +#include "nm-glib-aux/nm-time-utils.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" @@ -851,8 +850,7 @@ _nm_utils_strdict_to_dbus (const GValue *prop_value) } while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)); nm_assert (i == len); - g_qsort_with_data (idx, len, sizeof (idx[0]), - nm_utils_named_entry_cmp_with_data, NULL); + nm_utils_named_value_list_sort (idx, len, NULL, NULL); for (i = 0; i < len; i++) g_variant_builder_add (&builder, "{ss}", idx[i].name, idx[i].value_str); @@ -958,43 +956,51 @@ _nm_utils_bytes_from_dbus (GVariant *dbus_value, g_value_take_boxed (prop_value, bytes); } +/*****************************************************************************/ + GSList * _nm_utils_strv_to_slist (char **strv, gboolean deep_copy) { - int i; GSList *list = NULL; + gsize i; - if (strv) { - if (deep_copy) { - for (i = 0; strv[i]; i++) - list = g_slist_prepend (list, g_strdup (strv[i])); - } else { - for (i = 0; strv[i]; i++) - list = g_slist_prepend (list, strv[i]); - } - } + if (!strv) + return NULL; + if (deep_copy) { + for (i = 0; strv[i]; i++) + list = g_slist_prepend (list, g_strdup (strv[i])); + } else { + for (i = 0; strv[i]; i++) + list = g_slist_prepend (list, strv[i]); + } return g_slist_reverse (list); } char ** -_nm_utils_slist_to_strv (GSList *slist, gboolean deep_copy) +_nm_utils_slist_to_strv (const GSList *slist, gboolean deep_copy) { - GSList *iter; + const GSList *iter; char **strv; - int len, i; + guint len, i; - len = g_slist_length (slist); - if (!len) + if (!slist) return NULL; + + len = g_slist_length ((GSList *) slist); + strv = g_new (char *, len + 1); if (deep_copy) { - for (i = 0, iter = slist; iter; iter = iter->next, i++) + for (i = 0, iter = slist; iter; iter = iter->next, i++) { + nm_assert (iter->data); strv[i] = g_strdup (iter->data); + } } else { - for (i = 0, iter = slist; iter; iter = iter->next, i++) + for (i = 0, iter = slist; iter; iter = iter->next, i++) { + nm_assert (iter->data); strv[i] = iter->data; + } } strv[i] = NULL; @@ -1005,9 +1011,11 @@ GPtrArray * _nm_utils_strv_to_ptrarray (char **strv) { GPtrArray *ptrarray; - int i; + gsize i, l; + + l = NM_PTRARRAY_LEN (strv); - ptrarray = g_ptr_array_new_with_free_func (g_free); + ptrarray = g_ptr_array_new_full (l, g_free); if (strv) { for (i = 0; strv[i]; i++) @@ -1018,10 +1026,10 @@ _nm_utils_strv_to_ptrarray (char **strv) } char ** -_nm_utils_ptrarray_to_strv (GPtrArray *ptrarray) +_nm_utils_ptrarray_to_strv (const GPtrArray *ptrarray) { char **strv; - int i; + guint i; if (!ptrarray) return g_new0 (char *, 1); @@ -1035,6 +1043,8 @@ _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray) return strv; } +/*****************************************************************************/ + static gboolean device_supports_ap_ciphers (guint32 dev_caps, guint32 ap_flags, @@ -2280,41 +2290,80 @@ _nm_utils_string_append_tc_parent (GString *string, const char *prefix, guint32 guint32 _nm_utils_parse_tc_handle (const char *str, GError **error) { - gint64 maj, min; - char *sep; + gint64 maj; + gint64 min = 0; + const char *sep; - maj = g_ascii_strtoll (str, &sep, 0x10); - if (*sep == ':') - min = g_ascii_strtoll (&sep[1], &sep, 0x10); - else - min = 0; + nm_assert (str); + + maj = g_ascii_strtoll (str, (char **) &sep, 0x10); + if (sep == str) + goto fail; + + sep = nm_str_skip_leading_spaces (sep); + + if (sep[0] == ':') { + const char *str2 = &sep[1]; + + min = g_ascii_strtoll (str2, (char **) &sep, 0x10); + sep = nm_str_skip_leading_spaces (sep); + if (sep[0] != '\0') + goto fail; + } else if (sep[0] != '\0') + goto fail; - if (*sep != '\0' || maj <= 0 || maj > 0xffff || min < 0 || min > 0xffff) { - g_set_error (error, 1, 0, _("'%s' is not a valid handle."), str); - return TC_H_UNSPEC; + if ( maj <= 0 + || maj > 0xffff + || min < 0 + || min > 0xffff + || !NM_STRCHAR_ALL (str, ch, ( g_ascii_isxdigit (ch) + || ch == ':' + || g_ascii_isspace (ch)))) { + goto fail; } - return TC_H_MAKE (maj << 16, min); + return TC_H_MAKE (((guint32) maj) << 16, (guint32) min); +fail: + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("'%s' is not a valid handle."), str); + return TC_H_UNSPEC; } -#define TC_ATTR_SPEC_PTR(name, type, no_value, consumes_rest, str_type) \ - &(NMVariantAttributeSpec) { name, type, FALSE, FALSE, no_value, consumes_rest, str_type } +static const NMVariantAttributeSpec *const tc_object_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("root", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("parent", G_VARIANT_TYPE_STRING, .str_type = 'a', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("handle", G_VARIANT_TYPE_STRING, .str_type = 'a', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_qdisc_fq_codel_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("limit", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("flows", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("target", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("interval", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("quantum", G_VARIANT_TYPE_UINT32, ), -static const NMVariantAttributeSpec * const tc_object_attribute_spec[] = { - TC_ATTR_SPEC_PTR ("root", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ), - TC_ATTR_SPEC_PTR ("parent", G_VARIANT_TYPE_STRING, FALSE, FALSE, 'a' ), - TC_ATTR_SPEC_PTR ("handle", G_VARIANT_TYPE_STRING, FALSE, FALSE, 'a' ), - TC_ATTR_SPEC_PTR ("kind", G_VARIANT_TYPE_STRING, TRUE, FALSE, 'a' ), - TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ), + /* 0x83126E97u is not a valid value (it means "disabled"). We should reject that + * value. Or alternatively, reject all values >= MAX_INT(32). */ + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ce_threshold", G_VARIANT_TYPE_UINT32, ), + + /* kernel clamps the value at 2^31. Possibly such values should be rejected from configuration + * as they cannot be configured. Leaving the attribute unspecified causes kernel to choose + * a default (currently 32MB). */ + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("memory_limit", G_VARIANT_TYPE_UINT32, ), + + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ecn", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), NULL, }; typedef struct { const char *kind; - const NMVariantAttributeSpec * const *attrs; + const NMVariantAttributeSpec *const *attrs; } NMQdiscAttributeSpec; static const NMQdiscAttributeSpec *const tc_qdisc_attribute_spec[] = { + &(const NMQdiscAttributeSpec) { "fq_codel", tc_qdisc_fq_codel_spec }, NULL, }; @@ -2524,14 +2573,23 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error) /*****************************************************************************/ -static const NMVariantAttributeSpec * const tc_action_simple_attribute_spec[] = { - TC_ATTR_SPEC_PTR ("sdata", G_VARIANT_TYPE_BYTESTRING, FALSE, FALSE, 0 ), +static const NMVariantAttributeSpec *const tc_action_simple_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("sdata", G_VARIANT_TYPE_BYTESTRING, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_action_mirred_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("egress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ingress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("mirror", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("redirect", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("dev", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ), NULL, }; -static const NMVariantAttributeSpec * const tc_action_attribute_spec[] = { - TC_ATTR_SPEC_PTR ("kind", G_VARIANT_TYPE_STRING, TRUE, FALSE, 'a' ), - TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ), +static const NMVariantAttributeSpec *const tc_action_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ), NULL, }; @@ -2600,7 +2658,7 @@ nm_utils_tc_action_from_str (const char *str, GError **error) gs_unref_hashtable GHashTable *ht = NULL; gs_unref_hashtable GHashTable *options = NULL; GVariant *variant; - const NMVariantAttributeSpec * const *attrs; + const NMVariantAttributeSpec *const *attrs; nm_assert (str); nm_assert (!error || !*error); @@ -2623,6 +2681,8 @@ nm_utils_tc_action_from_str (const char *str, GError **error) kind = g_variant_get_string (variant, NULL); if (strcmp (kind, "simple") == 0) attrs = tc_action_simple_attribute_spec; + else if (strcmp (kind, "mirred") == 0) + attrs = tc_action_mirred_attribute_spec; else attrs = NULL; @@ -2726,9 +2786,9 @@ nm_utils_tc_tfilter_to_str (NMTCTfilter *tfilter, GError **error) return g_string_free (string, FALSE); } -static const NMVariantAttributeSpec * const tc_tfilter_attribute_spec[] = { - TC_ATTR_SPEC_PTR ("action", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ), - TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ), +static const NMVariantAttributeSpec *const tc_tfilter_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("action", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ), NULL, }; @@ -3665,6 +3725,25 @@ nm_utils_wifi_freq_to_channel (guint32 freq) } /** + * nm_utils_wifi_freq_to_band: + * @freq: frequency + * + * Utility function to translate a Wi-Fi frequency to its corresponding band. + * + * Returns: the band containing the frequency or NULL if freq is invalid + **/ +const char * +nm_utils_wifi_freq_to_band (guint32 freq) +{ + if (freq >= 4915 && freq <= 5825) + return "a"; + else if (freq >= 2412 && freq <= 2484) + return "bg"; + + return NULL; +} + +/** * nm_utils_wifi_channel_to_freq: * @channel: channel * @band: frequency band for wireless ("a" or "bg") @@ -4257,12 +4336,16 @@ _nm_utils_hwaddr_to_dbus_impl (const char *str) } GVariant * -_nm_utils_hwaddr_cloned_get (NMSetting *setting, - const char *property) +_nm_utils_hwaddr_cloned_get (const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection *connection, + NMSetting *setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_free char *addr = NULL; - nm_assert (nm_streq0 (property, "cloned-mac-address")); + nm_assert (nm_streq (sett_info->property_infos[property_idx].name, "cloned-mac-address")); g_object_get (setting, "cloned-mac-address", &addr, NULL); return _nm_utils_hwaddr_to_dbus_impl (addr); @@ -4316,7 +4399,8 @@ _nm_utils_hwaddr_cloned_data_synth (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_free char *addr = NULL; @@ -4595,7 +4679,7 @@ nm_utils_is_valid_iface_name_utf8safe (const char *utf8safe_name) /** * nm_utils_is_valid_iface_name: - * @name: Name of interface + * @name: (allow-none): Name of interface * @error: location to store the error occurring, or %NULL to ignore * * Validate the network interface name. @@ -4604,13 +4688,20 @@ nm_utils_is_valid_iface_name_utf8safe (const char *utf8safe_name) * function in net/core/dev.c. * * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + * + * Before 1.20, this function did not accept %NULL as @name argument. If you + * want to run against older versions of libnm, don't pass %NULL. */ gboolean nm_utils_is_valid_iface_name (const char *name, GError **error) { int i; - g_return_val_if_fail (name, FALSE); + if (!name) { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("interface name is missing")); + return FALSE; + } if (name[0] == '\0') { g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -4647,13 +4738,16 @@ nm_utils_is_valid_iface_name (const char *name, GError **error) /** * nm_utils_iface_valid_name: - * @name: Name of interface + * @name: (allow-none): Name of interface * * Validate the network interface name. * * Deprecated: 1.6: use nm_utils_is_valid_iface_name() instead, with better error reporting. * * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + * + * Before 1.20, this function did not accept %NULL as @name argument. If you + * want to run against older versions of libnm, don't pass %NULL. */ gboolean nm_utils_iface_valid_name (const char *name) @@ -4663,11 +4757,14 @@ nm_utils_iface_valid_name (const char *name) /** * nm_utils_is_uuid: - * @str: a string that might be a UUID + * @str: (allow-none): a string that might be a UUID * * Checks if @str is a UUID * * Returns: %TRUE if @str is a UUID, %FALSE if not + * + * In older versions, nm_utils_is_uuid() did not accept %NULL as @str + * argument. Don't pass %NULL if you run against older versions of libnm. */ gboolean nm_utils_is_uuid (const char *str) @@ -4675,7 +4772,8 @@ nm_utils_is_uuid (const char *str) const char *p = str; int num_dashes = 0; - g_return_val_if_fail (str, FALSE); + if (!p) + return FALSE; while (*p) { if (*p == '-') @@ -5326,429 +5424,6 @@ _nm_utils_is_json_object_no_validation (const char *str, GError **error) return FALSE; } -#if WITH_JSON_VALIDATION - -static void -_json_add_object (json_t *json, - const char *key1, - const char *key2, - const char *key3, - json_t *value) -{ - json_t *json_element, *json_link; - - json_element = json_object_get (json, key1); - if (!json_element) { - json_element = value; - if (key2) { - if (key3) { - json_element = json_object (); - json_object_set_new (json_element, key3, value); - } - json_link = json_object (); - json_object_set_new (json_link, key2, json_element); - json_element = json_link; - } - json_object_set_new (json, key1, json_element); - return; - } - - if (!key2) - goto key_already_there; - - json_link = json_element; - json_element = json_object_get (json_element, key2); - if (!json_element) { - json_element = value; - if (key3) { - json_element = json_object (); - json_object_set_new (json_element, key3, value); - } - json_object_set_new (json_link, key2, json_element); - return; - } - - if (!key3) - goto key_already_there; - - json_link = json_element; - json_element = json_object_get (json_element, key3); - if (!json_element) { - json_object_set_new (json_link, key3, value); - return; - } - -key_already_there: - json_decref (value); -} - -/* - * Removes the specified key1[.key2.key3] from json. - * Returns TRUE if json has been modified, FALSE otherwise. */ -static gboolean -_json_del_object (json_t *json, - const char *key1, - const char *key2, - const char *key3) -{ - json_t *json_element = json; - json_t *json_link = NULL; - const char *iter_key = key1; - - if (key2) { - json_link = json; - json_element = json_object_get (json, key1); - if (!json_element) - return FALSE; - iter_key = key2; - } - if (key3) { - json_link = json_element; - json_element = json_object_get (json_element, key2); - if (!json_element) - return FALSE; - iter_key = key3; - } - - if (json_object_del (json_element, iter_key) != 0) - return FALSE; - - /* 1st level key only */ - if (!json_link) - return TRUE; - - if (json_object_size (json_element) == 0) - json_object_del (json_link, (key3 ? key2 : key1)); - - if (key3 && json_object_size (json_link) == 0) - json_object_del (json, key1); - - return TRUE; -} - -/* Adds in place to json the defaults for missing properties; - * the "add_implicit" allows to add to the json also the default - * values used but not shown with teamdctl */ -static void -_json_team_add_defaults (json_t *json, - gboolean port_config, - gboolean add_implicit) -{ - json_t *json_element; - const char *runner = NULL; - - if (port_config) { - _json_add_object (json, "link_watch", "name", NULL, - json_string (NM_TEAM_LINK_WATCHER_ETHTOOL)); - return; - } - - /* Retrieve runner or add default one */ - json_element = json_object_get (json, "runner"); - if (json_element) { - runner = json_string_value (json_object_get (json_element, "name")); - } else { - json_element = json_object (); - json_object_set_new (json, "runner", json_element); - } - if (!runner) { - runner = NM_SETTING_TEAM_RUNNER_DEFAULT; - json_object_set_new (json_element, "name", json_string (runner)); - } - - if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) { - _json_add_object (json, "notify_peers", "count", NULL, - json_integer (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT)); - _json_add_object (json, "mcast_rejoin", "count", NULL, - json_integer (NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT)); - } else if ( nm_streq (runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE) - || nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) { - json_element = json_array (); - json_array_append_new (json_element, json_string ("eth")); - json_array_append_new (json_element, json_string ("ipv4")); - json_array_append_new (json_element, json_string ("ipv6")); - _json_add_object (json, "runner", "tx_hash", NULL, json_element); - } - - if (!add_implicit) - return; - - if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) - _json_add_object (json, "runner", "hwaddr_policy", NULL, json_string ("same_all")); - else if (NM_IN_STRSET (runner, - NM_SETTING_TEAM_RUNNER_LOADBALANCE, - NM_SETTING_TEAM_RUNNER_LACP)) { - _json_add_object (json, "runner", "tx_balancer", "balancing_interval", - json_integer (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT)); - if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) { - _json_add_object (json, "runner", "active", NULL, json_boolean (TRUE)); - _json_add_object (json, "runner", "sys_prio", NULL, - json_integer (NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT)); - _json_add_object (json, "runner", "min_ports", NULL, json_integer (0)); - _json_add_object (json, "runner", "agg_select_policy", NULL, - json_string (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT)); - } - } -} - -static json_t * -_json_find_object (json_t *json, - const char *key1, - const char *key2, - const char *key3) -{ - json_t *json_element; - - if (!key1) - return NULL; - json_element = json_object_get (json, key1); - if (!key2 || !json_element) - return json_element; - - json_element = json_object_get (json_element, key2); - if (!key3 || !json_element) - return json_element; - - json_element = json_object_get (json_element, key3); - return json_element; -} - -static void -_json_delete_object_on_int_match (json_t *json, - const char *key1, - const char *key2, - const char *key3, - int val) -{ - json_t *json_element; - - json_element = _json_find_object (json, key1, key2, key3); - if (!json_element || !json_is_integer (json_element)) - return; - if (json_integer_value (json_element) == val) - _json_del_object (json, key1, key2, key3); -} - -static void -_json_delete_object_on_bool_match (json_t *json, - const char *key1, - const char *key2, - const char *key3, - gboolean val) -{ - json_t *json_element; - - json_element = _json_find_object (json, key1, key2, key3); - if (!json_element || !json_is_boolean (json_element)) - return; - if (json_boolean_value (json_element) == val) - _json_del_object (json, key1, key2, key3); -} - -static void -_json_delete_object_on_string_match (json_t *json, - const char *key1, - const char *key2, - const char *key3, - const char *val) -{ - json_t *json_element; - - json_element = _json_find_object (json, key1, key2, key3); - if (!json_element || !json_is_string (json_element)) - return; - if (nm_streq0 (json_string_value (json_element), val)) - _json_del_object (json, key1, key2, key3); -} - -static void -_json_team_normalize_defaults (json_t *json, gboolean reset) -{ - json_t *json_element; - const char *runner = NM_SETTING_TEAM_RUNNER_DEFAULT; - gs_free char *runner_free = NULL; - int notify_peers_count = 0, notify_peers_interval = 0; - int mcast_rejoin_count = 0, mcast_rejoin_interval = 0; - int runner_tx_balancer_interval = -1; - gboolean runner_active = FALSE, runner_fast_rate = FALSE; - int runner_sys_prio = -1, runner_min_ports = -1; - - json_element = _json_find_object (json, "runner", "name", NULL); - if (json_element) { - runner_free = g_strdup (json_string_value (json_element)); - runner = runner_free; - _json_delete_object_on_string_match (json, "runner", "name", NULL, - NM_SETTING_TEAM_RUNNER_DEFAULT); - } - - /* the runner changed: clear all the properties. Then team.config will be saved - * and reloaded triggering the reset of the values through _nm_utils_team_config_get - */ - if (reset) { - _json_del_object (json, "notify_peers", "count", NULL); - _json_del_object (json, "notify_peers", "interval", NULL); - _json_del_object (json, "mcast_rejoin", "count", NULL); - _json_del_object (json, "mcast_rejoin", "interval", NULL); - _json_del_object (json, "runner", "hwaddr_policy", NULL); - _json_del_object (json, "runner", "tx_hash", NULL); - _json_del_object (json, "runner", "tx_balancer", "name"); - _json_del_object (json, "runner", "tx_balancer", "balancing_interval"); - _json_del_object (json, "runner", "active", NULL); - _json_del_object (json, "runner", "fast_rate", NULL); - _json_del_object (json, "runner", "sys_prio", NULL); - _json_del_object (json, "runner", "min_ports", NULL); - _json_del_object (json, "runner", "agg_select_policy", NULL); - return; - } - - if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) { - notify_peers_count = 1; - mcast_rejoin_count = 1; - _json_delete_object_on_string_match (json, "runner", "hwaddr_policy", NULL, - NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT); - } else if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) { - runner_tx_balancer_interval = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT; - runner_active = TRUE; - runner_sys_prio = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT; - runner_min_ports = 0; - _json_delete_object_on_string_match (json, "runner", "agg_select_policy", NULL, - NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT); - } else if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE)) - runner_tx_balancer_interval = 50; - - _json_delete_object_on_int_match (json, "notify_peers", "count", NULL, notify_peers_count); - _json_delete_object_on_int_match (json, "notify_peers", "interval", NULL, notify_peers_interval); - _json_delete_object_on_int_match (json, "mcast_rejoin", "count", NULL, mcast_rejoin_count); - _json_delete_object_on_int_match (json, "macst_rejoin", "interval", NULL, mcast_rejoin_interval); - _json_delete_object_on_int_match (json, "runner", "tx_balancer", "balancing_interval", - runner_tx_balancer_interval); - _json_delete_object_on_int_match (json, "runner", "sys_prio", NULL, runner_sys_prio); - _json_delete_object_on_int_match (json, "runner", "min_ports", NULL, runner_min_ports); - _json_delete_object_on_bool_match (json, "runner", "active", NULL, runner_active); - _json_delete_object_on_bool_match (json, "runner", "active", NULL, runner_active); - _json_delete_object_on_bool_match (json, "runner", "fast_rate", NULL, runner_fast_rate); -} - -static NMTeamLinkWatcher * -_nm_utils_team_link_watcher_from_json (json_t *json_element) -{ - const char *j_key; - json_t *j_val; - gs_free char *name = NULL, *target_host = NULL, *source_host = NULL; - int val1 = 0, val2 = 0, val3 = 3, val4 = -1; - NMTeamLinkWatcherArpPingFlags flags = 0; - - g_return_val_if_fail (json_element, NULL); - - json_object_foreach (json_element, j_key, j_val) { - if (nm_streq (j_key, "name")) { - g_free (name); - name = strdup (json_string_value (j_val)); - } else if (nm_streq (j_key, "target_host")) { - g_free (target_host); - target_host = strdup (json_string_value (j_val)); - } else if (nm_streq (j_key, "source_host")) { - g_free (source_host); - source_host = strdup (json_string_value (j_val)); - } else if (NM_IN_STRSET (j_key, "delay_up", "init_wait")) - val1 = json_integer_value (j_val); - else if (NM_IN_STRSET (j_key, "delay_down", "interval")) - val2 = json_integer_value (j_val); - else if (nm_streq (j_key, "missed_max")) - val3 = json_integer_value (j_val); - else if (nm_streq (j_key, "vlanid")) - val4 = json_integer_value (j_val); - else if (nm_streq (j_key, "validate_active")) { - if (json_is_true (j_val)) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE; - } else if (nm_streq (j_key, "validate_inactive")) { - if (json_is_true (j_val)) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE; - } else if (nm_streq (j_key, "send_always")) { - if (json_is_true (j_val)) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS; - } - } - - if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) - return nm_team_link_watcher_new_ethtool (val1, val2, NULL); - else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) - return nm_team_link_watcher_new_nsna_ping (val1, val2, val3, target_host, NULL); - else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ARP_PING)) { - return nm_team_link_watcher_new_arp_ping2 (val1, val2, val3, val4, target_host, - source_host, flags, NULL); - } else - return NULL; -} - -static json_t * -_nm_utils_team_link_watcher_to_json (NMTeamLinkWatcher *watcher) -{ - const char *name; - int int_val; - const char *str_val; - NMTeamLinkWatcherArpPingFlags flags = 0; - json_t *json_element; - - g_return_val_if_fail (watcher, NULL); - - json_element = json_object (); - name = nm_team_link_watcher_get_name (watcher); - if (!name) - goto fail; - - json_object_set_new (json_element, "name", json_string (name)); - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { - int_val = nm_team_link_watcher_get_delay_up (watcher); - if (int_val) - json_object_set_new (json_element, "delay_up", json_integer (int_val)); - int_val = nm_team_link_watcher_get_delay_down (watcher); - if (int_val) - json_object_set_new (json_element, "delay_down", json_integer (int_val)); - return json_element; - } - - int_val = nm_team_link_watcher_get_init_wait (watcher); - if (int_val) - json_object_set_new (json_element, "init_wait", json_integer (int_val)); - int_val = nm_team_link_watcher_get_interval (watcher); - if (int_val) - json_object_set_new (json_element, "interval", json_integer (int_val)); - int_val = nm_team_link_watcher_get_missed_max (watcher); - if (int_val != 3) - json_object_set_new (json_element, "missed_max", json_integer (int_val)); - str_val = nm_team_link_watcher_get_target_host (watcher); - if (!str_val) - goto fail; - json_object_set_new (json_element, "target_host", json_string (str_val)); - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) - return json_element; - - int_val = nm_team_link_watcher_get_vlanid (watcher); - if (int_val != -1) - json_object_set_new (json_element, "vlanid", json_integer (int_val)); - str_val = nm_team_link_watcher_get_source_host (watcher); - if (!str_val) - goto fail; - json_object_set_new (json_element, "source_host", json_string (str_val)); - - flags = nm_team_link_watcher_get_flags (watcher); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE) - json_object_set_new (json_element, "validate_active", json_string ("true")); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE) - json_object_set_new (json_element, "validate_inactive", json_string ("true")); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS) - json_object_set_new (json_element, "send_always", json_string ("true")); - - return json_element; - -fail: - json_decref (json_element); - return NULL; -} - /** * nm_utils_is_json_object: * @str: the JSON string to test @@ -5764,6 +5439,7 @@ fail: gboolean nm_utils_is_json_object (const char *str, GError **error) { +#if WITH_JSON_VALIDATION json_t *json; json_error_t jerror; @@ -5803,305 +5479,7 @@ nm_utils_is_json_object (const char *str, GError **error) json_decref (json); return TRUE; -} - -gboolean -_nm_utils_team_config_equal (const char *conf1, - const char *conf2, - gboolean port_config) -{ - json_t *json1 = NULL, *json2 = NULL, *json; - gs_free char *dump1 = NULL, *dump2 = NULL; - json_t *value; - json_error_t jerror; - const char *key; - gboolean ret; - void *tmp; - int i; - - if (nm_streq0 (conf1, conf2)) - return TRUE; - else if (!nm_jansson_load ()) - return FALSE; - - /* A NULL configuration is equivalent to default value '{}' */ - json1 = json_loads (conf1 ?: "{}", JSON_REJECT_DUPLICATES, &jerror); - if (json1) - json2 = json_loads (conf2 ?: "{}", JSON_REJECT_DUPLICATES, &jerror); - - if (!json1 || !json2) { - ret = FALSE; - goto out; - } - - /* Some properties are added by teamd when missing from the initial - * configuration. Add them with the default value if necessary, depending - * on the configuration type. - */ - for (i = 0, json = json1; i < 2; i++, json = json2) - _json_team_add_defaults (json, port_config, FALSE); - - /* Only consider a given subset of nodes, others can change depending on - * current state */ - for (i = 0, json = json1; i < 2; i++, json = json2) { - json_object_foreach_safe (json, tmp, key, value) { - if (!NM_IN_STRSET (key, "runner", "link_watch")) - json_object_del (json, key); - } - } - - dump1 = json_dumps (json1, JSON_INDENT(0) | JSON_ENSURE_ASCII | JSON_SORT_KEYS); - dump2 = json_dumps (json2, JSON_INDENT(0) | JSON_ENSURE_ASCII | JSON_SORT_KEYS); - - ret = nm_streq0 (dump1, dump2); -out: - - if (json1) - json_decref (json1); - if (json2) - json_decref (json2); - - return ret; -} - -GValue * -_nm_utils_team_config_get (const char *conf, - const char *key, - const char *key2, - const char *key3, - gboolean port_config) -{ - json_t *json; - json_t *json_element; - GValue *value = NULL; - json_error_t jerror; - - if (!key) - return NULL; - - if (!nm_jansson_load ()) - return NULL; - - json = json_loads (conf ?: "{}", JSON_REJECT_DUPLICATES, &jerror); - - /* Invalid json in conf */ - if (!json) - return NULL; - - /* Some properties are added by teamd when missing from the initial - * configuration. Add them with the default value if necessary, depending - * on the configuration type. - * Skip this for port config, as some properties change on the basis of the - * runner specified in the master connection... but we don't want to check - * against properties in another connection. Moreover, for team-port we have - * the link-watchers property only here: and for this compound property it is - * fine to show the default value only if explicitly set. - */ - if (!port_config) - _json_team_add_defaults (json, port_config, TRUE); - - /* Now search the property to retrieve */ - json_element = json_object_get (json, key); - if (json_element && key2) - json_element = json_object_get (json_element, key2); - if (json_element && key3) - json_element = json_object_get (json_element, key3); - - if (json_element) { - value = g_new0 (GValue, 1); - if (json_is_string (json_element)) { - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, json_string_value (json_element)); - } else if (json_is_integer (json_element)) { - g_value_init (value, G_TYPE_INT); - g_value_set_int (value, json_integer_value (json_element)); - } else if (json_is_boolean (json_element)) { - g_value_init (value, G_TYPE_BOOLEAN); - g_value_set_boolean (value, json_boolean_value (json_element)); - } else if (nm_streq (key, "link_watch")) { - NMTeamLinkWatcher *watcher; - GPtrArray *data = g_ptr_array_new_with_free_func - ((GDestroyNotify) nm_team_link_watcher_unref); - - if (json_is_array (json_element)) { - json_t *j_watcher; - int index; - - json_array_foreach (json_element, index, j_watcher) { - watcher = _nm_utils_team_link_watcher_from_json (j_watcher); - if (watcher) - g_ptr_array_add (data, watcher); - } - } else { - watcher = _nm_utils_team_link_watcher_from_json (json_element); - if (watcher) - g_ptr_array_add (data, watcher); - } - if (data->len) { - g_value_init (value, G_TYPE_PTR_ARRAY); - g_value_take_boxed (value, data); - } else - g_ptr_array_free (data, TRUE); - - } else if (json_is_array (json_element)) { - GPtrArray *data = g_ptr_array_new_with_free_func (g_free); - json_t *str_element; - int index; - - json_array_foreach (json_element, index, str_element) { - if (json_is_string (str_element)) - g_ptr_array_add (data, g_strdup (json_string_value (str_element))); - } - g_ptr_array_add (data, NULL); - g_value_init (value, G_TYPE_STRV); - g_value_take_boxed (value, g_ptr_array_free (data, FALSE)); - } else { - g_assert_not_reached (); - g_free (value); - value = NULL; - } - } - - if (json) - json_decref (json); - - return value; -} - -/* if conf is updated in place returns TRUE */ -gboolean -_nm_utils_team_config_set (char **conf, - const char *key, - const char *key2, - const char *key3, - const GValue *value) -{ - nm_auto_decref_json json_t *json = NULL; - nm_auto_decref_json json_t *json_value = NULL; - json_t *json_element; - json_t *json_link; - json_error_t jerror; - const char *iter_key = key; - gs_free char *conf_new = NULL; - - g_return_val_if_fail (key, FALSE); - - if (!nm_jansson_load ()) - return FALSE; - - json = json_loads (*conf?: "{}", JSON_REJECT_DUPLICATES, &jerror); - if (!json) - return FALSE; - - if (!value) { - if (!_json_del_object (json, key, key2, key3)) - return FALSE; - goto done; - } - - if (G_VALUE_HOLDS_STRING (value)) - json_value = json_string (g_value_get_string (value)); - else if (G_VALUE_HOLDS_INT (value)) - json_value = json_integer (g_value_get_int (value)); - else if (G_VALUE_HOLDS_BOOLEAN (value)) - json_value = json_boolean (g_value_get_boolean (value)); - else if (G_VALUE_HOLDS_BOXED (value)) { - if (nm_streq (key, "link_watch")) { - gboolean has_array = FALSE; - GPtrArray *array; - guint i; - - array = g_value_get_boxed (value); - if (!array || !array->len) - return FALSE; - - for (i = 0; i < array->len; i++) { - json_t *el; - - el = _nm_utils_team_link_watcher_to_json (array->pdata[i]); - if (!el) - continue; - /* if there is only one watcher, it is added as-is. If there - * are multiple watchers, they are added in an array. */ - if (!json_value) { - json_value = el; - continue; - } - if (!has_array) { - json_t *el_arr; - - has_array = TRUE; - el_arr = json_array(); - json_array_append_new (el_arr, json_value); - json_value = el_arr; - } - json_array_append_new (json_value, el); - } - } else if ( nm_streq (key, "runner") - && nm_streq0 (key2, "tx_hash")) { - const char *const*strv; - gsize i; - - strv = g_value_get_boxed (value); - if (!strv) - return FALSE; - - json_value = json_array (); - for (i = 0; strv[i]; i++) - json_array_append_new (json_value, json_string (strv[i])); - } else { - nm_assert_not_reached (); - return FALSE; - } - - } else { /* G_VALUE_HOLDS_? */ - nm_assert_not_reached (); - return FALSE; - } - - /* Simplest case: first level key only */ - json_element = json; - json_link = NULL; - - if (key2) { - json_link = json; - json_element = json_object_get (json, iter_key); - if (!json_element) { - json_element = json_object (); - json_object_set_new (json_link, iter_key, json_element); - } - iter_key = key2; - } - if (key3) { - json_link = json_element; - json_element = json_object_get (json_link, iter_key); - if (!json_element) { - json_element = json_object (); - json_object_set_new (json_link, iter_key, json_element); - } - iter_key = key3; - } - - json_object_set_new (json_element, iter_key, g_steal_pointer (&json_value)); - -done: - _json_team_normalize_defaults (json, ( nm_streq0 (key, "runner") - && nm_streq0 (key2, "name"))); - conf_new = json_dumps (json, JSON_PRESERVE_ORDER); - if (nm_streq0 (conf_new, "{}")) - nm_clear_g_free (&conf_new); - if (nm_streq0 (conf_new, *conf)) - return FALSE; - g_free (*conf); - *conf = g_steal_pointer (&conf_new); - return TRUE; -} - #else /* !WITH_JSON_VALIDATION */ - -gboolean -nm_utils_is_json_object (const char *str, GError **error) -{ g_return_val_if_fail (!error || !*error, FALSE); if (!str || !str[0]) { @@ -6113,239 +5491,7 @@ nm_utils_is_json_object (const char *str, GError **error) } return _nm_utils_is_json_object_no_validation (str, error); -} - -gboolean -_nm_utils_team_config_equal (const char *conf1, - const char *conf2, - gboolean port_config) -{ - return nm_streq0 (conf1, conf2); -} - -GValue * -_nm_utils_team_config_get (const char *conf, - const char *key, - const char *key2, - const char *key3, - gboolean port_config) -{ - return NULL; -} - -gboolean -_nm_utils_team_config_set (char **conf, - const char *key, - const char *key2, - const char *key3, - const GValue *value) -{ - return FALSE; -} #endif - -/** - * _nm_utils_team_link_watchers_to_variant: - * @link_watchers: (element-type NMTeamLinkWatcher): array of #NMTeamLinkWatcher - * - * Utility function to convert a #GPtrArray of #NMTeamLinkWatcher objects - * representing link watcher configuration for team devices into a #GVariant - * of type 'aa{sv}' representing an array of link watchers. - * - * Returns: (transfer none): a new floating #GVariant representing link watchers. - **/ -GVariant * -_nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers) -{ - GVariantBuilder builder; - int i; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); - - if (!link_watchers) - goto end; - - for (i = 0; i < link_watchers->len; i++) { - NMTeamLinkWatcher *watcher = link_watchers->pdata[i]; - GVariantBuilder watcher_builder; - const char *name; - int int_val; - NMTeamLinkWatcherArpPingFlags flags; - - g_variant_builder_init (&watcher_builder, G_VARIANT_TYPE ("a{sv}")); - - name = nm_team_link_watcher_get_name (watcher); - g_variant_builder_add (&watcher_builder, "{sv}", - "name", - g_variant_new_string (name)); - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { - int_val = nm_team_link_watcher_get_delay_up (watcher); - if (int_val) { - g_variant_builder_add (&watcher_builder, "{sv}", - "delay-up", - g_variant_new_int32 (int_val)); - } - int_val = nm_team_link_watcher_get_delay_down (watcher); - if (int_val) { - g_variant_builder_add (&watcher_builder, "{sv}", - "delay-down", - g_variant_new_int32 (int_val)); - } - g_variant_builder_add (&builder, "a{sv}", &watcher_builder); - continue; - } - - /* Common properties for arp_ping and nsna_ping link watchers */ - int_val = nm_team_link_watcher_get_init_wait (watcher); - if (int_val) { - g_variant_builder_add (&watcher_builder, "{sv}", - "init-wait", - g_variant_new_int32 (int_val)); - } - int_val = nm_team_link_watcher_get_interval (watcher); - if (int_val) { - g_variant_builder_add (&watcher_builder, "{sv}", - "interval", - g_variant_new_int32 (int_val)); - } - int_val = nm_team_link_watcher_get_missed_max (watcher); - if (int_val != 3) { - g_variant_builder_add (&watcher_builder, "{sv}", - "missed-max", - g_variant_new_int32 (int_val)); - } - g_variant_builder_add (&watcher_builder, "{sv}", - "target-host", - g_variant_new_string (nm_team_link_watcher_get_target_host (watcher))); - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) { - g_variant_builder_add (&builder, "a{sv}", &watcher_builder); - continue; - } - - /* arp_ping watcher only */ - int_val = nm_team_link_watcher_get_vlanid (watcher); - if (int_val != -1) { - g_variant_builder_add (&watcher_builder, "{sv}", - "vlanid", - g_variant_new_int32 (int_val)); - } - g_variant_builder_add (&watcher_builder, "{sv}", - "source-host", - g_variant_new_string (nm_team_link_watcher_get_source_host (watcher))); - flags = nm_team_link_watcher_get_flags (watcher); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE) { - g_variant_builder_add (&watcher_builder, "{sv}", - "validate-active", - g_variant_new_boolean (TRUE)); - } - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE) { - g_variant_builder_add (&watcher_builder, "{sv}", - "validate-inactive", - g_variant_new_boolean (TRUE)); - } - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS) { - g_variant_builder_add (&watcher_builder, "{sv}", - "send-always", - g_variant_new_boolean (TRUE)); - } - g_variant_builder_add (&builder, "a{sv}", &watcher_builder); - } -end: - return g_variant_builder_end (&builder); -} - -/** - * _nm_utils_team_link_watchers_from_variant: - * @value: a #GVariant of type 'aa{sv}' - * - * Utility function to convert a #GVariant representing a list of team link - * watchers int a #GPtrArray of #NMTeamLinkWatcher objects. - * - * Returns: (transfer full) (element-type NMTeamLinkWatcher): a newly allocated - * #GPtrArray of #NMTeamLinkWatcher objects. - **/ -GPtrArray * -_nm_utils_team_link_watchers_from_variant (GVariant *value) -{ - GPtrArray *link_watchers; - GVariantIter iter; - GVariant *watcher_var; - - g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL); - - link_watchers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref); - g_variant_iter_init (&iter, value); - - while (g_variant_iter_next (&iter, "@a{sv}", &watcher_var)) { - NMTeamLinkWatcher *watcher; - const char *name; - int val1, val2, val3 = 0, val4 = -1; - const char *target_host = NULL, *source_host = NULL; - gboolean bval; - NMTeamLinkWatcherArpPingFlags flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE; - GError *error = NULL; - - if (!g_variant_lookup (watcher_var, "name", "&s", &name)) - goto next; - if (!NM_IN_STRSET (name, - NM_TEAM_LINK_WATCHER_ETHTOOL, - NM_TEAM_LINK_WATCHER_ARP_PING, - NM_TEAM_LINK_WATCHER_NSNA_PING)) { - goto next; - } - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { - if (!g_variant_lookup (watcher_var, "delay-up", "i", &val1)) - val1 = 0; - if (!g_variant_lookup (watcher_var, "delay-down", "i", &val2)) - val2 = 0; - watcher = nm_team_link_watcher_new_ethtool (val1, val2, &error); - } else { - if (!g_variant_lookup (watcher_var, "target-host", "&s", &target_host)) - goto next; - if (!g_variant_lookup (watcher_var, "init_wait", "i", &val1)) - val1 = 0; - if (!g_variant_lookup (watcher_var, "interval", "i", &val2)) - val2 = 0; - if (!g_variant_lookup (watcher_var, "missed-max", "i", &val3)) - val3 = 3; - if (nm_streq (name, NM_TEAM_LINK_WATCHER_ARP_PING)) { - if (!g_variant_lookup (watcher_var, "vlanid", "i", &val4)) - val4 = -1; - if (!g_variant_lookup (watcher_var, "source-host", "&s", &source_host)) - goto next; - if (!g_variant_lookup (watcher_var, "validate-active", "b", &bval)) - bval = FALSE; - if (bval) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE; - if (!g_variant_lookup (watcher_var, "validate-inactive", "b", &bval)) - bval = FALSE; - if (bval) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE; - if (!g_variant_lookup (watcher_var, "send-always", "b", &bval)) - bval = FALSE; - if (bval) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS; - watcher = nm_team_link_watcher_new_arp_ping2 (val1, val2, val3, val4, - target_host, source_host, - flags, &error); - } else - watcher = nm_team_link_watcher_new_nsna_ping (val1, val2, val3, - target_host, &error); - } - if (!watcher) { - g_clear_error (&error); - goto next; - } - - g_ptr_array_add (link_watchers, watcher); -next: - g_variant_unref (watcher_var); - } - - return link_watchers; } static char * @@ -6415,7 +5561,7 @@ nm_utils_parse_variant_attributes (const char *string, gs_unref_hashtable GHashTable *ht = NULL; const char *ptr = string, *start = NULL, *sep; GVariant *variant; - const NMVariantAttributeSpec * const *s; + const NMVariantAttributeSpec *const *s; g_return_val_if_fail (string, NULL); g_return_val_if_fail (attr_separator, NULL); @@ -6659,24 +5805,23 @@ nm_utils_format_variant_attributes (GHashTable *attributes, gint64 nm_utils_get_timestamp_msec (void) { - struct timespec ts; + gint64 ts; - if (clock_gettime (CLOCK_BOOTTIME, &ts) != -1) - goto success; + ts = nm_utils_clock_gettime_ms (CLOCK_BOOTTIME); + if (ts >= 0) + return ts; - if (errno == EINVAL) { + if (ts == -EINVAL) { /* The fallback to CLOCK_MONOTONIC is taken only if we're running on a * criminally old kernel, prior to 2.6.39 (released on 18 May, 2011). * That happens during buildcheck on old builders, we don't expect to * be actually runs on kernels that old. */ - if (clock_gettime (CLOCK_MONOTONIC, &ts) != -1) - goto success; + ts = nm_utils_clock_gettime_ms (CLOCK_MONOTONIC); + if (ts >= 0) + return ts; } g_return_val_if_reached (-1); - -success: - return (((gint64) ts.tv_sec) * 1000) + (ts.tv_nsec / 1000000); } /*****************************************************************************/ @@ -6767,13 +5912,21 @@ nm_utils_base64secret_normalize (const char *base64_key, } GVariant * -_nm_utils_bridge_vlans_to_dbus (NMSetting *setting, const char *property) +_nm_utils_bridge_vlans_to_dbus (const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection *connection, + NMSetting *setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *vlans = NULL; GVariantBuilder builder; guint i; + const char *property_name = sett_info->property_infos[property_idx].name; + + nm_assert (property_name); - g_object_get (setting, property, &vlans, NULL); + g_object_get (setting, property_name, &vlans, NULL); g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); if (vlans) { @@ -6928,3 +6081,30 @@ _nm_utils_bridge_vlan_verify_list (GPtrArray *vlans, return TRUE; } + +gboolean +nm_utils_connection_is_adhoc_wpa (NMConnection *connection) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char *key_mgmt; + const char *mode; + + s_wifi = nm_connection_get_setting_wireless (connection); + if (!s_wifi) + return FALSE; + + mode = nm_setting_wireless_get_mode (s_wifi); + if (!nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) + return FALSE; + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (!s_wsec) + return FALSE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + if (!nm_streq0 (key_mgmt, "wpa-none")) + return FALSE; + + return TRUE; +} |