From f44c793f6cd89c3e84e83872478daf286821ed64 Mon Sep 17 00:00:00 2001 From: Patrick Talbert Date: Wed, 5 Dec 2018 15:26:50 +0100 Subject: [PATCH 1/2] team: add support for 'vlanid' link-watchers property Add support for the teaming arp_ping link watcher 'vlanid' property. Signed-off-by: Patrick Talbert [thaller@redhat.com: minor fixes to original patch] https://bugzilla.redhat.com/show_bug.cgi?id=1652931 --- clients/common/nm-meta-setting-desc.c | 14 ++++- libnm-core/nm-setting-team.c | 86 +++++++++++++++++++++++++-- libnm-core/nm-setting-team.h | 11 ++++ libnm-core/nm-utils.c | 27 ++++++--- libnm/libnm.ver | 2 + 5 files changed, 124 insertions(+), 16 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 77945bc5cd..e58fe4e6c0 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -285,13 +285,14 @@ _dump_team_link_watcher (NMTeamLinkWatcher *watcher) DUMP_WATCHER_INT (w_dump, watcher, "init-wait", init_wait); DUMP_WATCHER_INT (w_dump, watcher, "interval", interval); DUMP_WATCHER_INT (w_dump, watcher, "missed-max", missed_max); -#undef DUMP_WATCHER_INT g_string_append_printf (w_dump, " target-host=%s", nm_team_link_watcher_get_target_host (watcher)); if (nm_streq (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) return g_string_free (w_dump, FALSE); + DUMP_WATCHER_INT (w_dump, watcher, "vlanid", vlanid); +#undef DUMP_WATCHER_INT g_string_append_printf (w_dump, " source-host=%s", nm_team_link_watcher_get_source_host (watcher)); flags = nm_team_link_watcher_get_flags (watcher); @@ -313,7 +314,7 @@ _parse_team_link_watcher (const char *str, gs_free char *str_clean = NULL; guint i; gs_free const char *name = NULL; - int val1 = 0, val2 = 0, val3 = 3; + int val1 = 0, val2 = 0, val3 = 3, val4 = -1; gs_free const char *target_host = NULL; gs_free const char *source_host = NULL; NMTeamLinkWatcherArpPingFlags flags = 0; @@ -358,6 +359,8 @@ _parse_team_link_watcher (const char *str, val2 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1); else if (nm_streq (pair[0], "missed-max")) val3 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1); + else if (nm_streq (pair[0], "vlanid")) + val4 = _nm_utils_ascii_str_to_int64 (pair[1], 10, -1, 4094, -2); else if (nm_streq (pair[0], "target-host")) target_host = g_strdup (pair[1]); else if (nm_streq (pair[0], "source-host")) @@ -382,6 +385,11 @@ _parse_team_link_watcher (const char *str, "value is not a valid number [0, MAXINT]"); return NULL; } + if (val4 < -1) { + g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], + "value is not a valid number [-1, 4094]"); + return NULL; + } } if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) @@ -389,7 +397,7 @@ _parse_team_link_watcher (const char *str, else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) return nm_team_link_watcher_new_nsna_ping (val1, val2, val3, target_host, error); else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ARP_PING)) - return nm_team_link_watcher_new_arp_ping (val1, val2, val3, target_host, source_host, flags, error); + return nm_team_link_watcher_new_arp_ping2 (val1, val2, val3, val4, target_host, source_host, flags, error); if (!name) g_set_error (error, 1, 0, "link watcher name missing"); diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 0ed96335fb..b12ef0bbcd 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -83,6 +83,7 @@ struct NMTeamLinkWatcher { int init_wait; int interval; int missed_max; + int vlanid; char *target_host; char *source_host; NMTeamLinkWatcherArpPingFlags flags; @@ -277,6 +278,59 @@ nm_team_link_watcher_new_arp_ping (int init_wait, watcher->arp_ping.target_host = g_strdup (target_host); watcher->arp_ping.source_host = g_strdup (source_host); watcher->arp_ping.flags = flags; + watcher->arp_ping.vlanid = -1; + + return watcher; +} + +/** + * nm_team_link_watcher_new_arp_ping2: + * @init_wait: init_wait value + * @interval: interval value + * @missed_max: missed_max value + * @vlanid: vlanid value + * @target_host: the host name or the ip address that will be used as destination + * address in the arp request + * @source_host: the host name or the ip address that will be used as source + * address in the arp request + * @flags: the watcher #NMTeamLinkWatcherArpPingFlags + * @error: (out) (allow-none): location to store the error on failure + * + * Creates a new arp_ping #NMTeamLinkWatcher object + * + * Returns: (transfer full): the new #NMTeamLinkWatcher object, or %NULL on error + * + * Since: 1.16 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_new_arp_ping2 (int init_wait, + int interval, + int missed_max, + int vlanid, + const char *target_host, + const char *source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError **error) +{ + NMTeamLinkWatcher *watcher; + const char *val_fail = NULL; + + watcher = nm_team_link_watcher_new_arp_ping (init_wait, interval, missed_max, + target_host, source_host, flags, + error); + + if (!watcher) + return NULL; + if (vlanid < -1 || vlanid > 4094) + val_fail = "vlanid"; + if (val_fail) { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("vlanid is out of range [-1, 4094]")); + nm_team_link_watcher_unref (watcher); + return NULL; + } + + watcher->arp_ping.vlanid = vlanid; return watcher; } @@ -342,6 +396,7 @@ nm_team_link_watcher_equal (NMTeamLinkWatcher *watcher, NMTeamLinkWatcher *other || watcher->arp_ping.init_wait != other->arp_ping.init_wait || watcher->arp_ping.interval != other->arp_ping.interval || watcher->arp_ping.missed_max != other->arp_ping.missed_max + || watcher->arp_ping.vlanid != other->arp_ping.vlanid || watcher->arp_ping.flags != other->arp_ping.flags) return FALSE; @@ -377,12 +432,13 @@ nm_team_link_watcher_dup (NMTeamLinkWatcher *watcher) NULL); break; case LINK_WATCHER_ARP_PING: - return nm_team_link_watcher_new_arp_ping (watcher->arp_ping.init_wait, - watcher->arp_ping.interval, - watcher->arp_ping.missed_max, - watcher->arp_ping.target_host, - watcher->arp_ping.source_host, - watcher->arp_ping.flags, + return nm_team_link_watcher_new_arp_ping2 (watcher->arp_ping.init_wait, + watcher->arp_ping.interval, + watcher->arp_ping.missed_max, + watcher->arp_ping.vlanid, + watcher->arp_ping.target_host, + watcher->arp_ping.source_host, + watcher->arp_ping.flags, NULL); default: g_assert_not_reached (); @@ -506,6 +562,24 @@ nm_team_link_watcher_get_missed_max (NMTeamLinkWatcher *watcher) return watcher->arp_ping.missed_max; } +/** + * nm_team_link_watcher_get_vlanid: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the VLAN tag ID to be used to outgoing link probes + * + * Since: 1.16 + **/ +int +nm_team_link_watcher_get_vlanid (NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER (watcher, -1); + + if (watcher->type != LINK_WATCHER_ARP_PING) + return -1; + return watcher->arp_ping.vlanid; +} + /** * nm_team_link_watcher_get_target_host: * @watcher: the #NMTeamLinkWatcher diff --git a/libnm-core/nm-setting-team.h b/libnm-core/nm-setting-team.h index a600053a67..5819fecad9 100644 --- a/libnm-core/nm-setting-team.h +++ b/libnm-core/nm-setting-team.h @@ -74,6 +74,15 @@ NMTeamLinkWatcher *nm_team_link_watcher_new_arp_ping (int init_wait, const char *source_host, NMTeamLinkWatcherArpPingFlags flags, GError **error); +NM_AVAILABLE_IN_1_16 +NMTeamLinkWatcher *nm_team_link_watcher_new_arp_ping2 (int init_wait, + int interval, + int missed_max, + int vlanid, + const char *target_host, + const char *source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError **error); NM_AVAILABLE_IN_1_12 void nm_team_link_watcher_ref (NMTeamLinkWatcher *watcher); NM_AVAILABLE_IN_1_12 @@ -100,6 +109,8 @@ NM_AVAILABLE_IN_1_12 const char *nm_team_link_watcher_get_source_host (NMTeamLinkWatcher *watcher); NM_AVAILABLE_IN_1_12 NMTeamLinkWatcherArpPingFlags nm_team_link_watcher_get_flags (NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_16 +int nm_team_link_watcher_get_vlanid (NMTeamLinkWatcher *watcher); #define NM_TYPE_SETTING_TEAM (nm_setting_team_get_type ()) #define NM_SETTING_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TEAM, NMSettingTeam)) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index b70f784d54..d26e64c75f 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -5427,7 +5427,7 @@ _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; + int val1 = 0, val2 = 0, val3 = 3, val4 = -1; NMTeamLinkWatcherArpPingFlags flags = 0; g_return_val_if_fail (json_element, NULL); @@ -5448,6 +5448,8 @@ _nm_utils_team_link_watcher_from_json (json_t *json_element) 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; @@ -5465,8 +5467,8 @@ _nm_utils_team_link_watcher_from_json (json_t *json_element) 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_ping (val1, val2, val3, target_host, - source_host, flags, NULL); + return nm_team_link_watcher_new_arp_ping2 (val1, val2, val3, val4, target_host, + source_host, flags, NULL); } else return NULL; } @@ -5516,6 +5518,9 @@ _nm_utils_team_link_watcher_to_json (NMTeamLinkWatcher *watcher) 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; @@ -6017,6 +6022,12 @@ _nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers) } /* 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))); @@ -6067,7 +6078,7 @@ _nm_utils_team_link_watchers_from_variant (GVariant *value) while (g_variant_iter_next (&iter, "@a{sv}", &watcher_var)) { NMTeamLinkWatcher *watcher; const char *name; - int val1, val2, val3 = 0; + 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; @@ -6098,6 +6109,8 @@ _nm_utils_team_link_watchers_from_variant (GVariant *value) 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)) @@ -6112,9 +6125,9 @@ _nm_utils_team_link_watchers_from_variant (GVariant *value) 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); + 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); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 09681e4733..f1f6954e53 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1450,4 +1450,6 @@ global: nm_client_add_and_activate_connection_options; nm_client_add_and_activate_connection_options_finish; nm_device_get_connectivity; + nm_team_link_watcher_get_vlanid; + nm_team_link_watcher_new_arp_ping2; } libnm_1_14_0; From 99befe7e518da99ff4e0de6ee9b6f15bb4d5446d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 12 Dec 2018 14:07:34 +0100 Subject: [PATCH 2/2] libnm: implement nm_team_link_watcher_new_arp_ping() based on nm_team_link_watcher_new_arp_ping2() nm_team_link_watcher_new_arp_ping2() is the more powerful variant of nm_team_link_watcher_new_arp_ping(). It can do everything the new variant can, and more. Hence, v1 should be implemented based on v2. This way, validating and constructing the watcher is all done in one place, not split in two places. --- libnm-core/nm-setting-team.c | 111 ++++++++++++++++------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index b12ef0bbcd..0ca47e83fa 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -234,53 +234,14 @@ nm_team_link_watcher_new_arp_ping (int init_wait, NMTeamLinkWatcherArpPingFlags flags, GError **error) { - NMTeamLinkWatcher *watcher; - const char *val_fail = NULL; - - if (!target_host || !source_host) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - _("Missing %s in arp_ping link watcher"), - target_host ? "source-host" : "target-host"); - return NULL; - } - - if (strpbrk (target_host, " \\/\t=\"\'")) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - _("target-host '%s' contains invalid characters"), target_host); - return NULL; - } - - if (strpbrk (source_host, " \\/\t=\"\'")) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - _("source-host '%s' contains invalid characters"), source_host); - return NULL; - } - - if (init_wait < 0 || !_NM_INT_LE_MAXINT32 (init_wait)) - val_fail = "init-wait"; - if (interval < 0 || !_NM_INT_LE_MAXINT32 (interval)) - val_fail = "interval"; - if (missed_max < 0 || !_NM_INT_LE_MAXINT32 (missed_max)) - val_fail = "missed-max"; - if (val_fail) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - _("%s is out of range [0, %d]"), val_fail, G_MAXINT32); - return NULL; - } - - watcher = g_slice_new0 (NMTeamLinkWatcher); - watcher->refcount = 1; - - watcher->type = LINK_WATCHER_ARP_PING; - watcher->arp_ping.init_wait = init_wait; - watcher->arp_ping.interval = interval; - watcher->arp_ping.missed_max = missed_max; - watcher->arp_ping.target_host = g_strdup (target_host); - watcher->arp_ping.source_host = g_strdup (source_host); - watcher->arp_ping.flags = flags; - watcher->arp_ping.vlanid = -1; - - return watcher; + return nm_team_link_watcher_new_arp_ping2 (init_wait, + interval, + missed_max, + -1, + target_host, + source_host, + flags, + error); } /** @@ -315,21 +276,53 @@ nm_team_link_watcher_new_arp_ping2 (int init_wait, NMTeamLinkWatcher *watcher; const char *val_fail = NULL; - watcher = nm_team_link_watcher_new_arp_ping (init_wait, interval, missed_max, - target_host, source_host, flags, - error); - - if (!watcher) - return NULL; - if (vlanid < -1 || vlanid > 4094) - val_fail = "vlanid"; - if (val_fail) { - g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, - _("vlanid is out of range [-1, 4094]")); - nm_team_link_watcher_unref (watcher); + if (!target_host || !source_host) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("Missing %s in arp_ping link watcher"), + target_host ? "source-host" : "target-host"); return NULL; } + if (strpbrk (target_host, " \\/\t=\"\'")) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("target-host '%s' contains invalid characters"), target_host); + return NULL; + } + + if (strpbrk (source_host, " \\/\t=\"\'")) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("source-host '%s' contains invalid characters"), source_host); + return NULL; + } + + else if (init_wait < 0 || !_NM_INT_LE_MAXINT32 (init_wait)) + val_fail = "init-wait"; + else if (interval < 0 || !_NM_INT_LE_MAXINT32 (interval)) + val_fail = "interval"; + else if (missed_max < 0 || !_NM_INT_LE_MAXINT32 (missed_max)) + val_fail = "missed-max"; + if (val_fail) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("%s is out of range [0, %d]"), val_fail, G_MAXINT32); + return NULL; + } + + if (vlanid < -1 || vlanid > 4094) { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("vlanid is out of range [-1, 4094]")); + return NULL; + } + + watcher = g_slice_new0 (NMTeamLinkWatcher); + watcher->refcount = 1; + + watcher->type = LINK_WATCHER_ARP_PING; + watcher->arp_ping.init_wait = init_wait; + watcher->arp_ping.interval = interval; + watcher->arp_ping.missed_max = missed_max; + watcher->arp_ping.target_host = g_strdup (target_host); + watcher->arp_ping.source_host = g_strdup (source_host); + watcher->arp_ping.flags = flags; watcher->arp_ping.vlanid = vlanid; return watcher;