diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c index 97edf2da62..9ab4fc0450 100644 --- a/libnm-core/nm-team-utils.c +++ b/libnm-core/nm-team-utils.c @@ -1122,6 +1122,165 @@ fail: /*****************************************************************************/ +static GVariant * +_link_watcher_to_variant (const NMTeamLinkWatcher *watcher) +{ + GVariantBuilder builder; + const char *name; + int int_val; + NMTeamLinkWatcherArpPingFlags flags; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + name = nm_team_link_watcher_get_name (watcher); + g_variant_builder_add (&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 (&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 (&builder, "{sv}", + "delay-down", + g_variant_new_int32 (int_val)); + } + return g_variant_builder_end (&builder); + } + + /* 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 (&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 (&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 (&builder, "{sv}", + "missed-max", + g_variant_new_int32 (int_val)); + } + g_variant_builder_add (&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)) + return g_variant_builder_end (&builder); + + /* arp_ping watcher only */ + int_val = nm_team_link_watcher_get_vlanid (watcher); + if (int_val != -1) { + g_variant_builder_add (&builder, "{sv}", + "vlanid", + g_variant_new_int32 (int_val)); + } + g_variant_builder_add (&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 (&builder, "{sv}", + "validate-active", + g_variant_new_boolean (TRUE)); + } + if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE) { + g_variant_builder_add (&builder, "{sv}", + "validate-inactive", + g_variant_new_boolean (TRUE)); + } + if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS) { + g_variant_builder_add (&builder, "{sv}", + "send-always", + g_variant_new_boolean (TRUE)); + } + return g_variant_builder_end (&builder); +} + +static NMTeamLinkWatcher * +_link_watcher_from_variant (GVariant *watcher_var) +{ + NMTeamLinkWatcher *watcher; + const char *name; + int val1; + int val2; + int val3 = 0; + int val4 = -1; + const char *target_host = NULL; + const char *source_host = NULL; + gboolean bval; + NMTeamLinkWatcherArpPingFlags flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE; + gs_free_error GError *error = NULL; + + nm_assert (g_variant_is_of_type (watcher_var, G_VARIANT_TYPE ("a{sv}"))); + + if (!g_variant_lookup (watcher_var, "name", "&s", &name)) + return NULL; + + if (!NM_IN_STRSET (name, + NM_TEAM_LINK_WATCHER_ETHTOOL, + NM_TEAM_LINK_WATCHER_ARP_PING, + NM_TEAM_LINK_WATCHER_NSNA_PING)) { + return NULL; + } + + 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)) + return NULL; + 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)) + return NULL; + 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); + } + } + + return watcher; +} + +/*****************************************************************************/ + /** * _nm_utils_team_link_watchers_to_variant: * @link_watchers: (element-type NMTeamLinkWatcher): array of #NMTeamLinkWatcher @@ -1130,107 +1289,22 @@ fail: * 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. + * Returns: (transfer full): a new floating #GVariant representing link watchers. **/ GVariant * _nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers) { GVariantBuilder builder; - int i; + guint 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; + if (link_watchers) { + for (i = 0; i < link_watchers->len; i++) { + g_variant_builder_add (&builder, + "@a{sv}", + _link_watcher_to_variant (link_watchers->pdata[i])); } - - /* 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); } @@ -1254,73 +1328,15 @@ _nm_utils_team_link_watchers_from_variant (GVariant *value) 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)) { + _nm_unused gs_unref_variant GVariant *watcher_var_free = 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); + watcher = _link_watcher_from_variant (watcher_var); + if (watcher) + g_ptr_array_add (link_watchers, watcher); } return link_watchers;