diff options
author | Francesco Giudici <fgiudici@redhat.com> | 2017-11-07 14:38:45 +0100 |
---|---|---|
committer | Francesco Giudici <fgiudici@redhat.com> | 2017-12-08 00:46:26 +0100 |
commit | ba4ce843fa796c3e99777743279187b8c95b4743 (patch) | |
tree | 42880b3a342fda02fd0a50f1ab2fa236b32fb674 | |
parent | 72f6d08714f19598eedd5b9d96f032dce0e80c8b (diff) | |
download | NetworkManager-ba4ce843fa796c3e99777743279187b8c95b4743.tar.gz |
libnm-core: add backend for GVariant de/serialization of link_watchers.
-rw-r--r-- | libnm-core/nm-property-compare.c | 34 | ||||
-rw-r--r-- | libnm-core/nm-utils-private.h | 2 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 196 | ||||
-rwxr-xr-x | libnm/generate-setting-docs.py | 1 |
4 files changed, 233 insertions, 0 deletions
diff --git a/libnm-core/nm-property-compare.c b/libnm-core/nm-property-compare.c index d13d019f0a..64ed663c22 100644 --- a/libnm-core/nm-property-compare.c +++ b/libnm-core/nm-property-compare.c @@ -56,6 +56,38 @@ _nm_property_compare_collection (GVariant *value1, GVariant *value2) } static gint +_nm_property_compare_vardict (GVariant *value1, GVariant *value2) +{ + GVariantIter iter; + int len1, len2; + const char *key; + GVariant *val1, *val2; + + len1 = g_variant_n_children (value1); + len2 = g_variant_n_children (value2); + + if (len1 != len2) + return len1 < len2 ? -1 : 1; + + g_variant_iter_init (&iter, value1); + while (g_variant_iter_next (&iter, "{&sv}", &key, &val1)) { + if (!g_variant_lookup (value2, key, "v", &val2)) { + g_variant_unref (val1); + return -1; + } + if (!g_variant_equal (val1, val2)) { + g_variant_unref (val1); + g_variant_unref (val2); + return -1; + } + g_variant_unref (val1); + g_variant_unref (val2); + } + + return 0; +} + +static gint _nm_property_compare_strdict (GVariant *value1, GVariant *value2) { GVariantIter iter; @@ -106,6 +138,8 @@ nm_property_compare (GVariant *value1, GVariant *value2) ret = g_variant_compare (value1, value2); else if (g_variant_is_of_type (value1, G_VARIANT_TYPE ("a{ss}"))) ret = _nm_property_compare_strdict (value1, value2); + else if (g_variant_is_of_type (value1, G_VARIANT_TYPE ("a{sv}"))) + ret = _nm_property_compare_vardict (value1, value2); else if (g_variant_type_is_array (type1)) ret = _nm_property_compare_collection (value1, value2); else if (g_variant_type_is_tuple (type1)) diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index 6b8d58726a..31196694ca 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -78,6 +78,8 @@ void _nm_utils_bytes_from_dbus (GVariant *dbus_value, char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length); +GPtrArray * _nm_utils_team_link_watchers_from_variant (GVariant *value); +GVariant * _nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers); /* JSON to GValue conversion macros */ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index cac5c5e9b4..7d3ad4e380 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4783,6 +4783,202 @@ _nm_utils_team_config_set (char **conf, } #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 */ + 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; + 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, "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_ping (val1, val2, val3, + 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 * attribute_escape (const char *src, char c1, char c2) { diff --git a/libnm/generate-setting-docs.py b/libnm/generate-setting-docs.py index aa0c96ebb2..50ae9d4682 100755 --- a/libnm/generate-setting-docs.py +++ b/libnm/generate-setting-docs.py @@ -54,6 +54,7 @@ dbus_type_name_map = { 'ay': 'byte array', 'a{ss}': 'dict of string to string', 'a{sv}': 'vardict', + 'aa{sv}': 'array of vardict', 'aau': 'array of array of uint32', 'aay': 'array of byte array', 'a(ayuay)': 'array of legacy IPv6 address struct', |