mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-09 17:00:40 +01:00
cli,libnm: merge branch 'th/cli-team-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/121
This commit is contained in:
commit
5aff6fc83b
26 changed files with 2082 additions and 938 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -63,9 +63,11 @@ test-*.trs
|
|||
|
||||
/clients/cli/nmcli
|
||||
/clients/common/settings-docs.h
|
||||
/clients/common/tests/test-general
|
||||
/clients/common/tests/test-libnm-core-aux
|
||||
/clients/nm-online
|
||||
/clients/tui/newt/libnmt-newt.a
|
||||
/clients/tui/nmtui
|
||||
/clients/nm-online
|
||||
|
||||
/data/NetworkManager.service
|
||||
/data/NetworkManager-wait-online.service
|
||||
|
|
@ -146,8 +148,8 @@ test-*.trs
|
|||
/examples/C/qt/list-connections
|
||||
/examples/C/qt/change-ipv4-addresses
|
||||
|
||||
/shared/nm-version-macros.h
|
||||
/shared/nm-utils/tests/test-shared-general
|
||||
/shared/nm-version-macros.h
|
||||
|
||||
/introspection/org.freedesktop.NetworkManager*.[ch]
|
||||
|
||||
|
|
@ -278,8 +280,6 @@ test-*.trs
|
|||
/src/tests/test-utils
|
||||
/src/tests/test-wired-defname
|
||||
|
||||
/clients/common/tests/test-general
|
||||
|
||||
/vapi/*.vapi
|
||||
|
||||
# The following names are no longer present on this branch,
|
||||
|
|
|
|||
38
Makefile.am
38
Makefile.am
|
|
@ -449,6 +449,8 @@ shared_nm_libnm_core_aux_libnm_libnm_core_aux_la_CPPFLAGS = \
|
|||
|
||||
shared_nm_libnm_core_aux_libnm_libnm_core_aux_la_SOURCES = \
|
||||
shared/nm-libnm-core-aux/nm-dispatcher-api.h \
|
||||
shared/nm-libnm-core-aux/nm-libnm-core-aux.c \
|
||||
shared/nm-libnm-core-aux/nm-libnm-core-aux.h \
|
||||
$(NULL)
|
||||
|
||||
shared_nm_libnm_core_aux_libnm_libnm_core_aux_la_LDFLAGS = \
|
||||
|
|
@ -4101,6 +4103,8 @@ clients_common_tests_test_general_LDADD = \
|
|||
|
||||
$(clients_common_tests_test_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
|
||||
|
||||
###############################################################################
|
||||
|
||||
EXTRA_DIST += \
|
||||
clients/common/tests/wg-test0.conf \
|
||||
clients/common/tests/wg-test1.conf \
|
||||
|
|
@ -4108,6 +4112,40 @@ EXTRA_DIST += \
|
|||
clients/common/tests/wg-test3.conf \
|
||||
$(NULL)
|
||||
|
||||
###############################################################################
|
||||
|
||||
check_programs += clients/common/tests/test-libnm-core-aux
|
||||
|
||||
clients_common_tests_test_libnm_core_aux_CPPFLAGS = \
|
||||
$(dflt_cppflags) \
|
||||
-I$(builddir)/shared \
|
||||
-I$(srcdir)/shared \
|
||||
-I$(builddir)/libnm-core \
|
||||
-I$(srcdir)/libnm-core \
|
||||
-I$(builddir)/libnm \
|
||||
-I$(srcdir)/libnm \
|
||||
-DNETWORKMANAGER_COMPILATION_TEST \
|
||||
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_CLIENT \
|
||||
$(CODE_COVERAGE_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(SANITIZER_LIB_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
clients_common_tests_test_libnm_core_aux_LDFLAGS = \
|
||||
$(CODE_COVERAGE_LDFLAGS) \
|
||||
$(SANITIZER_EXEC_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
clients_common_tests_test_libnm_core_aux_LDADD = \
|
||||
shared/nm-libnm-core-aux/libnm-libnm-core-aux.la \
|
||||
libnm/libnm.la \
|
||||
shared/nm-glib-aux/libnm-glib-aux.la \
|
||||
$(GLIB_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
|
||||
$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_lib_h_pub_mkenums)
|
||||
|
||||
###############################################################################
|
||||
# clients/cli
|
||||
###############################################################################
|
||||
|
|
|
|||
|
|
@ -915,88 +915,6 @@ signal_handler (gpointer user_data)
|
|||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nmc_convert_strv_to_string (const GValue *src_value, GValue *dest_value)
|
||||
{
|
||||
char **strings;
|
||||
|
||||
strings = g_value_get_boxed (src_value);
|
||||
if (strings)
|
||||
g_value_take_string (dest_value, g_strjoinv (",", strings));
|
||||
else
|
||||
g_value_set_string (dest_value, "");
|
||||
}
|
||||
|
||||
static void
|
||||
nmc_convert_string_hash_to_string (const GValue *src_value, GValue *dest_value)
|
||||
{
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
const char *key, *value;
|
||||
GString *string;
|
||||
|
||||
hash = (GHashTable *) g_value_get_boxed (src_value);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
if (hash) {
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
|
||||
if (string->len)
|
||||
g_string_append_c (string, ',');
|
||||
g_string_append_printf (string, "%s=%s", key, value);
|
||||
}
|
||||
}
|
||||
|
||||
g_value_take_string (dest_value, g_string_free (string, FALSE));
|
||||
}
|
||||
|
||||
static void
|
||||
nmc_convert_bytes_to_string (const GValue *src_value, GValue *dest_value)
|
||||
{
|
||||
GBytes *bytes;
|
||||
const guint8 *array;
|
||||
gsize length;
|
||||
GString *printable;
|
||||
guint i = 0;
|
||||
|
||||
bytes = g_value_get_boxed (src_value);
|
||||
|
||||
printable = g_string_new ("[");
|
||||
|
||||
if (bytes) {
|
||||
array = g_bytes_get_data (bytes, &length);
|
||||
while (i < MIN (length, 35)) {
|
||||
if (i > 0)
|
||||
g_string_append_c (printable, ' ');
|
||||
g_string_append_printf (printable, "0x%02X", array[i++]);
|
||||
}
|
||||
if (i < length)
|
||||
g_string_append (printable, " ... ");
|
||||
}
|
||||
g_string_append_c (printable, ']');
|
||||
|
||||
g_value_take_string (dest_value, g_string_free (printable, FALSE));
|
||||
}
|
||||
|
||||
static void
|
||||
nmc_value_transforms_register (void)
|
||||
{
|
||||
g_value_register_transform_func (G_TYPE_STRV,
|
||||
G_TYPE_STRING,
|
||||
nmc_convert_strv_to_string);
|
||||
|
||||
/* This depends on the fact that all of the hash-table-valued properties
|
||||
* in libnm-core are string->string.
|
||||
*/
|
||||
g_value_register_transform_func (G_TYPE_HASH_TABLE,
|
||||
G_TYPE_STRING,
|
||||
nmc_convert_string_hash_to_string);
|
||||
|
||||
g_value_register_transform_func (G_TYPE_BYTES,
|
||||
G_TYPE_STRING,
|
||||
nmc_convert_bytes_to_string);
|
||||
}
|
||||
|
||||
void
|
||||
nm_cli_spawn_pager (NmCli *nmc)
|
||||
{
|
||||
|
|
@ -1054,8 +972,6 @@ main (int argc, char *argv[])
|
|||
/* Save terminal settings */
|
||||
tcgetattr (STDIN_FILENO, &termios_orig);
|
||||
|
||||
nmc_value_transforms_register ();
|
||||
|
||||
nm_cli.return_text = g_string_new (_("Success"));
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "nm-glib-aux/nm-enum-utils.h"
|
||||
#include "nm-glib-aux/nm-secret-utils.h"
|
||||
#include "nm-libnm-core-intern/nm-libnm-core-utils.h"
|
||||
#include "nm-libnm-core-aux/nm-libnm-core-aux.h"
|
||||
|
||||
#include "nm-vpn-helpers.h"
|
||||
#include "nm-client-utils.h"
|
||||
|
|
@ -76,6 +77,25 @@ _gtype_property_get_gtype (GType gtype, const char *property_name)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static char *
|
||||
bytes_to_string (GBytes *bytes)
|
||||
{
|
||||
const guint8 *data;
|
||||
gsize len;
|
||||
|
||||
if (!bytes)
|
||||
return NULL;
|
||||
|
||||
data = g_bytes_get_data (bytes, &len);
|
||||
return nm_utils_bin2hexstr_full (data,
|
||||
len,
|
||||
'\0',
|
||||
TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
_int64_cmp_desc (gconstpointer a,
|
||||
gconstpointer b,
|
||||
|
|
@ -432,158 +452,7 @@ _parse_ip_route (int family,
|
|||
return route;
|
||||
}
|
||||
|
||||
static char *
|
||||
_dump_team_link_watcher (NMTeamLinkWatcher *watcher)
|
||||
{
|
||||
const char *name;
|
||||
NMTeamLinkWatcherArpPingFlags flags;
|
||||
GString *w_dump;
|
||||
|
||||
if (!watcher)
|
||||
return NULL;
|
||||
|
||||
w_dump = g_string_new (NULL);
|
||||
name = nm_team_link_watcher_get_name (watcher);
|
||||
g_string_append_printf (w_dump, "name=%s", name);
|
||||
|
||||
#define DUMP_WATCHER_INT(str, watcher, name, key) \
|
||||
G_STMT_START { \
|
||||
int _val = nm_team_link_watcher_get_##key (watcher); \
|
||||
\
|
||||
if (_val) \
|
||||
g_string_append_printf (str, " %s=%d", name, _val); \
|
||||
} G_STMT_END;
|
||||
|
||||
if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
|
||||
DUMP_WATCHER_INT (w_dump, watcher, "delay-up", delay_up);
|
||||
DUMP_WATCHER_INT (w_dump, watcher, "delay-down", delay_down);
|
||||
return g_string_free (w_dump, FALSE);
|
||||
}
|
||||
/* NM_TEAM_LINK_WATCHER_NSNA_PING and NM_TEAM_LINK_WATCHER_ARP_PING */
|
||||
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);
|
||||
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);
|
||||
if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE)
|
||||
g_string_append_printf (w_dump, " validate-active=true");
|
||||
if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE)
|
||||
g_string_append_printf (w_dump, " validate-inactive=true");
|
||||
if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS)
|
||||
g_string_append_printf (w_dump, "send-always=true");
|
||||
|
||||
return g_string_free (w_dump, FALSE);
|
||||
}
|
||||
|
||||
static NMTeamLinkWatcher *
|
||||
_parse_team_link_watcher (const char *str,
|
||||
GError **error)
|
||||
{
|
||||
gs_free const char **watcherv = NULL;
|
||||
gs_free char *str_clean_free = NULL;
|
||||
const char *str_clean;
|
||||
guint i;
|
||||
gs_free const char *name = NULL;
|
||||
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;
|
||||
|
||||
nm_assert (str);
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
str_clean = nm_strstrip_avoid_copy_a (300, str, &str_clean_free);
|
||||
watcherv = nm_utils_strsplit_set (str_clean, " \t");
|
||||
if (!watcherv) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid", str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; watcherv[i]; i++) {
|
||||
gs_free const char **pair = NULL;
|
||||
|
||||
pair = nm_utils_strsplit_set (watcherv[i], "=");
|
||||
if (!pair) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"properties should be specified as 'key=value'");
|
||||
return NULL;
|
||||
}
|
||||
if (!pair[1]) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"missing key value");
|
||||
return NULL;
|
||||
}
|
||||
if (pair[2]) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"properties should be specified as 'key=value'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nm_streq (pair[0], "name"))
|
||||
name = g_strdup (pair[1]);
|
||||
else if ( nm_streq (pair[0], "delay-up")
|
||||
|| nm_streq (pair[0], "init-wait"))
|
||||
val1 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1);
|
||||
else if ( nm_streq (pair[0], "delay-down")
|
||||
|| nm_streq (pair[0], "interval"))
|
||||
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"))
|
||||
source_host = g_strdup (pair[1]);
|
||||
else if (nm_streq (pair[0], "validate-active")) {
|
||||
if (nm_streq (pair[1], "true"))
|
||||
flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE;
|
||||
} else if (nm_streq (pair[0], "validate-inactive")) {
|
||||
if (nm_streq (pair[1], "true"))
|
||||
flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE;
|
||||
} else if (nm_streq (pair[0], "send-always")) {
|
||||
if (nm_streq (pair[1], "true"))
|
||||
flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS;
|
||||
} else {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"unknown key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((val1 < 0) || (val2 < 0) || (val3 < 0)) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"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))
|
||||
return nm_team_link_watcher_new_ethtool (val1, val2, error);
|
||||
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_ping2 (val1, val2, val3, val4, target_host, source_host, flags, error);
|
||||
|
||||
if (!name)
|
||||
g_set_error (error, 1, 0, "link watcher name missing");
|
||||
else
|
||||
g_set_error (error, 1, 0, "unknown link watcher name: '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Max priority values from libnm-core/nm-setting-vlan.c */
|
||||
#define MAX_SKB_PRIO G_MAXUINT32
|
||||
|
|
@ -849,9 +718,21 @@ _SET_FCN_DO_REMOVE (char modifier, const char *value)
|
|||
#define RETURN_STR_TO_FREE(val) \
|
||||
G_STMT_START { \
|
||||
char *_val = (val); \
|
||||
\
|
||||
return ((*(out_to_free)) = _val); \
|
||||
} G_STMT_END
|
||||
|
||||
#define RETURN_STR_TEMPORARY(val) \
|
||||
G_STMT_START { \
|
||||
const char *_val = (val); \
|
||||
\
|
||||
if (_val == NULL) \
|
||||
return NULL; \
|
||||
if (_val[0] == '\0') \
|
||||
return ""; \
|
||||
return ((*(out_to_free)) = g_strdup (_val)); \
|
||||
} G_STMT_END
|
||||
|
||||
static gboolean
|
||||
_gobject_property_is_default (NMSetting *setting, const char *prop_name)
|
||||
{
|
||||
|
|
@ -905,73 +786,167 @@ _gobject_property_reset_default (NMSetting *setting, const char *prop_name)
|
|||
return _gobject_property_reset (setting, prop_name, TRUE);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_coerce_str_emptyunset (NMMetaAccessorGetType get_type,
|
||||
gboolean is_default,
|
||||
const char *cstr,
|
||||
char **out_str)
|
||||
{
|
||||
nm_assert (out_str && !*out_str);
|
||||
nm_assert ( (!is_default && cstr && cstr[0] != '\0')
|
||||
|| NM_IN_STRSET (cstr, NULL, ""));
|
||||
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) {
|
||||
if ( !cstr
|
||||
|| cstr[0] == '\0') {
|
||||
if (is_default)
|
||||
return "";
|
||||
else
|
||||
return "\"\"";
|
||||
}
|
||||
nm_assert (!is_default);
|
||||
return (*out_str = g_strdup_printf ("\"%s\"", cstr));
|
||||
}
|
||||
|
||||
/* we coerce NULL/"" to either "" or " ". */
|
||||
if ( !cstr
|
||||
|| cstr[0] == '\0') {
|
||||
if (is_default)
|
||||
return "";
|
||||
else
|
||||
return " ";
|
||||
}
|
||||
nm_assert (!is_default);
|
||||
return cstr;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_is_default (const NMMetaPropertyInfo *property_info,
|
||||
NMSetting *setting)
|
||||
{
|
||||
if ( property_info->property_typ_data
|
||||
&& property_info->property_typ_data->is_default_fcn)
|
||||
return !!(property_info->property_typ_data->is_default_fcn (setting));
|
||||
|
||||
return _gobject_property_is_default (setting, property_info->property_name);
|
||||
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info,
|
||||
NMSetting *setting,
|
||||
NMMetaAccessorGetType get_type,
|
||||
gboolean handle_emptyunset,
|
||||
gboolean *out_is_default,
|
||||
gpointer *out_to_free)
|
||||
{
|
||||
const char *cstr;
|
||||
GType gtype_prop;
|
||||
nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
|
||||
gboolean is_default;
|
||||
gboolean glib_handles_str_transform;
|
||||
|
||||
RETURN_UNSUPPORTED_GET_TYPE ();
|
||||
NM_SET_OUT (out_is_default, _gobject_property_is_default (setting, property_info->property_name));
|
||||
|
||||
if ( property_info->property_typ_data
|
||||
&& property_info->property_typ_data->is_default_fcn
|
||||
&& property_info->property_typ_data->is_default_fcn (setting)) {
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
|
||||
return _("(default)");
|
||||
return "";
|
||||
}
|
||||
is_default = _is_default (property_info, setting);
|
||||
|
||||
NM_SET_OUT (out_is_default, is_default);
|
||||
|
||||
gtype_prop = _gobject_property_get_gtype (G_OBJECT (setting), property_info->property_name);
|
||||
|
||||
glib_handles_str_transform = !NM_IN_SET (gtype_prop, G_TYPE_BOOLEAN,
|
||||
G_TYPE_STRV,
|
||||
G_TYPE_BYTES,
|
||||
G_TYPE_HASH_TABLE);
|
||||
|
||||
if (glib_handles_str_transform) {
|
||||
/* We rely on the type convertion of the gobject property to string. */
|
||||
g_value_init (&val, G_TYPE_STRING);
|
||||
} else
|
||||
g_value_init (&val, gtype_prop);
|
||||
|
||||
g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
|
||||
|
||||
/* Currently only one particular property asks us to "handle_emptyunset".
|
||||
* So, don't implement it (yet) for the other types, where it's unneeded. */
|
||||
nm_assert ( !handle_emptyunset
|
||||
|| ( gtype_prop == G_TYPE_STRV
|
||||
&& !glib_handles_str_transform));
|
||||
|
||||
if (glib_handles_str_transform)
|
||||
RETURN_STR_TEMPORARY (g_value_get_string (&val));
|
||||
|
||||
if (gtype_prop == G_TYPE_BOOLEAN) {
|
||||
gboolean b;
|
||||
|
||||
g_value_init (&val, gtype_prop);
|
||||
g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
|
||||
b = g_value_get_boolean (&val);
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
|
||||
cstr = b ? _("yes") : _("no");
|
||||
else
|
||||
cstr = b ? "yes" : "no";
|
||||
return cstr;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (gtype_prop == G_TYPE_STRV) {
|
||||
const char *const*strv;
|
||||
|
||||
strv = g_value_get_boxed (&val);
|
||||
if (strv && strv[0])
|
||||
RETURN_STR_TO_FREE (g_strjoinv (",", (char **) strv));
|
||||
|
||||
/* special hack for handling properties that can be empty and unset
|
||||
* (see multilist.clear_emptyunset_fcn). */
|
||||
if (handle_emptyunset) {
|
||||
char *str = NULL;
|
||||
|
||||
cstr = _coerce_str_emptyunset (get_type, is_default, NULL, &str);
|
||||
if (str)
|
||||
RETURN_STR_TO_FREE (str);
|
||||
RETURN_STR_TEMPORARY (cstr);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
if (gtype_prop == G_TYPE_BYTES) {
|
||||
char *str;
|
||||
|
||||
/* Note that we register certain transform functions in nmc_value_transforms_register().
|
||||
* This makes G_TYPE_STRV working.
|
||||
*
|
||||
* FIXME: that is particularly ugly because it's non-obvious which code relies
|
||||
* on nmc_value_transforms_register(). Also, nmc_value_transforms_register() is
|
||||
* in clients/cli, while we are here in clients/common. */
|
||||
g_value_init (&val, G_TYPE_STRING);
|
||||
g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
|
||||
cstr = g_value_get_string (&val);
|
||||
|
||||
if ( property_info->property_typ_data
|
||||
&& property_info->property_typ_data->is_default_fcn) {
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) {
|
||||
str = cstr
|
||||
? g_strdup_printf ("\"%s\"", cstr)
|
||||
: g_strdup ("");
|
||||
} else
|
||||
str = g_strdup (cstr && cstr[0] ? cstr : " ");
|
||||
} else
|
||||
str = cstr ? g_strdup (cstr) : NULL;
|
||||
|
||||
str = bytes_to_string (g_value_get_boxed (&val));
|
||||
NM_SET_OUT (out_is_default, !str || !str[0]);
|
||||
RETURN_STR_TO_FREE (str);
|
||||
}
|
||||
|
||||
if (gtype_prop == G_TYPE_HASH_TABLE) {
|
||||
GHashTable *strdict;
|
||||
gs_free const char **keys = NULL;
|
||||
GString *str;
|
||||
gsize i;
|
||||
|
||||
strdict = g_value_get_boxed (&val);
|
||||
keys = nm_utils_strdict_get_keys (strdict, TRUE, NULL);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
str = g_string_new (NULL);
|
||||
for (i = 0; keys[i]; i++) {
|
||||
if (str->len > 0)
|
||||
g_string_append_c (str, ',');
|
||||
g_string_append_printf (str,
|
||||
"%s=%s",
|
||||
keys[i],
|
||||
(const char *) g_hash_table_lookup (strdict, keys[i]));
|
||||
}
|
||||
RETURN_STR_TO_FREE (g_string_free (str, FALSE));
|
||||
}
|
||||
|
||||
nm_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_gobject (ARGS_GET_FCN)
|
||||
{
|
||||
return _get_fcn_gobject_impl (property_info, setting, get_type, out_is_default, out_to_free);
|
||||
return _get_fcn_gobject_impl (property_info, setting, get_type, FALSE, out_is_default, out_to_free);
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
|
|
@ -1063,7 +1038,7 @@ _get_fcn_gobject_mtu (ARGS_GET_FCN)
|
|||
|
||||
if ( !property_info->property_typ_data
|
||||
|| !property_info->property_typ_data->subtype.mtu.get_fcn)
|
||||
return _get_fcn_gobject_impl (property_info, setting, get_type, out_is_default, out_to_free);
|
||||
return _get_fcn_gobject_impl (property_info, setting, get_type, FALSE, out_is_default, out_to_free);
|
||||
|
||||
mtu = property_info->property_typ_data->subtype.mtu.get_fcn (setting);
|
||||
if (mtu == 0) {
|
||||
|
|
@ -1722,23 +1697,6 @@ wep_key_type_to_string (NMWepKeyType type)
|
|||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
bytes_to_string (GBytes *bytes)
|
||||
{
|
||||
const guint8 *data;
|
||||
gsize len;
|
||||
|
||||
if (!bytes)
|
||||
return NULL;
|
||||
|
||||
data = g_bytes_get_data (bytes, &len);
|
||||
return nm_utils_bin2hexstr_full (data,
|
||||
len,
|
||||
'\0',
|
||||
TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
vlan_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type)
|
||||
{
|
||||
|
|
@ -1839,19 +1797,41 @@ _multilist_do_validate (const NMMetaPropertyInfo *property_info,
|
|||
return item;
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_multilist (ARGS_GET_FCN)
|
||||
{
|
||||
return _get_fcn_gobject_impl (property_info,
|
||||
setting,
|
||||
get_type,
|
||||
property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn != NULL,
|
||||
out_is_default,
|
||||
out_to_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_multilist_clear_property (const NMMetaPropertyInfo *property_info,
|
||||
NMSetting *setting,
|
||||
gboolean is_set /* or else set default */)
|
||||
{
|
||||
if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn) {
|
||||
property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn (setting, is_set);
|
||||
return TRUE;
|
||||
}
|
||||
if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) {
|
||||
property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting);
|
||||
return TRUE;
|
||||
}
|
||||
return _gobject_property_reset (setting, property_info->property_name, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_fcn_multilist (ARGS_SET_FCN)
|
||||
{
|
||||
gs_free const char **strv = NULL;
|
||||
gsize i, j, nstrv;
|
||||
|
||||
if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) {
|
||||
if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) {
|
||||
property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting);
|
||||
return TRUE;
|
||||
}
|
||||
return _gobject_property_reset (setting, property_info->property_name, FALSE);
|
||||
}
|
||||
if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value))
|
||||
return _multilist_clear_property (property_info, setting, FALSE);
|
||||
|
||||
if ( _SET_FCN_DO_REMOVE (modifier, value)
|
||||
&& ( property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32
|
||||
|
|
@ -1884,6 +1864,11 @@ _set_fcn_multilist (ARGS_SET_FCN)
|
|||
}
|
||||
}
|
||||
|
||||
if ( _SET_FCN_DO_SET_ALL (modifier, value)
|
||||
&& property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn
|
||||
&& value[0] == '\0')
|
||||
return _multilist_clear_property (property_info, setting, FALSE);
|
||||
|
||||
strv = _value_strsplit (value,
|
||||
property_info->property_typ_data->subtype.multilist.strsplit_plain
|
||||
? VALUE_STRSPLIT_MODE_MULTILIST
|
||||
|
|
@ -1906,11 +1891,13 @@ _set_fcn_multilist (ARGS_SET_FCN)
|
|||
}
|
||||
nstrv = j;
|
||||
|
||||
if (_SET_FCN_DO_SET_ALL (modifier, value)) {
|
||||
if (property_info->property_typ_data->subtype.multilist.clear_all_fcn)
|
||||
property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting);
|
||||
else
|
||||
_gobject_property_reset (setting, property_info->property_name, FALSE);
|
||||
if (_SET_FCN_DO_SET_ALL (modifier, value))
|
||||
_multilist_clear_property (property_info, setting, TRUE);
|
||||
else if ( property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn
|
||||
&& _is_default (property_info, setting)) {
|
||||
/* the property is already the default. But we hav here a '+' / '-' modifier, so
|
||||
* that always makes it non-default (empty) first. */
|
||||
_multilist_clear_property (property_info, setting, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < nstrv; i++) {
|
||||
|
|
@ -2298,21 +2285,6 @@ _set_fcn_cert_8021x (ARGS_SET_FCN)
|
|||
}
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_gobject_bytes (ARGS_GET_FCN)
|
||||
{
|
||||
gs_unref_bytes GBytes *bytes = NULL;
|
||||
char *str;
|
||||
|
||||
RETURN_UNSUPPORTED_GET_TYPE ();
|
||||
|
||||
g_object_get (setting, property_info->property_name, &bytes, NULL);
|
||||
|
||||
str = bytes_to_string (bytes);
|
||||
NM_SET_OUT (out_is_default, !str || !str[0]);
|
||||
RETURN_STR_TO_FREE (str);
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_bond_options (ARGS_GET_FCN)
|
||||
{
|
||||
|
|
@ -3362,8 +3334,7 @@ _objlist_set_fcn_ip_config_routes (NMSetting *setting,
|
|||
static gboolean
|
||||
_is_default_func_ip_config_dns_options (NMSetting *setting)
|
||||
{
|
||||
return nm_setting_ip_config_has_dns_options (NM_SETTING_IP_CONFIG (setting))
|
||||
&& !nm_setting_ip_config_get_num_dns_options (NM_SETTING_IP_CONFIG (setting));
|
||||
return !nm_setting_ip_config_has_dns_options (NM_SETTING_IP_CONFIG (setting));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3779,9 +3750,9 @@ _objlist_obj_to_str_fcn_team_link_watchers (NMMetaAccessorGetType get_type,
|
|||
else
|
||||
watcher = nm_setting_team_port_get_link_watcher (NM_SETTING_TEAM_PORT (setting), idx);
|
||||
|
||||
s = _dump_team_link_watcher (watcher);
|
||||
s = nm_utils_team_link_watcher_to_string (watcher);
|
||||
if (s)
|
||||
g_string_append (str, s);
|
||||
nm_utils_escaped_tokens_escape_gstr (s, ESCAPED_TOKENS_DELIMITERS, str);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -3792,7 +3763,7 @@ _objlist_set_fcn_team_link_watchers (NMSetting *setting,
|
|||
{
|
||||
nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher = NULL;
|
||||
|
||||
watcher = _parse_team_link_watcher (value, error);
|
||||
watcher = nm_utils_team_link_watcher_from_string (value, error);
|
||||
if (!watcher)
|
||||
return FALSE;
|
||||
if (NM_IS_SETTING_TEAM (setting)) {
|
||||
|
|
@ -4412,7 +4383,7 @@ static const NMMetaPropertyType _pt_gobject_mtu = {
|
|||
};
|
||||
|
||||
static const NMMetaPropertyType _pt_gobject_bytes = {
|
||||
.get_fcn = _get_fcn_gobject_bytes,
|
||||
.get_fcn = _get_fcn_gobject,
|
||||
.set_fcn = _set_fcn_gobject_bytes,
|
||||
};
|
||||
|
||||
|
|
@ -4466,7 +4437,7 @@ static const NMMetaPropertyType _pt_ethtool = {
|
|||
};
|
||||
|
||||
static const NMMetaPropertyType _pt_multilist = {
|
||||
.get_fcn = _get_fcn_gobject,
|
||||
.get_fcn = _get_fcn_multilist,
|
||||
.set_fcn = _set_fcn_multilist,
|
||||
.set_supports_remove = TRUE,
|
||||
};
|
||||
|
|
@ -4485,6 +4456,7 @@ static const NMMetaPropertyType _pt_objlist = {
|
|||
#define MULTILIST_REMOVE_BY_IDX_FCN_S(type, func) (((func) == ((void (*) (type *, int )) (func))) ? ((void (*) (NMSetting *, int )) (func)) : NULL)
|
||||
#define MULTILIST_REMOVE_BY_IDX_FCN_U(type, func) (((func) == ((void (*) (type *, guint )) (func))) ? ((void (*) (NMSetting *, guint )) (func)) : NULL)
|
||||
#define MULTILIST_REMOVE_BY_VALUE_FCN(type, func) (((func) == ((gboolean (*) (type *, const char *)) (func))) ? ((gboolean (*) (NMSetting *, const char *)) (func)) : NULL)
|
||||
#define MULTILIST_CLEAR_EMPTYUNSET_FCN(type, func) (((func) == ((void (*) (type *, gboolean )) (func))) ? ((void (*) (NMSetting *, gboolean )) (func)) : NULL)
|
||||
|
||||
#define OBJLIST_GET_NUM_FCN(type, func) (((func) == ((guint (*) (type * )) (func))) ? ((guint (*) (NMSetting * )) (func)) : NULL)
|
||||
#define OBJLIST_CLEAR_ALL_FCN(type, func) (((func) == ((void (*) (type * )) (func))) ? ((void (*) (NMSetting * )) (func)) : NULL)
|
||||
|
|
@ -5595,6 +5567,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
|
|||
.add_fcn = _multilist_add_fcn_ip_config_dns_options,
|
||||
.remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
|
||||
.remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
|
||||
.clear_emptyunset_fcn = MULTILIST_CLEAR_EMPTYUNSET_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_dns_options),
|
||||
.strsplit_plain = TRUE,
|
||||
),
|
||||
.is_default_fcn = _is_default_func_ip_config_dns_options,
|
||||
|
|
@ -5807,6 +5780,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
|
|||
.add_fcn = _multilist_add_fcn_ip_config_dns_options,
|
||||
.remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
|
||||
.remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
|
||||
.clear_emptyunset_fcn = MULTILIST_CLEAR_EMPTYUNSET_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_dns_options),
|
||||
.strsplit_plain = TRUE,
|
||||
),
|
||||
.is_default_fcn = _is_default_func_ip_config_dns_options,
|
||||
|
|
@ -6662,7 +6636,6 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
|
|||
.obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
|
||||
.set_fcn = _objlist_set_fcn_team_link_watchers,
|
||||
.remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_link_watcher),
|
||||
.strsplit_plain = TRUE,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -6739,7 +6712,6 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
|
|||
.obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
|
||||
.set_fcn = _objlist_set_fcn_team_link_watchers,
|
||||
.remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeamPort, nm_setting_team_port_remove_link_watcher),
|
||||
.strsplit_plain = TRUE,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -270,6 +270,13 @@ struct _NMMetaPropertyTypData {
|
|||
guint32 (*get_num_fcn_u32) (NMSetting *setting);
|
||||
guint (*get_num_fcn_u) (NMSetting *setting);
|
||||
void (*clear_all_fcn) (NMSetting *setting);
|
||||
|
||||
/* some multilist properties distinguish between an empty list and
|
||||
* and unset. If this function pointer is set, certain behaviors come
|
||||
* into action to handle that. */
|
||||
void (*clear_emptyunset_fcn) (NMSetting *setting,
|
||||
gboolean is_set /* or else set default */);
|
||||
|
||||
gboolean (*add_fcn) (NMSetting *setting,
|
||||
const char *item);
|
||||
void (*add2_fcn) (NMSetting *setting,
|
||||
|
|
|
|||
|
|
@ -1,23 +1,42 @@
|
|||
test_unit = 'test-general'
|
||||
|
||||
deps = [
|
||||
libnm_dep,
|
||||
libnmc_dep,
|
||||
libnmc_base_dep,
|
||||
libnm_core_dep,
|
||||
]
|
||||
|
||||
exe = executable(
|
||||
'clients-' + test_unit,
|
||||
test_unit + '.c',
|
||||
dependencies: deps,
|
||||
'clients-test-general',
|
||||
'test-general.c',
|
||||
dependencies: [
|
||||
libnm_dep,
|
||||
libnmc_dep,
|
||||
libnmc_base_dep,
|
||||
libnm_core_dep,
|
||||
],
|
||||
c_args: clients_cflags + [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
],
|
||||
)
|
||||
|
||||
test(
|
||||
'clients/' + test_unit,
|
||||
'clients/common/tests/test-general',
|
||||
test_script,
|
||||
args: test_args + [exe.full_path()],
|
||||
)
|
||||
|
||||
###############################################################################
|
||||
|
||||
exe = executable(
|
||||
'test-libnm-core-aux',
|
||||
[ 'test-libnm-core-aux.c', ],
|
||||
c_args: [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_CLIENT',
|
||||
],
|
||||
dependencies: [
|
||||
libnm_dep,
|
||||
shared_nm_libnm_core_aux_dep,
|
||||
shared_nm_libnm_core_intern_dep,
|
||||
],
|
||||
)
|
||||
|
||||
test(
|
||||
'clients/common/tests/test-libnm-core-aux',
|
||||
test_script,
|
||||
args: test_args + [exe.full_path()]
|
||||
)
|
||||
|
|
|
|||
250
clients/common/tests/test-libnm-core-aux.c
Normal file
250
clients/common/tests/test-libnm-core-aux.c
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-libnm-core-aux/nm-libnm-core-aux.h"
|
||||
#include "nm-libnm-core-intern/nm-libnm-core-utils.h"
|
||||
|
||||
#include "nm-utils/nm-test-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMTeamLinkWatcher *
|
||||
_team_link_watcher_from_string_impl (const char *str, gsize nextra, const char *const*vextra)
|
||||
{
|
||||
NMTeamLinkWatcher *watcher;
|
||||
gs_free char *str1_free = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gsize i;
|
||||
|
||||
g_assert (str);
|
||||
|
||||
watcher = nm_utils_team_link_watcher_from_string (str, &error);
|
||||
nmtst_assert_success (watcher, error);
|
||||
|
||||
for (i = 0; i < 1 + nextra; i++) {
|
||||
nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher1 = NULL;
|
||||
const char *str1;
|
||||
|
||||
if (i == 0) {
|
||||
str1_free = nm_utils_team_link_watcher_to_string (watcher);
|
||||
g_assert (str1_free);
|
||||
str1 = str1_free;
|
||||
g_assert_cmpstr (str, ==, str1);
|
||||
} else
|
||||
str1 = vextra[i - 1];
|
||||
|
||||
watcher1 = nm_utils_team_link_watcher_from_string (str1, &error);
|
||||
nmtst_assert_success (watcher1, error);
|
||||
if (!nm_team_link_watcher_equal (watcher, watcher1)) {
|
||||
gs_free char *ss1 = NULL;
|
||||
gs_free char *ss2 = NULL;
|
||||
|
||||
g_print (">>> watcher differs: \"%s\" vs. \"%s\"",
|
||||
(ss1 = nm_utils_team_link_watcher_to_string (watcher)),
|
||||
(ss2 = nm_utils_team_link_watcher_to_string (watcher1)));
|
||||
g_print (">>> ORIG: \"%s\" vs. \"%s\"", str, str1);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_assert (nm_team_link_watcher_equal (watcher1, watcher));
|
||||
}
|
||||
|
||||
return watcher;
|
||||
}
|
||||
#define _team_link_watcher_from_string(str, ...) \
|
||||
_team_link_watcher_from_string_impl ((str), NM_NARG (__VA_ARGS__), NM_MAKE_STRV (__VA_ARGS__))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_team_link_watcher_tofro_string (void)
|
||||
{
|
||||
nm_auto_unref_team_link_watcher NMTeamLinkWatcher *w = NULL;
|
||||
|
||||
#define _team_link_watcher_cmp(watcher, \
|
||||
name, \
|
||||
delay_down, \
|
||||
delay_up, \
|
||||
init_wait, \
|
||||
interval, \
|
||||
missed_max, \
|
||||
target_host, \
|
||||
source_host, \
|
||||
vlanid, \
|
||||
arping_flags) \
|
||||
G_STMT_START { \
|
||||
nm_auto_unref_team_link_watcher NMTeamLinkWatcher *_w = g_steal_pointer (watcher); \
|
||||
\
|
||||
g_assert_cmpstr ((name), ==, nm_team_link_watcher_get_name (_w)); \
|
||||
g_assert_cmpint ((delay_down), ==, nm_team_link_watcher_get_delay_down (_w)); \
|
||||
g_assert_cmpint ((delay_up), ==, nm_team_link_watcher_get_delay_up (_w)); \
|
||||
g_assert_cmpint ((init_wait), ==, nm_team_link_watcher_get_init_wait (_w)); \
|
||||
g_assert_cmpint ((interval), ==, nm_team_link_watcher_get_interval (_w)); \
|
||||
g_assert_cmpint ((missed_max), ==, nm_team_link_watcher_get_missed_max (_w)); \
|
||||
g_assert_cmpstr ((target_host), ==, nm_team_link_watcher_get_target_host (_w)); \
|
||||
g_assert_cmpstr ((source_host), ==, nm_team_link_watcher_get_source_host (_w)); \
|
||||
g_assert_cmpint ((vlanid), ==, nm_team_link_watcher_get_vlanid (_w)); \
|
||||
g_assert_cmpint ((arping_flags), ==, nm_team_link_watcher_get_flags (_w)); \
|
||||
} G_STMT_END
|
||||
|
||||
w = _team_link_watcher_from_string ("name=ethtool",
|
||||
"delay-up=0 name=ethtool",
|
||||
" delay-down=0 name=ethtool ");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"ethtool",
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=ethtool delay-up=10",
|
||||
" delay-down=0 delay-up=10 name=ethtool");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"ethtool",
|
||||
0,
|
||||
10,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=ethtool delay-up=10 delay-down=11",
|
||||
" delay-down=11 delay-up=10 name=ethtool");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"ethtool",
|
||||
11,
|
||||
10,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=nsna_ping target-host=xxx",
|
||||
"name=nsna_ping target-host=xxx",
|
||||
" missed-max=3 target-host=xxx name=nsna_ping ");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"nsna_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
"xxx",
|
||||
NULL,
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=arp_ping target-host=xxx source-host=yzd",
|
||||
" source-host=yzd target-host=xxx name=arp_ping ");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"arp_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
"xxx",
|
||||
"yzd",
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=arp_ping missed-max=0 target-host=xxx vlanid=0 source-host=yzd");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"arp_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"xxx",
|
||||
"yzd",
|
||||
0,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=arp_ping target-host=xxx source-host=yzd validate-active=true",
|
||||
"source-host=yzd send-always=false name=arp_ping validate-active=true validate-inactive=false target-host=xxx",
|
||||
" source-host=yzd target-host=xxx validate-active=true name=arp_ping ");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"arp_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
"xxx",
|
||||
"yzd",
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=arp_ping target-host=xxx source-host=yzd validate-active=true validate-inactive=true send-always=true",
|
||||
"source-host=yzd send-always=true name=arp_ping validate-active=true validate-inactive=true target-host=xxx",
|
||||
"source-host=yzd send-always=true name=arp_ping validate-active=1 validate-inactive=yes target-host=xxx",
|
||||
" source-host=yzd target-host=xxx validate-inactive=true send-always=true validate-active=true name=arp_ping ");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"arp_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
"xxx",
|
||||
"yzd",
|
||||
-1,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE
|
||||
| NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE
|
||||
| NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS);
|
||||
|
||||
w = _team_link_watcher_from_string ("name=arp_ping missed-max=0 target-host=xxx vlanid=0 source-host=yzd");
|
||||
_team_link_watcher_cmp (&w,
|
||||
"arp_ping",
|
||||
-1,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"xxx",
|
||||
"yzd",
|
||||
0,
|
||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
nmtst_init (&argc, &argv, TRUE);
|
||||
|
||||
g_test_add_func ("/libnm-core-aux/test_team_link_watcher_tofro_string", test_team_link_watcher_tofro_string);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -889,7 +889,7 @@ class TestNmcli(NmTestBase):
|
|||
|
||||
replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('con-gsm1')), 'UUID-con-gsm1-REPLACED-REPLACED-REPL'))
|
||||
|
||||
self.call_nmcli(['connection', 'add', 'type', 'gsm', 'autoconnect', 'no', 'con-name', 'con-gsm1', 'ifname', '*', 'apn', 'xyz.con-gsm1', 'serial.baud', '5', 'serial.send-delay', '100', 'serial.pari', '1'],
|
||||
self.call_nmcli(['connection', 'add', 'type', 'gsm', 'autoconnect', 'no', 'con-name', 'con-gsm1', 'ifname', '*', 'apn', 'xyz.con-gsm1', 'serial.baud', '5', 'serial.send-delay', '100', 'serial.pari', '1', 'ipv4.dns-options', ' '],
|
||||
replace_stdout = replace_stdout)
|
||||
|
||||
replace_stdout.append((Util.memoize_nullary(lambda: self.srv.findConnectionUuid('ethernet')), 'UUID-ethernet-REPLACED-REPLACED-REPL'))
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ libnm_core_dep = declare_dependency(
|
|||
|
||||
shared_nm_libnm_core_aux = static_library(
|
||||
'nm-libnm-core-aux',
|
||||
sources: files('../shared/nm-libnm-core-aux/nm-dispatcher-api.h'),
|
||||
sources: files('../shared/nm-libnm-core-aux/nm-libnm-core-aux.c'),
|
||||
c_args: [
|
||||
'-DG_LOG_DOMAIN="@0@"'.format(libnm_name),
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_WITH_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB)',
|
||||
|
|
@ -270,6 +270,7 @@ shared_nm_libnm_core_aux = static_library(
|
|||
glib_dep,
|
||||
shared_c_siphash_dep,
|
||||
shared_nm_glib_aux_dep,
|
||||
libnm_core_dep,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,8 @@ typedef gpointer (*NMUtilsCopyFunc) (gpointer);
|
|||
|
||||
const char **_nm_ip_address_get_attribute_names (const NMIPAddress *addr, gboolean sorted, guint *out_length);
|
||||
|
||||
void _nm_setting_wired_clear_s390_options (NMSettingWired *setting);
|
||||
|
||||
gboolean _nm_ip_route_attribute_validate_all (const NMIPRoute *route);
|
||||
const char **_nm_ip_route_get_attribute_names (const NMIPRoute *route, gboolean sorted, guint *out_length);
|
||||
GHashTable *_nm_ip_route_get_attributes (NMIPRoute *route);
|
||||
|
|
|
|||
|
|
@ -994,6 +994,11 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
|
|||
gboolean is_vpn;
|
||||
gsize n_keys;
|
||||
|
||||
nm_assert ( (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_DATA))
|
||||
|| (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_SECRETS))
|
||||
|| (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
|
||||
|| (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
|
||||
|
||||
keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, &n_keys, NULL);
|
||||
if (n_keys == 0)
|
||||
return;
|
||||
|
|
@ -1041,7 +1046,10 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
|
|||
value);
|
||||
}
|
||||
g_object_set (setting, NM_SETTING_USER_DATA, data, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gsize
|
||||
|
|
@ -2019,6 +2027,64 @@ bridge_vlan_writer (KeyfileWriterInfo *info,
|
|||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
|
||||
#define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options"
|
||||
|
||||
static void
|
||||
wired_s390_options_parser_full (KeyfileReaderInfo *info,
|
||||
const NMMetaSettingInfo *setting_info,
|
||||
const NMSettInfoProperty *property_info,
|
||||
const ParseInfoProperty *pip,
|
||||
NMSetting *setting)
|
||||
{
|
||||
NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
|
||||
gs_strfreev char **keys = NULL;
|
||||
gsize n_keys;
|
||||
gsize i;
|
||||
|
||||
keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, ETHERNET_S390_OPTIONS_GROUP_NAME, &n_keys, NULL);
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
gs_free char *value = NULL;
|
||||
gs_free char *key_to_free = NULL;
|
||||
|
||||
value = nm_keyfile_plugin_kf_get_string (info->keyfile,
|
||||
ETHERNET_S390_OPTIONS_GROUP_NAME,
|
||||
keys[i],
|
||||
NULL);
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
nm_setting_wired_add_s390_option (s_wired,
|
||||
nm_keyfile_key_decode (keys[i],
|
||||
&key_to_free),
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wired_s390_options_writer_full (KeyfileWriterInfo *info,
|
||||
const NMMetaSettingInfo *setting_info,
|
||||
const NMSettInfoProperty *property_info,
|
||||
const ParseInfoProperty *pip,
|
||||
NMSetting *setting)
|
||||
{
|
||||
NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
|
||||
guint i, n;
|
||||
|
||||
n = nm_setting_wired_get_num_s390_options (s_wired);
|
||||
for (i = 0; i < n; i++) {
|
||||
const char *opt_key;
|
||||
const char *opt_val;
|
||||
gs_free char *key_to_free = NULL;
|
||||
|
||||
nm_setting_wired_get_s390_option (s_wired, i, &opt_key, &opt_val);
|
||||
nm_keyfile_plugin_kf_set_string (info->keyfile,
|
||||
ETHERNET_S390_OPTIONS_GROUP_NAME,
|
||||
nm_keyfile_key_encode (opt_key, &key_to_free),
|
||||
opt_val);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ip_routing_rule_writer_full (KeyfileWriterInfo *info,
|
||||
const NMMetaSettingInfo *setting_info,
|
||||
|
|
@ -2131,6 +2197,11 @@ write_hash_of_string (GKeyFile *file,
|
|||
gs_free const char **keys = NULL;
|
||||
guint i, l;
|
||||
|
||||
nm_assert ( (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_DATA))
|
||||
|| (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_SECRETS))
|
||||
|| (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
|
||||
|| (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
|
||||
|
||||
/* Write VPN secrets out to a different group to keep them separate */
|
||||
if ( NM_IS_SETTING_VPN (setting)
|
||||
&& nm_streq (key, NM_SETTING_VPN_SECRETS)) {
|
||||
|
|
@ -2478,6 +2549,13 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
|
|||
PARSE_INFO_PROPERTY (NM_SETTING_WIRED_MAC_ADDRESS,
|
||||
.parser = mac_address_parser_ETHER,
|
||||
),
|
||||
PARSE_INFO_PROPERTY (NM_SETTING_WIRED_S390_OPTIONS,
|
||||
.parser_no_check_key = TRUE,
|
||||
.parser_full = wired_s390_options_parser_full,
|
||||
.writer_full = wired_s390_options_writer_full,
|
||||
.has_parser_full = TRUE,
|
||||
.has_writer_full = TRUE,
|
||||
),
|
||||
),
|
||||
),
|
||||
PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BLUETOOTH,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,11 @@ typedef struct {
|
|||
guint32 mtu;
|
||||
char **s390_subchannels;
|
||||
char *s390_nettype;
|
||||
GHashTable *s390_options;
|
||||
struct {
|
||||
NMUtilsNamedValue *arr;
|
||||
guint len;
|
||||
guint n_alloc;
|
||||
} s390_options;
|
||||
NMSettingWiredWakeOnLan wol;
|
||||
char *wol_password;
|
||||
} NMSettingWiredPrivate;
|
||||
|
|
@ -87,15 +91,68 @@ G_DEFINE_TYPE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING)
|
|||
/*****************************************************************************/
|
||||
|
||||
static const char *valid_s390_opts[] = {
|
||||
"portno", "layer2", "portname", "protocol", "priority_queueing",
|
||||
"buffer_count", "isolation", "total", "inter", "inter_jumbo", "route4",
|
||||
"route6", "fake_broadcast", "broadcast_mode", "canonical_macaddr",
|
||||
"checksumming", "sniffer", "large_send", "ipato_enable", "ipato_invert4",
|
||||
"ipato_add4", "ipato_invert6", "ipato_add6", "vipa_add4", "vipa_add6",
|
||||
"rxip_add4", "rxip_add6", "lancmd_timeout", "ctcprot",
|
||||
NULL
|
||||
"broadcast_mode",
|
||||
"buffer_count",
|
||||
"canonical_macaddr",
|
||||
"checksumming",
|
||||
"ctcprot",
|
||||
"fake_broadcast",
|
||||
"inter",
|
||||
"inter_jumbo",
|
||||
"ipato_add4",
|
||||
"ipato_add6",
|
||||
"ipato_enable",
|
||||
"ipato_invert4",
|
||||
"ipato_invert6",
|
||||
"isolation",
|
||||
"lancmd_timeout",
|
||||
"large_send",
|
||||
"layer2",
|
||||
"portname",
|
||||
"portno",
|
||||
"priority_queueing",
|
||||
"protocol",
|
||||
"route4",
|
||||
"route6",
|
||||
"rxip_add4",
|
||||
"rxip_add6",
|
||||
"sniffer",
|
||||
"total",
|
||||
"vipa_add4",
|
||||
"vipa_add6",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
valid_s390_opts_check (const char *option)
|
||||
{
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
nm_assert (NM_PTRARRAY_LEN (valid_s390_opts) + 1 == G_N_ELEMENTS (valid_s390_opts));
|
||||
{
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (valid_s390_opts); i++) {
|
||||
if (i == G_N_ELEMENTS (valid_s390_opts) - 1)
|
||||
nm_assert (!valid_s390_opts[i]);
|
||||
else {
|
||||
nm_assert (valid_s390_opts[i]);
|
||||
nm_assert (valid_s390_opts[i][0] != '\0');
|
||||
if (i > 0)
|
||||
g_assert (strcmp (valid_s390_opts[i - 1], valid_s390_opts[i]) < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return option
|
||||
&& (nm_utils_array_find_binary_search (valid_s390_opts,
|
||||
sizeof (const char *),
|
||||
G_N_ELEMENTS (valid_s390_opts) - 1,
|
||||
&option,
|
||||
nm_strcmp_p_with_data,
|
||||
NULL) >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_wired_get_port:
|
||||
* @setting: the #NMSettingWired
|
||||
|
|
@ -417,7 +474,7 @@ nm_setting_wired_get_num_s390_options (NMSettingWired *setting)
|
|||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0);
|
||||
|
||||
return g_hash_table_size (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options);
|
||||
return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options.len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -447,24 +504,17 @@ nm_setting_wired_get_s390_option (NMSettingWired *setting,
|
|||
const char **out_key,
|
||||
const char **out_value)
|
||||
{
|
||||
const char *_key, *_value;
|
||||
GHashTableIter iter;
|
||||
guint i = 0;
|
||||
NMSettingWiredPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
|
||||
g_hash_table_iter_init (&iter, NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &_key, (gpointer) &_value)) {
|
||||
if (i == idx) {
|
||||
if (out_key)
|
||||
*out_key = _key;
|
||||
if (out_value)
|
||||
*out_value = _value;
|
||||
return TRUE;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
g_return_val_if_reached (FALSE);
|
||||
priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
|
||||
g_return_val_if_fail (idx < priv->s390_options.len, FALSE);
|
||||
|
||||
NM_SET_OUT (out_key, priv->s390_options.arr[idx].name);
|
||||
NM_SET_OUT (out_value, priv->s390_options.arr[idx].value_str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -482,10 +532,21 @@ const char *
|
|||
nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting,
|
||||
const char *key)
|
||||
{
|
||||
NMSettingWiredPrivate *priv;
|
||||
gssize idx;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
|
||||
g_return_val_if_fail (key && key[0], NULL);
|
||||
|
||||
return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
|
||||
priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
|
||||
idx = nm_utils_named_value_list_find (priv->s390_options.arr,
|
||||
priv->s390_options.len,
|
||||
key,
|
||||
TRUE);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
return priv->s390_options.arr[idx].value_str;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -507,14 +568,51 @@ nm_setting_wired_add_s390_option (NMSettingWired *setting,
|
|||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
g_return_val_if_fail (key && key[0], FALSE);
|
||||
g_return_val_if_fail (g_strv_contains (valid_s390_opts, key), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
NMSettingWiredPrivate *priv;
|
||||
gssize idx;
|
||||
NMUtilsNamedValue *v;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
if (!valid_s390_opts_check (key)) {
|
||||
g_return_val_if_fail (key, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
|
||||
idx = nm_utils_named_value_list_find (priv->s390_options.arr,
|
||||
priv->s390_options.len,
|
||||
key,
|
||||
TRUE);
|
||||
if (idx < 0) {
|
||||
gsize dst_idx = ~idx;
|
||||
|
||||
if (priv->s390_options.n_alloc < priv->s390_options.len + 1) {
|
||||
priv->s390_options.n_alloc = NM_MAX (4,
|
||||
(priv->s390_options.len + 1) * 2);
|
||||
priv->s390_options.arr = g_realloc (priv->s390_options.arr,
|
||||
priv->s390_options.n_alloc * sizeof (NMUtilsNamedValue));
|
||||
}
|
||||
if (dst_idx < priv->s390_options.len) {
|
||||
memmove (&priv->s390_options.arr[dst_idx + 1],
|
||||
&priv->s390_options.arr[dst_idx],
|
||||
(priv->s390_options.len - dst_idx) * sizeof (NMUtilsNamedValue));
|
||||
}
|
||||
priv->s390_options.arr[dst_idx] = (NMUtilsNamedValue) {
|
||||
.name = g_strdup (key),
|
||||
.value_str = g_strdup (value),
|
||||
};
|
||||
priv->s390_options.len++;
|
||||
} else {
|
||||
v = &priv->s390_options.arr[idx];
|
||||
if (nm_streq (value, v->value_str))
|
||||
return TRUE;
|
||||
g_free ((char *) v->value_str);
|
||||
v->value_str = g_strdup (value);
|
||||
}
|
||||
|
||||
g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options,
|
||||
g_strdup (key),
|
||||
g_strdup (value));
|
||||
_notify (setting, PROP_S390_OPTIONS);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -534,20 +632,64 @@ gboolean
|
|||
nm_setting_wired_remove_s390_option (NMSettingWired *setting,
|
||||
const char *key)
|
||||
{
|
||||
gboolean found;
|
||||
NMSettingWiredPrivate *priv;
|
||||
gsize dst_idx;
|
||||
gssize idx;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
|
||||
g_return_val_if_fail (key && key[0], FALSE);
|
||||
g_return_val_if_fail (key, FALSE);
|
||||
|
||||
found = g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
|
||||
if (found)
|
||||
_notify (setting, PROP_S390_OPTIONS);
|
||||
return found;
|
||||
priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
|
||||
idx = nm_utils_named_value_list_find (priv->s390_options.arr,
|
||||
priv->s390_options.len,
|
||||
key,
|
||||
TRUE);
|
||||
if (idx < 0)
|
||||
return FALSE;
|
||||
|
||||
dst_idx = idx;
|
||||
|
||||
g_free ((char *) priv->s390_options.arr[dst_idx].name);
|
||||
g_free ((char *) priv->s390_options.arr[dst_idx].value_str);
|
||||
if (dst_idx + 1 != priv->s390_options.len) {
|
||||
memmove (&priv->s390_options.arr[dst_idx],
|
||||
&priv->s390_options.arr[dst_idx + 1],
|
||||
(priv->s390_options.len - dst_idx - 1) * sizeof (NMUtilsNamedValue));
|
||||
}
|
||||
|
||||
priv->s390_options.len--;
|
||||
|
||||
_notify (setting, PROP_S390_OPTIONS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_s390_options_clear (NMSettingWiredPrivate *priv)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->s390_options.len; i++) {
|
||||
g_free ((char *) priv->s390_options.arr[i].name);
|
||||
g_free ((char *) priv->s390_options.arr[i].value_str);
|
||||
}
|
||||
nm_clear_g_free (&priv->s390_options.arr);
|
||||
priv->s390_options.len = 0;
|
||||
priv->s390_options.n_alloc = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_nm_setting_wired_clear_s390_options (NMSettingWired *setting)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_WIRED (setting));
|
||||
|
||||
_s390_options_clear (NM_SETTING_WIRED_GET_PRIVATE (setting));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_wired_get_valid_s390_options:
|
||||
* @setting: (allow-none): the #NMSettingWired
|
||||
* @setting: (allow-none): the #NMSettingWired. This argument is unused
|
||||
* and you may pass %NULL.
|
||||
*
|
||||
* Returns a list of valid s390 options.
|
||||
*
|
||||
|
|
@ -602,10 +744,8 @@ static gboolean
|
|||
verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
GHashTableIter iter;
|
||||
const char *key, *value;
|
||||
int i;
|
||||
GError *local = NULL;
|
||||
guint i;
|
||||
|
||||
if (!NM_IN_STRSET (priv->port, NULL, "tp", "aui", "bnc", "mii")) {
|
||||
g_set_error (error,
|
||||
|
|
@ -672,16 +812,19 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->s390_options);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
|
||||
if ( !g_strv_contains (valid_s390_opts, key)
|
||||
|| value[0] == '\0'
|
||||
|| (strlen (value) > 200)) {
|
||||
for (i = 0; i < priv->s390_options.len; i++) {
|
||||
const NMUtilsNamedValue *v = &priv->s390_options.arr[i];
|
||||
|
||||
nm_assert (v->name);
|
||||
|
||||
if ( !valid_s390_opts_check (v->name)
|
||||
|| v->value_str[0] == '\0'
|
||||
|| strlen (v->value_str) > 200) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("invalid '%s' or its value '%s'"),
|
||||
key, value);
|
||||
v->name, v->value_str);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -802,6 +945,8 @@ get_property (GObject *object, guint prop_id,
|
|||
{
|
||||
NMSettingWired *setting = NM_SETTING_WIRED (object);
|
||||
NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
GHashTable *hash;
|
||||
guint i;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PORT:
|
||||
|
|
@ -838,7 +983,16 @@ get_property (GObject *object, guint prop_id,
|
|||
g_value_set_string (value, nm_setting_wired_get_s390_nettype (setting));
|
||||
break;
|
||||
case PROP_S390_OPTIONS:
|
||||
g_value_take_boxed (value, _nm_utils_copy_strdict (priv->s390_options));
|
||||
hash = g_hash_table_new_full (nm_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
g_free);
|
||||
for (i = 0; i < priv->s390_options.len; i++) {
|
||||
g_hash_table_insert (hash,
|
||||
g_strdup (priv->s390_options.arr[i].name),
|
||||
g_strdup (priv->s390_options.arr[i].value_str));
|
||||
}
|
||||
g_value_take_boxed (value, hash);
|
||||
break;
|
||||
case PROP_WAKE_ON_LAN:
|
||||
g_value_set_uint (value, priv->wol);
|
||||
|
|
@ -859,7 +1013,6 @@ set_property (GObject *object, guint prop_id,
|
|||
NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (object);
|
||||
const char * const *blacklist;
|
||||
const char *mac;
|
||||
int i;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PORT:
|
||||
|
|
@ -894,6 +1047,8 @@ set_property (GObject *object, guint prop_id,
|
|||
blacklist = g_value_get_boxed (value);
|
||||
g_array_set_size (priv->mac_address_blacklist, 0);
|
||||
if (blacklist && *blacklist) {
|
||||
guint i;
|
||||
|
||||
for (i = 0; blacklist[i]; i++) {
|
||||
mac = _nm_utils_hwaddr_canonical_or_invalid (blacklist[i], ETH_ALEN);
|
||||
g_array_append_val (priv->mac_address_blacklist, mac);
|
||||
|
|
@ -913,8 +1068,63 @@ set_property (GObject *object, guint prop_id,
|
|||
priv->s390_nettype = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_S390_OPTIONS:
|
||||
g_hash_table_unref (priv->s390_options);
|
||||
priv->s390_options = _nm_utils_copy_strdict (g_value_get_boxed (value));
|
||||
{
|
||||
GHashTable *hash;
|
||||
|
||||
_s390_options_clear (priv);
|
||||
|
||||
hash = g_value_get_boxed (value);
|
||||
|
||||
priv->s390_options.n_alloc = hash ? g_hash_table_size (hash) : 0u;
|
||||
|
||||
if (priv->s390_options.n_alloc > 0) {
|
||||
gboolean invalid_content = FALSE;
|
||||
GHashTableIter iter;
|
||||
const char *key;
|
||||
const char *val;
|
||||
guint i, j;
|
||||
|
||||
priv->s390_options.arr = g_new (NMUtilsNamedValue, priv->s390_options.n_alloc);
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) {
|
||||
if (!key || !val) {
|
||||
invalid_content = TRUE;
|
||||
continue;
|
||||
}
|
||||
nm_assert (priv->s390_options.len < priv->s390_options.n_alloc);
|
||||
priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue) {
|
||||
.name = g_strdup (key),
|
||||
.value_str = g_strdup (val),
|
||||
};
|
||||
priv->s390_options.len++;
|
||||
}
|
||||
if (priv->s390_options.len > 1) {
|
||||
nm_utils_named_value_list_sort (priv->s390_options.arr,
|
||||
priv->s390_options.len,
|
||||
NULL,
|
||||
NULL);
|
||||
/* prune duplicate keys. This is only possible if @hash does not use
|
||||
* g_str_equal() as compare function (which would be a bug).
|
||||
* Still, handle this, because we use later binary sort and rely
|
||||
* on unique names. One bug here, should not bork the remainder
|
||||
* of the program. */
|
||||
j = 1;
|
||||
for (i = 1; i < priv->s390_options.len; i++) {
|
||||
if (nm_streq (priv->s390_options.arr[j - 1].name,
|
||||
priv->s390_options.arr[i].name)) {
|
||||
g_free ((char *) priv->s390_options.arr[i].name);
|
||||
g_free ((char *) priv->s390_options.arr[i].value_str);
|
||||
invalid_content = TRUE;
|
||||
continue;
|
||||
}
|
||||
priv->s390_options.arr[j++] = priv->s390_options.arr[i];
|
||||
}
|
||||
priv->s390_options.len = j;
|
||||
}
|
||||
|
||||
g_return_if_fail (!invalid_content);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_WAKE_ON_LAN:
|
||||
priv->wol = g_value_get_uint (value);
|
||||
|
|
@ -936,8 +1146,6 @@ nm_setting_wired_init (NMSettingWired *setting)
|
|||
{
|
||||
NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
|
||||
|
||||
priv->s390_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
/* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */
|
||||
priv->mac_address_blacklist = g_array_new (TRUE, FALSE, sizeof (char *));
|
||||
g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item);
|
||||
|
|
@ -965,7 +1173,7 @@ finalize (GObject *object)
|
|||
g_free (priv->duplex);
|
||||
g_free (priv->s390_nettype);
|
||||
|
||||
g_hash_table_destroy (priv->s390_options);
|
||||
_s390_options_clear (priv);
|
||||
|
||||
g_free (priv->device_mac_address);
|
||||
g_free (priv->cloned_mac_address);
|
||||
|
|
|
|||
|
|
@ -851,8 +851,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);
|
||||
|
|
|
|||
|
|
@ -2108,6 +2108,105 @@ test_tc_config_dbus (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_rndt_wired_add_s390_options (NMSettingWired *s_wired,
|
||||
char **out_keyfile_entries)
|
||||
{
|
||||
gsize n_opts;
|
||||
gsize i, j;
|
||||
const char *const*option_names;
|
||||
gs_free const char **opt_keys = NULL;
|
||||
gs_strfreev char **opt_vals = NULL;
|
||||
gs_free bool *opt_found = NULL;
|
||||
GString *keyfile_entries;
|
||||
nm_auto_free_gstring GString *str_tmp = NULL;
|
||||
|
||||
option_names = nm_setting_wired_get_valid_s390_options (nmtst_get_rand_bool () ? NULL : s_wired);
|
||||
|
||||
n_opts = NM_PTRARRAY_LEN (option_names);
|
||||
opt_keys = g_new (const char *, (n_opts + 1));
|
||||
nmtst_rand_perm (NULL, opt_keys, option_names, sizeof (const char *), n_opts);
|
||||
n_opts = nmtst_get_rand_int () % (n_opts + 1);
|
||||
opt_keys[n_opts] = NULL;
|
||||
|
||||
opt_vals = g_new0 (char *, n_opts + 1);
|
||||
opt_found = g_new0 (bool, n_opts + 1);
|
||||
for (i = 0; i < n_opts; i++) {
|
||||
guint p = nmtst_get_rand_int () % 1000;
|
||||
|
||||
if (p < 200)
|
||||
opt_vals[i] = nm_strdup_int (i);
|
||||
else {
|
||||
opt_vals[i] = g_strdup_printf ("%s%s%s%s-%zu",
|
||||
((p % 5) % 2) ? "\n" : "",
|
||||
((p % 7) % 2) ? "\t" : "",
|
||||
((p % 11) % 2) ? "x" : "",
|
||||
((p % 13) % 2) ? "=" : "",
|
||||
i);
|
||||
}
|
||||
}
|
||||
|
||||
if (nmtst_get_rand_bool ()) {
|
||||
gs_unref_hashtable GHashTable *hash = NULL;
|
||||
|
||||
hash = g_hash_table_new (nm_str_hash, g_str_equal);
|
||||
for (i = 0; i < n_opts; i++)
|
||||
g_hash_table_insert (hash, (char *) opt_keys[i], opt_vals[i]);
|
||||
g_object_set (s_wired,
|
||||
NM_SETTING_WIRED_S390_OPTIONS,
|
||||
hash,
|
||||
NULL);
|
||||
} else {
|
||||
_nm_setting_wired_clear_s390_options (s_wired);
|
||||
for (i = 0; i < n_opts; i++) {
|
||||
if (!nm_setting_wired_add_s390_option (s_wired, opt_keys[i], opt_vals[i]))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_cmpint (nm_setting_wired_get_num_s390_options (s_wired), ==, n_opts);
|
||||
|
||||
keyfile_entries = g_string_new (NULL);
|
||||
str_tmp = g_string_new (NULL);
|
||||
if (n_opts > 0)
|
||||
g_string_append_printf (keyfile_entries, "[ethernet-s390-options]\n");
|
||||
for (i = 0; i < n_opts; i++) {
|
||||
gssize idx;
|
||||
const char *k, *v;
|
||||
|
||||
nm_setting_wired_get_s390_option (s_wired, i, &k, &v);
|
||||
g_assert (k);
|
||||
g_assert (v);
|
||||
|
||||
idx = nm_utils_strv_find_first ((char **) opt_keys, n_opts, k);
|
||||
g_assert (idx >= 0);
|
||||
g_assert (!opt_found[idx]);
|
||||
opt_found[idx] = TRUE;
|
||||
g_assert_cmpstr (opt_keys[idx], ==, k);
|
||||
g_assert_cmpstr (opt_vals[idx], ==, v);
|
||||
|
||||
g_string_truncate (str_tmp, 0);
|
||||
for (j = 0; v[j] != '\0'; j++) {
|
||||
if (v[j] == '\n')
|
||||
g_string_append (str_tmp, "\\n");
|
||||
else if (v[j] == '\t')
|
||||
g_string_append (str_tmp, "\\t");
|
||||
else
|
||||
g_string_append_c (str_tmp, v[j]);
|
||||
}
|
||||
|
||||
g_string_append_printf (keyfile_entries,
|
||||
"%s=%s\n",
|
||||
k,
|
||||
str_tmp->str);
|
||||
}
|
||||
for (i = 0; i < n_opts; i++)
|
||||
g_assert (opt_found[i]);
|
||||
if (n_opts > 0)
|
||||
g_string_append_printf (keyfile_entries, "\n");
|
||||
*out_keyfile_entries = g_string_free (keyfile_entries, FALSE);
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
_rndt_wg_peers_create (void)
|
||||
{
|
||||
|
|
@ -2385,6 +2484,7 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
int is_ipv4;
|
||||
guint i;
|
||||
gboolean success;
|
||||
gs_free char *s390_keyfile_entries = NULL;
|
||||
|
||||
switch (MODE) {
|
||||
case 0:
|
||||
|
|
@ -2403,6 +2503,8 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
ETH_MTU,
|
||||
NULL);
|
||||
|
||||
_rndt_wired_add_s390_options (s_eth, &s390_keyfile_entries);
|
||||
|
||||
g_ptr_array_add (kf_data_arr,
|
||||
g_strdup_printf ("[connection]\n"
|
||||
"id=%s\n"
|
||||
|
|
@ -2415,6 +2517,7 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
"mac-address-blacklist=\n"
|
||||
"%s" /* mtu */
|
||||
"\n"
|
||||
"%s" /* [ethernet-s390-options] */
|
||||
"[ipv4]\n"
|
||||
"dns-search=\n"
|
||||
"method=auto\n"
|
||||
|
|
@ -2429,7 +2532,8 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
INTERFACE_NAME,
|
||||
(ETH_MTU != 0)
|
||||
? nm_sprintf_bufa (100, "mtu=%u\n", ETH_MTU)
|
||||
: ""));
|
||||
: "",
|
||||
s390_keyfile_entries));
|
||||
|
||||
g_ptr_array_add (kf_data_arr,
|
||||
g_strdup_printf ("[connection]\n"
|
||||
|
|
@ -2443,6 +2547,7 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
"mac-address-blacklist=\n"
|
||||
"%s" /* mtu */
|
||||
"\n"
|
||||
"%s" /* [ethernet-s390-options] */
|
||||
"[ipv4]\n"
|
||||
"dns-search=\n"
|
||||
"method=auto\n"
|
||||
|
|
@ -2457,7 +2562,8 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
INTERFACE_NAME,
|
||||
(ETH_MTU != 0)
|
||||
? nm_sprintf_bufa (100, "mtu=%d\n", (int) ETH_MTU)
|
||||
: ""));
|
||||
: "",
|
||||
s390_keyfile_entries));
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -2703,6 +2809,9 @@ test_roundtrip_conversion (gconstpointer test_data)
|
|||
|
||||
g_assert_cmpint (nm_setting_wired_get_mtu (s_eth), ==, ETH_MTU);
|
||||
g_assert_cmpint (nm_setting_wired_get_mtu (s_eth2), ==, ETH_MTU);
|
||||
|
||||
g_assert_cmpint (nm_setting_wired_get_num_s390_options (s_eth2), ==, nm_setting_wired_get_num_s390_options (s_eth));
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ libnm/nm-vpn-plugin-old.c
|
|||
libnm/nm-vpn-service-plugin.c
|
||||
data/org.freedesktop.NetworkManager.policy.in.in
|
||||
shared/nm-glib-aux/nm-shared-utils.c
|
||||
shared/nm-libnm-core-aux/nm-libnm-core-aux.c
|
||||
src/NetworkManagerUtils.c
|
||||
src/main.c
|
||||
src/main-utils.c
|
||||
|
|
|
|||
|
|
@ -287,18 +287,21 @@ libnm_systemd_shared_no_logging_dep = declare_dependency(
|
|||
|
||||
###############################################################################
|
||||
|
||||
test_shared_general = executable(
|
||||
'nm-utils/tests/test-shared-general',
|
||||
[ 'nm-utils/tests/test-shared-general.c', ],
|
||||
c_args: [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)',
|
||||
exe = executable(
|
||||
'nm-utils/tests/test-shared-general',
|
||||
[ 'nm-utils/tests/test-shared-general.c' ],
|
||||
c_args: [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)',
|
||||
],
|
||||
dependencies: [
|
||||
shared_nm_glib_aux_dep,
|
||||
shared_c_siphash_dep,
|
||||
],
|
||||
dependencies: shared_nm_glib_aux_dep,
|
||||
link_with: shared_c_siphash,
|
||||
)
|
||||
|
||||
test(
|
||||
'shared/nm-utils/test-shared-general',
|
||||
test_script,
|
||||
args: test_args + [test_shared_general.full_path()]
|
||||
'shared/nm-utils/tests/test-shared-general',
|
||||
test_script,
|
||||
args: test_args + [exe.full_path()]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2130,6 +2130,8 @@ nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMUtilsNamedValue *
|
||||
nm_utils_named_values_from_str_dict (GHashTable *hash, guint *out_len)
|
||||
{
|
||||
|
|
@ -2154,15 +2156,106 @@ nm_utils_named_values_from_str_dict (GHashTable *hash, guint *out_len)
|
|||
values[i].name = NULL;
|
||||
values[i].value_ptr = NULL;
|
||||
|
||||
if (len > 1) {
|
||||
g_qsort_with_data (values, len, sizeof (values[0]),
|
||||
nm_utils_named_entry_cmp_with_data, NULL);
|
||||
}
|
||||
nm_utils_named_value_list_sort (values, len, NULL, NULL);
|
||||
|
||||
NM_SET_OUT (out_len, len);
|
||||
return values;
|
||||
}
|
||||
|
||||
gssize
|
||||
nm_utils_named_value_list_find (const NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
const char *name,
|
||||
gboolean sorted)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
nm_assert (name);
|
||||
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
{
|
||||
for (i = 0; i < len; i++) {
|
||||
const NMUtilsNamedValue *v = &arr[i];
|
||||
|
||||
nm_assert (v->name);
|
||||
if ( sorted
|
||||
&& i > 0)
|
||||
nm_assert (strcmp (arr[i - 1].name, v->name) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
nm_assert ( !sorted
|
||||
|| nm_utils_named_value_list_is_sorted (arr, len, FALSE, NULL, NULL));
|
||||
#endif
|
||||
|
||||
if (sorted) {
|
||||
return nm_utils_array_find_binary_search (arr,
|
||||
sizeof (NMUtilsNamedValue),
|
||||
len,
|
||||
&name,
|
||||
nm_strcmp_p_with_data,
|
||||
NULL);
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (nm_streq (arr[i].name, name))
|
||||
return i;
|
||||
}
|
||||
return ~((gssize) len);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_utils_named_value_list_is_sorted (const NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
gboolean accept_duplicates,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
gsize i;
|
||||
int c_limit;
|
||||
|
||||
if (len == 0)
|
||||
return TRUE;
|
||||
|
||||
g_return_val_if_fail (arr, FALSE);
|
||||
|
||||
if (!compare_func)
|
||||
compare_func = nm_strcmp_p_with_data;
|
||||
|
||||
c_limit = accept_duplicates ? 0 : -1;
|
||||
|
||||
for (i = 1; i < len; i++) {
|
||||
int c;
|
||||
|
||||
c = compare_func (&arr[i - 1], &arr[i], user_data);
|
||||
if (c > c_limit)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_named_value_list_sort (NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
g_return_if_fail (arr);
|
||||
|
||||
if (len == 1)
|
||||
return;
|
||||
|
||||
g_qsort_with_data (arr,
|
||||
len,
|
||||
sizeof (NMUtilsNamedValue),
|
||||
compare_func ?: nm_strcmp_p_with_data,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gpointer *
|
||||
nm_utils_hash_keys_to_array (GHashTable *hash,
|
||||
GCompareDataFunc compare_func,
|
||||
|
|
|
|||
|
|
@ -906,11 +906,26 @@ typedef struct {
|
|||
};
|
||||
} NMUtilsNamedValue;
|
||||
|
||||
#define nm_utils_named_entry_cmp nm_strcmp_p
|
||||
#define nm_utils_named_entry_cmp_with_data nm_strcmp_p_with_data
|
||||
|
||||
NMUtilsNamedValue *nm_utils_named_values_from_str_dict (GHashTable *hash, guint *out_len);
|
||||
|
||||
gssize nm_utils_named_value_list_find (const NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
const char *name,
|
||||
gboolean sorted);
|
||||
|
||||
gboolean nm_utils_named_value_list_is_sorted (const NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
gboolean accept_duplicates,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_utils_named_value_list_sort (NMUtilsNamedValue *arr,
|
||||
gsize len,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gpointer *nm_utils_hash_keys_to_array (GHashTable *hash,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data,
|
||||
|
|
|
|||
372
shared/nm-libnm-core-aux/nm-libnm-core-aux.c
Normal file
372
shared/nm-libnm-core-aux/nm-libnm-core-aux.c
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-libnm-core-aux.h"
|
||||
|
||||
#include "nm-libnm-core-intern/nm-libnm-core-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
KEY_TYPE_STRING,
|
||||
KEY_TYPE_INT,
|
||||
KEY_TYPE_BOOL,
|
||||
} KeyType;
|
||||
|
||||
typedef struct {
|
||||
const char *str_val;
|
||||
union {
|
||||
int vint;
|
||||
bool vbool;
|
||||
} typ_val;
|
||||
} ParseData;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
NMTeamLinkWatcherType watcher_type;
|
||||
KeyType key_type;
|
||||
union {
|
||||
int (*fint) (NMTeamLinkWatcher *watcher);
|
||||
gboolean (*fbool) (NMTeamLinkWatcher *watcher);
|
||||
const char *(*fstring) (NMTeamLinkWatcher *watcher);
|
||||
} get_fcn;
|
||||
union {
|
||||
int vint;
|
||||
bool vbool;
|
||||
} def_val;
|
||||
} TeamLinkWatcherKeyInfo;
|
||||
|
||||
static gboolean
|
||||
_team_link_watcher_validate_active (NMTeamLinkWatcher *watcher)
|
||||
{
|
||||
return NM_FLAGS_HAS (nm_team_link_watcher_get_flags (watcher), NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_team_link_watcher_validate_inactive (NMTeamLinkWatcher *watcher)
|
||||
{
|
||||
return NM_FLAGS_HAS (nm_team_link_watcher_get_flags (watcher), NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_team_link_watcher_send_always (NMTeamLinkWatcher *watcher)
|
||||
{
|
||||
return NM_FLAGS_HAS (nm_team_link_watcher_get_flags (watcher), NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS);
|
||||
}
|
||||
|
||||
static const TeamLinkWatcherKeyInfo _team_link_watcher_key_infos[_NM_TEAM_LINK_WATCHER_KEY_NUM] = {
|
||||
|
||||
#define _KEY_INFO(key_id, _name, _watcher_type, _key_type, ...) \
|
||||
[key_id] = { .name = ""_name"", .watcher_type = (_watcher_type), .key_type = _key_type, ##__VA_ARGS__ }
|
||||
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_NAME, "name", NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL | NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_STRING, .get_fcn.fstring = nm_team_link_watcher_get_name, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_DELAY_UP, "delay-up", NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_delay_up, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN, "delay-down", NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_delay_down, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT, "init-wait", NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_init_wait, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_INTERVAL, "interval", NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_interval, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX, "missed-max", NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_missed_max, .def_val.vint = 3, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST, "target-host", NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_STRING, .get_fcn.fstring = nm_team_link_watcher_get_target_host, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_VLANID, "vlanid", NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_INT, .get_fcn.fint = nm_team_link_watcher_get_vlanid, .def_val.vint = -1, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST, "source-host", NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_STRING, .get_fcn.fstring = nm_team_link_watcher_get_source_host, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE, "validate-active", NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_BOOL, .get_fcn.fbool = _team_link_watcher_validate_active, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE, "validate-inactive", NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_BOOL, .get_fcn.fbool = _team_link_watcher_validate_inactive, ),
|
||||
_KEY_INFO (NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS, "send-always", NM_TEAM_LINK_WATCHER_TYPE_ARPING, KEY_TYPE_BOOL, .get_fcn.fbool = _team_link_watcher_send_always, ),
|
||||
|
||||
};
|
||||
|
||||
static NMTeamLinkWatcherType
|
||||
_team_link_watcher_get_watcher_type_from_name (const char *name)
|
||||
{
|
||||
if (name) {
|
||||
if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL))
|
||||
return NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL;
|
||||
if (nm_streq (name, NM_TEAM_LINK_WATCHER_NSNA_PING))
|
||||
return NM_TEAM_LINK_WATCHER_TYPE_NSNAPING;
|
||||
if (nm_streq (name, NM_TEAM_LINK_WATCHER_ARP_PING))
|
||||
return NM_TEAM_LINK_WATCHER_TYPE_ARPING;
|
||||
}
|
||||
return NM_TEAM_LINK_WATCHER_TYPE_NONE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_parse_data_get_str (const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM],
|
||||
NMTeamLinkWatcherKeyId key_id)
|
||||
{
|
||||
nm_assert (_NM_INT_NOT_NEGATIVE (key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM);
|
||||
nm_assert (_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_STRING);
|
||||
|
||||
return parse_data[key_id].str_val;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_data_get_int (const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM],
|
||||
NMTeamLinkWatcherKeyId key_id)
|
||||
{
|
||||
nm_assert (_NM_INT_NOT_NEGATIVE (key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM);
|
||||
nm_assert (_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_INT);
|
||||
|
||||
if (parse_data[key_id].str_val)
|
||||
return parse_data[key_id].typ_val.vint;
|
||||
return _team_link_watcher_key_infos[key_id].def_val.vint;
|
||||
}
|
||||
|
||||
static int
|
||||
_parse_data_get_bool (const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM],
|
||||
NMTeamLinkWatcherKeyId key_id)
|
||||
{
|
||||
nm_assert (_NM_INT_NOT_NEGATIVE (key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM);
|
||||
nm_assert (_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_BOOL);
|
||||
|
||||
if (parse_data[key_id].str_val)
|
||||
return parse_data[key_id].typ_val.vbool;
|
||||
return _team_link_watcher_key_infos[key_id].def_val.vbool;
|
||||
}
|
||||
|
||||
char *
|
||||
nm_utils_team_link_watcher_to_string (NMTeamLinkWatcher *watcher)
|
||||
{
|
||||
nm_auto_free_gstring GString *str = NULL;
|
||||
const char *name;
|
||||
NMTeamLinkWatcherType watcher_type;
|
||||
NMTeamLinkWatcherKeyId key_id;
|
||||
|
||||
if (!watcher)
|
||||
return NULL;
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
name = nm_team_link_watcher_get_name (watcher);
|
||||
g_string_append_printf (str, "name=%s", name ?: "");
|
||||
|
||||
watcher_type = _team_link_watcher_get_watcher_type_from_name (name);
|
||||
|
||||
for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) {
|
||||
const TeamLinkWatcherKeyInfo *info = &_team_link_watcher_key_infos[key_id];
|
||||
const char *vstr;
|
||||
int vint;
|
||||
bool vbool;
|
||||
|
||||
nm_assert (info->name && info->name && NM_STRCHAR_ALL (info->name, ch,((ch >= 'a' && ch <= 'z') || NM_IN_SET (ch, '-'))));
|
||||
nm_assert (NM_IN_SET (info->key_type, KEY_TYPE_STRING,
|
||||
KEY_TYPE_INT,
|
||||
KEY_TYPE_BOOL));
|
||||
|
||||
if (key_id == NM_TEAM_LINK_WATCHER_KEY_NAME)
|
||||
continue;
|
||||
|
||||
if (!NM_FLAGS_ALL (info->watcher_type, watcher_type))
|
||||
continue;
|
||||
|
||||
switch (info->key_type) {
|
||||
case KEY_TYPE_STRING:
|
||||
vstr = info->get_fcn.fstring (watcher);
|
||||
if (vstr) {
|
||||
g_string_append_printf (nm_gstring_add_space_delimiter (str),
|
||||
"%s=%s", info->name, vstr);
|
||||
}
|
||||
break;
|
||||
case KEY_TYPE_INT:
|
||||
vint = info->get_fcn.fint (watcher);
|
||||
if (vint != info->def_val.vint) {
|
||||
g_string_append_printf (nm_gstring_add_space_delimiter (str),
|
||||
"%s=%d", info->name, vint);
|
||||
}
|
||||
break;
|
||||
case KEY_TYPE_BOOL:
|
||||
vbool = info->get_fcn.fbool (watcher);
|
||||
if (vbool != info->def_val.vbool) {
|
||||
g_string_append_printf (nm_gstring_add_space_delimiter (str),
|
||||
"%s=%s", info->name, vbool ? "true" : "false");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (g_steal_pointer (&str), FALSE);
|
||||
}
|
||||
|
||||
NMTeamLinkWatcher *
|
||||
nm_utils_team_link_watcher_from_string (const char *str,
|
||||
GError **error)
|
||||
{
|
||||
gs_free const char **tokens = NULL;
|
||||
ParseData parse_data[_NM_TEAM_LINK_WATCHER_KEY_NUM] = { };
|
||||
NMTeamLinkWatcherType watcher_type;
|
||||
NMTeamLinkWatcherKeyId key_id;
|
||||
gsize i_token;
|
||||
NMTeamLinkWatcher *watcher;
|
||||
int errsv;
|
||||
|
||||
g_return_val_if_fail (str, NULL);
|
||||
g_return_val_if_fail (!error || !*error, NULL);
|
||||
|
||||
tokens = nm_utils_escaped_tokens_split (str, NM_ASCII_SPACES);
|
||||
if (!tokens) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid", str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i_token = 0; tokens[i_token]; i_token++) {
|
||||
const TeamLinkWatcherKeyInfo *info;
|
||||
const char *key = tokens[i_token];
|
||||
const char *val;
|
||||
|
||||
val = strchr (key, '=');
|
||||
if (!val) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("'%s' is not valid: properties should be specified as 'key=value'"),
|
||||
key);
|
||||
return NULL;
|
||||
}
|
||||
((char *) val)[0] = '\0';
|
||||
val++;
|
||||
|
||||
for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) {
|
||||
info = &_team_link_watcher_key_infos[key_id];
|
||||
if (nm_streq (key, info->name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (key_id == _NM_TEAM_LINK_WATCHER_KEY_NUM) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("'%s' is not a valid key"), key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parse_data[key_id].str_val) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("duplicate key '%s'"), key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parse_data[key_id].str_val = val;
|
||||
|
||||
if (info->key_type == KEY_TYPE_INT) {
|
||||
gint64 v64;
|
||||
|
||||
v64 = _nm_utils_ascii_str_to_int64 (val, 10, G_MININT, G_MAXINT, G_MAXINT64);
|
||||
if ( v64 == G_MAXINT64
|
||||
&& ((errsv = errno) != 0)) {
|
||||
if (errsv == ERANGE) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("number for '%s' is out of range"), key);
|
||||
} else {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("value for '%s' must be a number"), key);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
parse_data[key_id].typ_val.vint = v64;
|
||||
} else if (info->key_type == KEY_TYPE_BOOL) {
|
||||
int vbool;
|
||||
|
||||
vbool = _nm_utils_ascii_str_to_bool (val, -1);
|
||||
if (vbool == -1) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("value for '%s' must be a boolean"), key);
|
||||
return NULL;
|
||||
}
|
||||
parse_data[key_id].typ_val.vbool = vbool;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("missing 'name' attribute"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
watcher_type = _team_link_watcher_get_watcher_type_from_name (parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val);
|
||||
if (watcher_type == NM_TEAM_LINK_WATCHER_TYPE_NONE) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("invalid 'name' \"%s\""),
|
||||
parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) {
|
||||
const TeamLinkWatcherKeyInfo *info = &_team_link_watcher_key_infos[key_id];
|
||||
|
||||
if (!parse_data[key_id].str_val)
|
||||
continue;
|
||||
if (!NM_FLAGS_ALL (info->watcher_type, watcher_type)) {
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("attribute '%s' is invalid for \"%s\""),
|
||||
info->name,
|
||||
parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (watcher_type) {
|
||||
case NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL:
|
||||
watcher = nm_team_link_watcher_new_ethtool (_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_DELAY_UP),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN),
|
||||
error);
|
||||
break;
|
||||
case NM_TEAM_LINK_WATCHER_TYPE_NSNAPING:
|
||||
watcher = nm_team_link_watcher_new_nsna_ping (_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_INTERVAL),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX),
|
||||
_parse_data_get_str (parse_data, NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST),
|
||||
error);
|
||||
break;
|
||||
default:
|
||||
nm_assert (watcher_type == NM_TEAM_LINK_WATCHER_TYPE_ARPING);
|
||||
watcher = nm_team_link_watcher_new_arp_ping2 (_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_INTERVAL),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX),
|
||||
_parse_data_get_int (parse_data, NM_TEAM_LINK_WATCHER_KEY_VLANID),
|
||||
_parse_data_get_str (parse_data, NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST),
|
||||
_parse_data_get_str (parse_data, NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST),
|
||||
( NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE
|
||||
| (_parse_data_get_bool (parse_data, NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE) ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE)
|
||||
| (_parse_data_get_bool (parse_data, NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE) ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE)
|
||||
| (_parse_data_get_bool (parse_data, NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS) ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE)
|
||||
),
|
||||
error);
|
||||
break;
|
||||
}
|
||||
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
{
|
||||
gs_free char *str2 = NULL;
|
||||
nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher2 = NULL;
|
||||
static _nm_thread_local int recursive;
|
||||
|
||||
nm_assert (watcher);
|
||||
if (recursive == 0) {
|
||||
recursive = 1;
|
||||
str2 = nm_utils_team_link_watcher_to_string (watcher);
|
||||
nm_assert (str2);
|
||||
watcher2 = nm_utils_team_link_watcher_from_string (str2, NULL);
|
||||
nm_assert (watcher2);
|
||||
nm_assert (nm_team_link_watcher_equal (watcher, watcher2));
|
||||
nm_assert (nm_team_link_watcher_equal (watcher2, watcher));
|
||||
nm_assert (recursive == 1);
|
||||
recursive = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return watcher;
|
||||
}
|
||||
54
shared/nm-libnm-core-aux/nm-libnm-core-aux.h
Normal file
54
shared/nm-libnm-core-aux/nm-libnm-core-aux.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_LIBNM_CORE_AUX_H__
|
||||
#define __NM_LIBNM_CORE_AUX_H__
|
||||
|
||||
#include "nm-setting-team.h"
|
||||
|
||||
typedef enum {
|
||||
NM_TEAM_LINK_WATCHER_TYPE_NONE = 0,
|
||||
NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL = (1u << 0),
|
||||
NM_TEAM_LINK_WATCHER_TYPE_NSNAPING = (1u << 1),
|
||||
NM_TEAM_LINK_WATCHER_TYPE_ARPING = (1u << 2),
|
||||
} NMTeamLinkWatcherType;
|
||||
|
||||
typedef enum {
|
||||
NM_TEAM_LINK_WATCHER_KEY_NAME,
|
||||
NM_TEAM_LINK_WATCHER_KEY_DELAY_UP,
|
||||
NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN,
|
||||
NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT,
|
||||
NM_TEAM_LINK_WATCHER_KEY_INTERVAL,
|
||||
NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX,
|
||||
NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST,
|
||||
NM_TEAM_LINK_WATCHER_KEY_VLANID,
|
||||
NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST,
|
||||
NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE,
|
||||
NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE,
|
||||
NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS,
|
||||
_NM_TEAM_LINK_WATCHER_KEY_NUM,
|
||||
} NMTeamLinkWatcherKeyId;
|
||||
|
||||
char *nm_utils_team_link_watcher_to_string (NMTeamLinkWatcher *watcher);
|
||||
|
||||
NMTeamLinkWatcher *nm_utils_team_link_watcher_from_string (const char *str,
|
||||
GError **error);
|
||||
|
||||
#endif /* __NM_LIBNM_CORE_AUX_H__ */
|
||||
|
|
@ -461,4 +461,3 @@ int main (int argc, char **argv)
|
|||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1575,11 +1575,11 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, priv->subchannels_dbus, NULL);
|
||||
if (priv->s390_nettype)
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL);
|
||||
g_hash_table_iter_init (&iter, priv->s390_options);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
nm_setting_wired_add_s390_option (s_wired, (const char *) key, (const char *) value);
|
||||
}
|
||||
|
||||
_nm_setting_wired_clear_s390_options (s_wired);
|
||||
g_hash_table_iter_init (&iter, priv->s390_options);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
nm_setting_wired_add_s390_option (s_wired, (const char *) key, (const char *) value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -4512,7 +4512,7 @@ make_wired_setting (shvarFile *ifcfg,
|
|||
gs_free const char **options = NULL;
|
||||
gsize i;
|
||||
|
||||
options = nm_utils_strsplit_set_with_empty (value, " ");
|
||||
options = nm_utils_escaped_tokens_split (value, NM_ASCII_SPACES);
|
||||
for (i = 0; options && options[i]; i++) {
|
||||
const char *line = options[i];
|
||||
const char *equals;
|
||||
|
|
|
|||
|
|
@ -1118,14 +1118,22 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val);
|
||||
|
||||
/* portname is handled separately */
|
||||
if (!strcmp (s390_key, "portname") || !strcmp (s390_key, "ctcprot"))
|
||||
if (NM_IN_STRSET (s390_key, "portname", "ctcprot"))
|
||||
continue;
|
||||
|
||||
if (strchr (s390_key, '=')) {
|
||||
/* this key cannot be expressed. But after all, it's not valid anyway
|
||||
* and the connection shouldn't even verify. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tmp)
|
||||
tmp = g_string_sized_new (30);
|
||||
else
|
||||
g_string_append_c (tmp, ' ');
|
||||
g_string_append_printf (tmp, "%s=%s", s390_key, s390_val);
|
||||
nm_utils_escaped_tokens_escape_gstr (s390_key, NM_ASCII_SPACES, tmp);
|
||||
g_string_append_c (tmp, '=');
|
||||
nm_utils_escaped_tokens_escape_gstr (s390_val, NM_ASCII_SPACES, tmp);
|
||||
}
|
||||
if (tmp)
|
||||
svSetValueStr (ifcfg, "OPTIONS", tmp->str);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue