diff options
Diffstat (limited to 'libnm-core')
| -rw-r--r-- | libnm-core/nm-connection.c | 31 | ||||
| -rw-r--r-- | libnm-core/nm-core-internal.h | 18 | ||||
| -rw-r--r-- | libnm-core/nm-setting-8021x.h | 2 | ||||
| -rw-r--r-- | libnm-core/nm-setting-bond.c | 22 | ||||
| -rw-r--r-- | libnm-core/nm-setting-vlan.c | 1 | ||||
| -rw-r--r-- | libnm-core/tests/test-general.c | 116 | ||||
| -rw-r--r-- | libnm-core/tests/test-setting-bond.c | 49 |
7 files changed, 230 insertions, 9 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index ecfb9780..c1b75068 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -913,6 +913,36 @@ _normalize_bond_mode (NMConnection *self, GHashTable *parameters) } static gboolean +_normalize_bond_options (NMConnection *self, GHashTable *parameters) +{ + NMSettingBond *s_bond = nm_connection_get_setting_bond (self); + gboolean changed = FALSE; + const char *name, *mode_str; + NMBondMode mode; + guint32 num, i; + + /* Strip away unsupported options for current mode */ + if (s_bond) { + mode_str = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE); + mode = _nm_setting_bond_mode_from_string (mode_str); + if (mode == NM_BOND_MODE_UNKNOWN) + return FALSE; +again: + num = nm_setting_bond_get_num_options (s_bond); + for (i = 0; i < num; i++) { + if ( nm_setting_bond_get_option (s_bond, i, &name, NULL) + && !_nm_setting_bond_option_supported (name, mode)) { + nm_setting_bond_remove_option (s_bond, name); + changed = TRUE; + goto again; + } + } + } + + return changed; +} + +static gboolean _normalize_wireless_mac_address_randomization (NMConnection *self, GHashTable *parameters) { NMSettingWireless *s_wifi = nm_connection_get_setting_wireless (self); @@ -1275,6 +1305,7 @@ nm_connection_normalize (NMConnection *connection, was_modified |= _normalize_ethernet_link_neg (connection); was_modified |= _normalize_infiniband_mtu (connection, parameters); was_modified |= _normalize_bond_mode (connection, parameters); + was_modified |= _normalize_bond_options (connection, parameters); was_modified |= _normalize_wireless_mac_address_randomization (connection, parameters); was_modified |= _normalize_team_config (connection, parameters); was_modified |= _normalize_team_port_config (connection, parameters); diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index ac292bfc..91967ce3 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -343,6 +343,24 @@ _nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name); /*****************************************************************************/ +/* nm_connection_get_uuid() asserts against NULL, which is the right thing to + * do in order to catch bugs. However, sometimes that behavior is inconvenient. + * Just try or return NULL. */ + +static inline const char * +_nm_connection_get_id (NMConnection *connection) +{ + return connection ? nm_connection_get_id (connection) : NULL; +} + +static inline const char * +_nm_connection_get_uuid (NMConnection *connection) +{ + return connection ? nm_connection_get_uuid (connection) : NULL; +} + +/*****************************************************************************/ + typedef enum { NM_BOND_MODE_UNKNOWN = 0, NM_BOND_MODE_ROUNDROBIN, diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h index 0f5f7ddd..e1631e2d 100644 --- a/libnm-core/nm-setting-8021x.h +++ b/libnm-core/nm-setting-8021x.h @@ -175,7 +175,7 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_auth_flags >*/ /** * NMSetting8021x: * - * AIEEE 802.1x Authentication Settings + * IEEE 802.1x Authentication Settings */ struct _NMSetting8021x { NMSetting parent; diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 9a8bdc37..165001b0 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -85,8 +85,8 @@ static const BondDefault defaults[] = { { NM_SETTING_BOND_OPTION_USE_CARRIER, "1", NM_BOND_OPTION_TYPE_INT, 0, 1 }, { NM_SETTING_BOND_OPTION_AD_SELECT, "stable", NM_BOND_OPTION_TYPE_BOTH, 0, 2, { "stable", "bandwidth", "count", NULL } }, - { NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "layer2", NM_BOND_OPTION_TYPE_BOTH, 0, 2, - { "layer2", "layer3+4", "layer2+3", NULL } }, + { NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "layer2", NM_BOND_OPTION_TYPE_BOTH, 0, 4, + { "layer2", "layer3+4", "layer2+3", "encap2+3", "encap3+4", NULL } }, { NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", NM_BOND_OPTION_TYPE_INT, 0, 255 }, { NM_SETTING_BOND_OPTION_LACP_RATE, "slow", NM_BOND_OPTION_TYPE_BOTH, 0, 1, { "slow", "fast", NULL } }, @@ -542,6 +542,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) const char *arp_ip_target = NULL; const char *lacp_rate; const char *primary; + NMBondMode bond_mode; g_hash_table_iter_init (&iter, priv->options); while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { @@ -776,6 +777,23 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return NM_SETTING_VERIFY_NORMALIZABLE; } + /* normalize unsupported options for the current mode */ + bond_mode = _nm_setting_bond_mode_from_string (mode_new); + g_hash_table_iter_init (&iter, priv->options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) { + if (nm_streq (key, "mode")) + continue; + if (!_nm_setting_bond_option_supported (key, bond_mode)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is not valid with mode '%s'"), + key, mode_new); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + } + return TRUE; } diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index de9c5c48..ab1c5465 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -670,6 +670,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) _("the vlan id must be in range 0-4094 but is %u"), priv->id); g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID); + return FALSE; } if (priv->flags & ~NM_VLAN_FLAGS_ALL) { diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 7ecd6813..ccde24f8 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -4867,14 +4867,23 @@ enum TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED_64 { typeof (x) x1 = (x); \ type x2 = (type) x1; \ \ - if (((typeof (x1)) x2) == x1 && (x2 > 0 || x2 == 0)) { \ + g_assert_cmpint (expect, ==, nm_utils_is_power_of_two (x1)); \ + if ( ((typeof (x1)) x2) == x1 \ + && ((typeof (x2)) x1) == x2 \ + && x2 > 0) { \ /* x2 equals @x, and is positive. Compare to @expect */ \ g_assert_cmpint (expect, ==, nm_utils_is_power_of_two (x2)); \ - } else if (!(x2 > 0) && !(x2 == 0)) { \ - /* a (signed) negative value is always FALSE. */ \ - g_assert_cmpint (FALSE, ==, nm_utils_is_power_of_two (x2));\ + } else if (!(x2 > 0)) { \ + /* a non positive value is always FALSE. */ \ + g_assert_cmpint (FALSE, ==, nm_utils_is_power_of_two (x2)); \ + } \ + if (x2) { \ + x2 = -x2; \ + if (!(x2 > 0)) { \ + /* for negative values, we return FALSE. */ \ + g_assert_cmpint (FALSE, ==, nm_utils_is_power_of_two (x2)); \ + } \ } \ - g_assert_cmpint (expect, ==, nm_utils_is_power_of_two (x1)); \ } G_STMT_END static void @@ -4917,7 +4926,7 @@ again: gboolean expect = j == 0; guint64 x = expect ? xyes : xno; - if (!expect && xno == 0) + if (expect && xyes == 0) continue; /* check if @x is as @expect, when casted to a certain data type. */ @@ -5248,6 +5257,100 @@ static void test_nm_utils_enum (void) /*****************************************************************************/ +static void +do_test_utils_str_utf8safe (const char *str, const char *expected, NMUtilsStrUtf8SafeFlags flags) +{ + const char *str_safe, *s; + gs_free char *str2 = NULL; + gs_free char *str3 = NULL; + + str_safe = nm_utils_str_utf8safe_escape (str, flags, &str2); + + str3 = nm_utils_str_utf8safe_escape_cp (str, flags); + g_assert_cmpstr (str3, ==, str_safe); + g_assert ((!str && !str3) || (str != str3)); + g_clear_pointer (&str3, g_free); + + if (expected == NULL) { + g_assert (str_safe == str); + g_assert (!str2); + if (str) { + g_assert (!strchr (str, '\\')); + g_assert (g_utf8_validate (str, -1, NULL)); + } + + g_assert (str == nm_utils_str_utf8safe_unescape (str_safe, &str3)); + g_assert (!str3); + + str3 = nm_utils_str_utf8safe_unescape_cp (str_safe); + if (str) { + g_assert (str3 != str); + g_assert_cmpstr (str3, ==, str); + } else + g_assert (!str3); + g_clear_pointer (&str3, g_free); + return; + } + + g_assert (str); + g_assert (str_safe != str); + g_assert (str_safe == str2); + g_assert ( strchr (str, '\\') + || !g_utf8_validate (str, -1, NULL) + || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) + && NM_STRCHAR_ANY (str, ch, (guchar) ch >= 127)) + || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) + && NM_STRCHAR_ANY (str, ch, (guchar) ch < ' '))); + g_assert (g_utf8_validate (str_safe, -1, NULL)); + + str3 = g_strcompress (str_safe); + g_assert_cmpstr (str, ==, str3); + g_clear_pointer (&str3, g_free); + + str3 = nm_utils_str_utf8safe_unescape_cp (str_safe); + g_assert (str3 != str); + g_assert_cmpstr (str3, ==, str); + g_clear_pointer (&str3, g_free); + + s = nm_utils_str_utf8safe_unescape (str_safe, &str3); + g_assert (str3 != str); + g_assert (s == str3); + g_assert_cmpstr (str3, ==, str); + g_clear_pointer (&str3, g_free); + + g_assert_cmpstr (str_safe, ==, expected); +} + +static void +test_utils_str_utf8safe (void) +{ + do_test_utils_str_utf8safe (NULL, NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\314", "\\314", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\314\315x\315\315x", "\\314\\315x\\315\\315x", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\314\315xx", "\\314\\315xx", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\314xx", "\\314xx", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\xa0", "\\240", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\xe2\x91\xa0", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\xe2\xe2\x91\xa0", "\\342\xe2\x91\xa0", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("\xe2\xe2\x91\xa0\xa0", "\\342\xe2\x91\xa0\\240", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("a", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("ab", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("ab\314", "ab\\314", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("ab\314adsf", "ab\\314adsf", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("abadsf", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("abäb", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("x\xa0", "x\\240", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("Ä\304ab\\äb", "Ä\\304ab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("Äab\\äb", "Äab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("ÄÄab\\äb", "ÄÄab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("㈞abä㈞b", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe ("abäb", "ab\\303\\244b", NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII); + do_test_utils_str_utf8safe ("ab\ab", "ab\\007b", NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL); +} + +/*****************************************************************************/ + static int _test_nm_in_set_get (int *call_counter, gboolean allow_called, int value) { @@ -5605,6 +5708,7 @@ int main (int argc, char **argv) nmtst_init (&argc, &argv, TRUE); /* The tests */ + g_test_add_func ("/core/general/test_utils_str_utf8safe", test_utils_str_utf8safe); g_test_add_func ("/core/general/test_nm_in_set", test_nm_in_set); g_test_add_func ("/core/general/test_nm_in_strset", test_nm_in_strset); g_test_add_func ("/core/general/test_setting_vpn_items", test_setting_vpn_items); diff --git a/libnm-core/tests/test-setting-bond.c b/libnm-core/tests/test-setting-bond.c index 91a81997..e6a65bba 100644 --- a/libnm-core/tests/test-setting-bond.c +++ b/libnm-core/tests/test-setting-bond.c @@ -182,6 +182,54 @@ test_compare (void) ((const char *[]){ "num_unsol_na", "4", "num_grat_arp", "4", NULL })); } +static void +test_normalize_options (const char **opts1, const char **opts2) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingBond *s_bond; + GError *error = NULL; + gboolean success; + const char **p; + int num = 0; + + create_bond_connection (&con, &s_bond); + + for (p = opts1; p[0] && p[1]; p += 2) + g_assert (nm_setting_bond_add_option (s_bond, p[0], p[1])); + + nmtst_assert_connection_verifies_and_normalizable (con); + nmtst_connection_normalize (con); + success = nm_setting_verify ((NMSetting *) s_bond, con, &error); + nmtst_assert_success (success, error); + + for (p = opts2; p[0] && p[1]; p += 2) { + g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, p[0]), ==, p[1]); + num++; + } + + g_assert_cmpint (num, ==, nm_setting_bond_get_num_options (s_bond)); +} + +static void +test_normalize (void) +{ + test_normalize_options ( + ((const char *[]){ "mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL }), + ((const char *[]){ "mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL })); + test_normalize_options ( + ((const char *[]){ "mode", "1", "miimon", "1", NULL }), + ((const char *[]){ "mode", "active-backup", "miimon", "1", NULL })); + test_normalize_options ( + ((const char *[]){ "mode", "balance-alb", "tlb_dynamic_lb", "1", NULL }), + ((const char *[]){ "mode", "balance-alb", NULL })); + test_normalize_options ( + ((const char *[]){ "mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL }), + ((const char *[]){ "mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL })); + test_normalize_options ( + ((const char *[]){ "mode", "balance-rr", "ad_actor_sys_prio", "4", "packets_per_slave", "3", NULL }), + ((const char *[]){ "mode", "balance-rr", "packets_per_slave", "3", NULL })); +} + #define TPATH "/libnm/settings/bond/" NMTST_DEFINE (); @@ -193,6 +241,7 @@ main (int argc, char **argv) g_test_add_func (TPATH "verify", test_verify); g_test_add_func (TPATH "compare", test_compare); + g_test_add_func (TPATH "normalize", test_normalize); return g_test_run (); } |