summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-05-31 10:48:47 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2019-06-04 15:48:15 +0200
commit23b1f8234ded35b2debfc16e60f6fbebaf2b61e2 (patch)
tree9a2f65148d206bbef3746b334dff84279ccf9406
parentefe602af2a5df9d0cb157be3ef91ae4c9ecc5f44 (diff)
downloadNetworkManager-23b1f8234ded35b2debfc16e60f6fbebaf2b61e2.tar.gz
libnm/team: fix handling default values and stricter validate team config
For each artifical team property we need to track whether it was explicitly set (i.e., present in JSON/GVariant or set by the user via NMSettingTeam/NMSettingTeamPort API). -- As a plus, libnm is now no longer concerned with the underling default values that teamd uses. For example, the effective default value for "notify_peers.count" depends on the selected runner. But libnm does not need to care, it only cares wheher the property is set in JSON or not. This also means that the default (e.g. as interesting to `nmcli -o con show $PROFILE`) is independent from other properties (like the runner). Also change the default value for the GObject properties of NMSettingTeam and NMSettingTeamPort to indicate the "unset" value. For most properties, the default value is a special value that is not a valid configuration itself. For some properties the default value is itself a valid value, namely, "runner.active", "runner.fast_rate", "port.sticky" and "port.prio". As far as NMTeamSetting is concerned, it distinguishes between unset value and set value (including the default value). That means, when it parses a JSON or GVariant, it will remember whether the property was present or not. When using API of NMSettingTeam/NMSettingTeamPort to set a property to the default value, it marks the property as unset. For example, setting NM_SETTING_TEAM_RUNNER_ACTIVE to TRUE (the default), means that the value will not be serialized to JSON/GVariant. For the above 4 properties (where the default value is itself a valid value) this is a limitation of libnm API, as it does not allow to explicitly set '"runner": { "active": true }'. See SET_FIELD_MODE_SET_UNLESS_DEFAULT, Note that changing the default value for properties of NMSetting is problematic, because it changes behavior for how settings are parsed from keyfile/GVariant. For team settings that's not the case, because if a JSON "config" is present, all other properties are ignore. Also, we serialize properties to JSON/GVariant depending on whether it's marked as present, and not whether the value is set to the default (_nm_team_settings_property_to_dbus()). -- While at it, sticter validate the settings. Note that if a setting is initialized from JSON, the strict validation is not not performed. That means, such a setting will always validate, regardless whether the values in JSON are invalid according to libnm. Only when using the extended properties, strict validation is turned on. Note that libnm serializes the properties to GVariant both as JSON "config" and extended properties. Since when parsing a setting from GVariant will prefer the "config" (if present), in most cases also validation is performed. Likewise, settings plugins (keyfile, ifcfg-rh) only persist the JSON config to disk. When loading a setting from file, strict validation is also not performed. The stricter validation only happens if as last operation one of the artificial properties was set, or if the setting was created from a GVariant that has no "config" field. -- This is a (another) change in behavior.
-rw-r--r--clients/common/nm-meta-setting-desc.c46
-rw-r--r--libnm-core/nm-setting-team-port.c46
-rw-r--r--libnm-core/nm-setting-team.c65
-rw-r--r--libnm-core/nm-team-utils.c1057
-rw-r--r--libnm-core/nm-team-utils.h28
-rw-r--r--libnm-core/tests/test-general.c10
-rw-r--r--libnm-core/tests/test-setting.c116
7 files changed, 817 insertions, 551 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index c252832d35..a99bb014ee 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -6514,6 +6514,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "disabled",
},
@@ -6525,6 +6529,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "default",
},
@@ -6536,6 +6544,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "disabled",
},
@@ -6547,6 +6559,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "default",
},
@@ -6598,6 +6614,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
.nick = "default",
},
@@ -6615,6 +6635,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT,
.nick = "default",
},
@@ -6626,6 +6650,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "default",
},
@@ -6676,7 +6704,11 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
- .value.i64 = NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT,
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
.nick = "default",
},
),
@@ -6688,6 +6720,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
.value_infos = INT_VALUE_INFOS (
{
.value.i64 = 0,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
.nick = "default",
},
),
@@ -6701,6 +6737,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT,
.nick = "default",
},
@@ -6712,6 +6752,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
.value.i64 = 0,
.nick = "default",
},
diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c
index 22cbdb6703..504798c163 100644
--- a/libnm-core/nm-setting-team-port.c
+++ b/libnm-core/nm-setting-team-port.c
@@ -54,6 +54,14 @@ G_DEFINE_TYPE (NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING)
/*****************************************************************************/
+NMTeamSetting *
+_nm_setting_team_port_get_team_setting (NMSettingTeamPort *setting)
+{
+ return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->team_setting;
+}
+
+/*****************************************************************************/
+
#define _maybe_changed(self, changed) \
nm_team_setting_maybe_changed (NM_SETTING (_NM_ENSURE_TYPE (NMSettingTeamPort *, self)), (const GParamSpec *const*) obj_properties, (changed))
@@ -289,19 +297,6 @@ nm_setting_team_port_clear_link_watchers (NMSettingTeamPort *setting)
0));
}
-static GVariant *
-team_link_watchers_to_dbus (const GValue *prop_value)
-{
- return _nm_utils_team_link_watchers_to_variant (g_value_get_boxed (prop_value));
-}
-
-static void
-team_link_watchers_from_dbus (GVariant *dbus_value,
- GValue *prop_value)
-{
- g_value_take_boxed (prop_value, _nm_utils_team_link_watchers_from_variant (dbus_value, FALSE, NULL));
-}
-
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@@ -556,6 +551,13 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
setting_class->duplicate_copy_properties = duplicate_copy_properties;
setting_class->init_from_dbus = init_from_dbus;
+#define _property_override(_properties_override, _param_spec, _variant_type, _is_link_watcher) \
+ _properties_override_add ((_properties_override), \
+ .param_spec = (_param_spec), \
+ .dbus_type = G_VARIANT_TYPE (""_variant_type""), \
+ .to_dbus_fcn = _nm_team_settings_property_to_dbus, \
+ .gprop_from_dbus_fcn = ((_is_link_watcher) ? _nm_team_settings_property_from_dbus_link_watchers : NULL))
+
/**
* NMSettingTeamPort:config:
*
@@ -587,9 +589,10 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID] =
g_param_spec_int (NM_SETTING_TEAM_PORT_QUEUE_ID, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID], "i", FALSE);
/**
* NMSettingTeamPort:prio:
@@ -603,6 +606,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_PORT_PRIO], "i", FALSE);
/**
* NMSettingTeamPort:sticky:
@@ -616,6 +620,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_PORT_STICKY], "b", FALSE);
/**
* NMSettingTeamPort:lacp-prio:
@@ -626,9 +631,10 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO] =
g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_PRIO, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO], "i", FALSE);
/**
* NMSettingTeamPort:lacp-key:
@@ -639,9 +645,10 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_KEY] =
g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_KEY, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_KEY], "i", FALSE);
/**
* NMSettingTeamPort:link-watchers: (type GPtrArray(NMTeamLinkWatcher))
@@ -662,12 +669,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *klass)
G_TYPE_PTR_ARRAY,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
-
- _properties_override_add_transform (properties_override,
- obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS],
- G_VARIANT_TYPE ("aa{sv}"),
- team_link_watchers_to_dbus,
- team_link_watchers_from_dbus);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], "aa{sv}", TRUE);
g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_properties), obj_properties);
diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c
index a478b802b1..a9095836d3 100644
--- a/libnm-core/nm-setting-team.c
+++ b/libnm-core/nm-setting-team.c
@@ -734,6 +734,14 @@ G_DEFINE_TYPE (NMSettingTeam, nm_setting_team, NM_TYPE_SETTING)
/*****************************************************************************/
+NMTeamSetting *
+_nm_setting_team_get_team_setting (NMSettingTeam *setting)
+{
+ return NM_SETTING_TEAM_GET_PRIVATE (setting)->team_setting;
+}
+
+/*****************************************************************************/
+
#define _maybe_changed(self, changed) \
nm_team_setting_maybe_changed (NM_SETTING (_NM_ENSURE_TYPE (NMSettingTeam *, self)), (const GParamSpec *const*) obj_properties, (changed))
@@ -1223,19 +1231,6 @@ nm_setting_team_clear_link_watchers (NMSettingTeam *setting)
0));
}
-static GVariant *
-team_link_watchers_to_dbus (const GValue *prop_value)
-{
- return _nm_utils_team_link_watchers_to_variant (g_value_get_boxed (prop_value));
-}
-
-static void
-team_link_watchers_from_dbus (GVariant *dbus_value,
- GValue *prop_value)
-{
- g_value_take_boxed (prop_value, _nm_utils_team_link_watchers_from_variant (dbus_value, FALSE, NULL));
-}
-
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@@ -1503,6 +1498,13 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
setting_class->duplicate_copy_properties = duplicate_copy_properties;
setting_class->init_from_dbus = init_from_dbus;
+#define _property_override(_properties_override, _param_spec, _variant_type, _is_link_watcher) \
+ _properties_override_add ((_properties_override), \
+ .param_spec = (_param_spec), \
+ .dbus_type = G_VARIANT_TYPE (""_variant_type""), \
+ .to_dbus_fcn = _nm_team_settings_property_to_dbus, \
+ .gprop_from_dbus_fcn = ((_is_link_watcher) ? _nm_team_settings_property_from_dbus_link_watchers : NULL))
+
/**
* NMSettingTeam:config:
*
@@ -1533,9 +1535,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT] =
g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT], "i", FALSE);
/**
* NMSettingTeam:notify-peers-interval:
@@ -1546,9 +1549,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL] =
g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL], "i", FALSE);
/**
* NMSettingTeam:mcast-rejoin-count:
@@ -1559,9 +1563,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT] =
g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_COUNT, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT], "i", FALSE);
/**
* NMSettingTeam:mcast-rejoin-interval:
@@ -1572,9 +1577,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL] =
g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL], "i", FALSE);
/**
* NMSettingTeam:runner:
@@ -1590,6 +1596,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER], "s", FALSE);
/**
* NMSettingTeam:runner-hwaddr-policy:
@@ -1603,6 +1610,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY], "s", FALSE);
/**
* NMSettingTeam:runner-tx-hash:
@@ -1617,6 +1625,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
G_PARAM_READWRITE |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH], "as", FALSE);
/**
* NMSettingTeam:runner-tx-balancer:
@@ -1630,6 +1639,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER], "s", FALSE);
/**
* NMSettingTeam:runner-tx-balancer-interval:
@@ -1640,9 +1650,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL] =
g_param_spec_int (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL], "i", FALSE);
/**
* NMSettingTeam:runner-active:
@@ -1653,9 +1664,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE] =
g_param_spec_boolean (NM_SETTING_TEAM_RUNNER_ACTIVE, "", "",
- FALSE,
+ TRUE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE], "b", FALSE);
/**
* NMSettingTeam:runner-fast-rate:
@@ -1669,6 +1681,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE], "b", FALSE);
/**
* NMSettingTeam:runner-sys-prio:
@@ -1679,9 +1692,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO] =
g_param_spec_int (NM_SETTING_TEAM_RUNNER_SYS_PRIO, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO], "i", FALSE);
/**
* NMSettingTeam:runner-min-ports:
@@ -1692,9 +1706,10 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
**/
obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS] =
g_param_spec_int (NM_SETTING_TEAM_RUNNER_MIN_PORTS, "", "",
- G_MININT32, G_MAXINT32, 0,
+ G_MININT32, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS], "i", FALSE);
/**
* NMSettingTeam:runner-agg-select-policy:
@@ -1708,6 +1723,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY], "s", FALSE);
/**
* NMSettingTeam:link-watchers: (type GPtrArray(NMTeamLinkWatcher))
@@ -1728,12 +1744,7 @@ nm_setting_team_class_init (NMSettingTeamClass *klass)
G_TYPE_PTR_ARRAY,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
-
- _properties_override_add_transform (properties_override,
- obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS],
- G_VARIANT_TYPE ("aa{sv}"),
- team_link_watchers_to_dbus,
- team_link_watchers_from_dbus);
+ _property_override (properties_override, obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], "aa{sv}", TRUE);
/* ---dbus---
* property: interface-name
diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c
index f30cd108f4..701424a725 100644
--- a/libnm-core/nm-team-utils.c
+++ b/libnm-core/nm-team-utils.c
@@ -33,21 +33,115 @@
/*****************************************************************************/
+typedef enum {
+ SET_FIELD_MODE_UNSET = 0,
+ SET_FIELD_MODE_SET = 1,
+
+ /* Sets the field as set, unless the field is at the default.
+ * This is the case for API that is called from NMSettingTeam/NMSettingTeamPort.
+ * This means, using libnm API to reset the value of a NMSetting to the default,
+ * will mark the field as unset.
+ * This is different from initializing the field when parsing JSON/GVariant. In
+ * that case an explicitly set field (even set to the default value) will be remembered
+ * to be set. */
+ SET_FIELD_MODE_SET_UNLESS_DEFAULT = 2,
+} SetFieldModeEnum;
+
+typedef enum {
+ RESET_JSON_NO = FALSE,
+ RESET_JSON_YES = TRUE,
+} ResetJsonEnum;
+
/* we rely on "config" being the first. At various places we iterate over attribute types,
* starting after "config".*/
G_STATIC_ASSERT (_NM_TEAM_ATTRIBUTE_0 == 0);
G_STATIC_ASSERT (NM_TEAM_ATTRIBUTE_CONFIG == 1);
+static const char *const _valid_names_runner[] = {
+ NM_SETTING_TEAM_RUNNER_BROADCAST,
+ NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
+ NM_SETTING_TEAM_RUNNER_RANDOM,
+ NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
+ NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+ NM_SETTING_TEAM_RUNNER_LACP,
+ NULL,
+};
+
+static const char *const _valid_names_runner_hwaddr_policy[] = {
+ NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL,
+ NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE,
+ NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE,
+ NULL,
+};
+
+static const char *const _valid_names_runner_tx_balancer[] = {
+ "basic",
+ NULL,
+};
+
+static const char *const _valid_names_runner_tx_hash[] = {
+ "eth",
+ "vlan",
+ "ipv4",
+ "ipv6",
+ "ip",
+ "l3",
+ "l4",
+ "tcp",
+ "udp",
+ "sctp",
+ NULL,
+};
+
+static const char *const _valid_names_runner_agg_select_policy[] = {
+ "lacp_prio",
+ "lacp_prio_stable",
+ "bandwidth",
+ "count",
+ "port_config",
+ NULL,
+};
+
+typedef struct {
+ NMTeamAttribute team_attr;
+ const char *const*valid_runners;
+} RunnerCompatElem;
+
+static const RunnerCompatElem _runner_compat_lst[] = {
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+ NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+ NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+ NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+ { NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+};
+
typedef struct {
const char *const*js_keys;
- const char *dbus_name;
+ const char *property_name;
NMValueTypUnion default_val;
+ union {
+ struct {
+ gint32 min;
+ gint32 max;
+ } r_int32;
+ struct {
+ const char *const*valid_names;
+ } r_string;
+ } range;
NMTeamAttribute team_attr;
NMValueType value_type;
guint8 field_offset;
guint8 js_keys_len;
bool for_master:1;
bool for_port:1;
+ bool has_range:1;
} TeamAttrData;
#define TEAM_ATTR_IDX(_is_port, _team_attr) \
@@ -63,44 +157,65 @@ static const TeamAttrData team_attr_datas[] = {
.js_keys = NM_MAKE_STRV (__VA_ARGS__), \
.js_keys_len = NM_NARG (__VA_ARGS__)
-#define _INIT(_is_port, _team_attr, field, _value_type, _dbus_name, ...) \
+#define _VAL_BOOL(_default) \
+ .default_val.v_bool = (_default)
+
+#define _VAL_INT32(_default) \
+ .default_val.v_int32 = (_default)
+
+#define _VAL_INT32_RANGE(_default, _min,_max) \
+ _VAL_INT32 (_default), \
+ .has_range = TRUE, \
+ .range.r_int32 = { .min = _min, .max = _max, }
+
+#define _VAL_STRING() \
+ .default_val.v_string = NULL
+
+#define _VAL_STRING_RANGE(_valid_names) \
+ _VAL_STRING (), \
+ .has_range = TRUE, \
+ .range.r_string = { .valid_names = (_valid_names), }
+
+#define _VAL_UNSPEC() \
+ .default_val.v_string = (NULL)
+
+#define _INIT(_is_port, _team_attr, field, _value_type, _property_name, ...) \
[TEAM_ATTR_IDX (_is_port, _team_attr)] = { \
.for_master = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || !(_is_port), \
.for_port = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || (_is_port), \
.team_attr = (_team_attr), \
.field_offset = G_STRUCT_OFFSET (NMTeamSetting, _data_priv.field), \
.value_type = (_value_type), \
- .dbus_name = ""_dbus_name"", \
+ .property_name = ""_property_name"", \
__VA_ARGS__ \
}
- _INIT (0, NM_TEAM_ATTRIBUTE_CONFIG, _js_str, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_CONFIG, ),
-
- _INIT (0, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, link_watchers, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_LINK_WATCHERS, _JS_KEYS ("link_watch"), ),
-
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT, master.notify_peers_count, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, _JS_KEYS ("notify_peers", "count"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL, master.notify_peers_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, _JS_KEYS ("notify_peers", "interval"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT, master.mcast_rejoin_count, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_MCAST_REJOIN_COUNT, _JS_KEYS ("mcast_rejoin", "count"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL, master.mcast_rejoin_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, _JS_KEYS ("mcast_rejoin", "interval"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER, master.runner, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER, _JS_KEYS ("runner", "name"), .default_val.v_string = NM_SETTING_TEAM_RUNNER_DEFAULT, ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, master.runner_hwaddr_policy, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, _JS_KEYS ("runner", "hwaddr_policy"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, master.runner_tx_hash, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_RUNNER_TX_HASH, _JS_KEYS ("runner", "tx_hash"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, master.runner_tx_balancer, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_TX_BALANCER, _JS_KEYS ("runner", "tx_balancer", "name"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, master.runner_tx_balancer_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, _JS_KEYS ("runner", "tx_balancer", "balancing_interval"), .default_val.v_int32 = -1 ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, master.runner_active, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_RUNNER_ACTIVE, _JS_KEYS ("runner", "active"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, master.runner_fast_rate, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_RUNNER_FAST_RATE, _JS_KEYS ("runner", "fast_rate"), ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, master.runner_sys_prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_SYS_PRIO, _JS_KEYS ("runner", "sys_prio"), .default_val.v_int32 = -1, ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, master.runner_min_ports, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_MIN_PORTS, _JS_KEYS ("runner", "min_ports"), .default_val.v_int32 = -1, ),
- _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, master.runner_agg_select_policy, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, _JS_KEYS ("runner", "agg_select_policy"), ),
-
- _INIT (1, NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID, port.queue_id, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_QUEUE_ID, _JS_KEYS ("queue_id"), .default_val.v_int32 = NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT, ),
- _INIT (1, NM_TEAM_ATTRIBUTE_PORT_PRIO, port.prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_PRIO, _JS_KEYS ("prio"), ),
- _INIT (1, NM_TEAM_ATTRIBUTE_PORT_STICKY, port.sticky, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_PORT_STICKY, _JS_KEYS ("sticky"), ),
- _INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, port.lacp_prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_LACP_PRIO, _JS_KEYS ("lacp_prio"), .default_val.v_int32 = NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT, ),
- _INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, port.lacp_key, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_LACP_KEY, _JS_KEYS ("lacp_key"), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_CONFIG, _js_str, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_CONFIG, ),
+
+ _INIT (0, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, link_watchers, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_LINK_WATCHERS, _JS_KEYS ("link_watch"), _VAL_UNSPEC (), ),
+
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT, master.notify_peers_count, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, _JS_KEYS ("notify_peers", "count"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL, master.notify_peers_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, _JS_KEYS ("notify_peers", "interval"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT, master.mcast_rejoin_count, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_MCAST_REJOIN_COUNT, _JS_KEYS ("mcast_rejoin", "count"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL, master.mcast_rejoin_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, _JS_KEYS ("mcast_rejoin", "interval"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER, master.runner, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER, _JS_KEYS ("runner", "name"), _VAL_STRING_RANGE (_valid_names_runner), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, master.runner_hwaddr_policy, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, _JS_KEYS ("runner", "hwaddr_policy"), _VAL_STRING_RANGE (_valid_names_runner_hwaddr_policy), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, master.runner_tx_hash, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_RUNNER_TX_HASH, _JS_KEYS ("runner", "tx_hash"), _VAL_UNSPEC (), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, master.runner_tx_balancer, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_TX_BALANCER, _JS_KEYS ("runner", "tx_balancer", "name"), _VAL_STRING_RANGE (_valid_names_runner_tx_balancer), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, master.runner_tx_balancer_interval, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, _JS_KEYS ("runner", "tx_balancer", "balancing_interval"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, master.runner_active, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_RUNNER_ACTIVE, _JS_KEYS ("runner", "active"), _VAL_BOOL (TRUE), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, master.runner_fast_rate, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_RUNNER_FAST_RATE, _JS_KEYS ("runner", "fast_rate"), _VAL_BOOL (FALSE), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, master.runner_sys_prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_SYS_PRIO, _JS_KEYS ("runner", "sys_prio"), _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, master.runner_min_ports, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_RUNNER_MIN_PORTS, _JS_KEYS ("runner", "min_ports"), _VAL_INT32_RANGE (-1, 1, UCHAR_MAX + 1), ),
+ _INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, master.runner_agg_select_policy, NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, _JS_KEYS ("runner", "agg_select_policy"), _VAL_STRING_RANGE (_valid_names_runner_agg_select_policy), ),
+
+ _INIT (1, NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID, port.queue_id, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_QUEUE_ID, _JS_KEYS ("queue_id"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32), ),
+ _INIT (1, NM_TEAM_ATTRIBUTE_PORT_PRIO, port.prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_PRIO, _JS_KEYS ("prio"), _VAL_INT32 (0), ),
+ _INIT (1, NM_TEAM_ATTRIBUTE_PORT_STICKY, port.sticky, NM_VALUE_TYPE_BOOL, NM_SETTING_TEAM_PORT_STICKY, _JS_KEYS ("sticky"), _VAL_BOOL (FALSE), ),
+ _INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, port.lacp_prio, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_LACP_PRIO, _JS_KEYS ("lacp_prio"), _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1), ),
+ _INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, port.lacp_key, NM_VALUE_TYPE_INT32, NM_SETTING_TEAM_PORT_LACP_KEY, _JS_KEYS ("lacp_key"), _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1), ),
#undef _INIT
-
};
/*****************************************************************************/
@@ -177,8 +292,8 @@ static const TeamAttrData *_team_attr_data_get (gboolean is_port,
NMTeamAttribute team_attr);
static gpointer _team_setting_get_field (const NMTeamSetting *self,
const TeamAttrData *attr_data);
-static gboolean _team_setting_verify (const NMTeamSetting *self,
- GError **error);
+static gboolean _team_setting_verify_properties (const NMTeamSetting *self,
+ GError **error);
static void _link_watcher_to_json (const NMTeamLinkWatcher *link_watcher,
GString *gstr);
@@ -197,7 +312,7 @@ _team_attr_data_ASSERT (const TeamAttrData *attr_data)
nm_assert (attr_data->value_type > 0);
nm_assert (attr_data->field_offset < sizeof (NMTeamSetting));
nm_assert (attr_data->js_keys_len == NM_PTRARRAY_LEN (attr_data->js_keys));
- nm_assert (attr_data->dbus_name);
+ nm_assert (attr_data->property_name);
{
static int checked = 0;
@@ -235,124 +350,19 @@ _team_attr_data_get (gboolean is_port,
}
static const TeamAttrData *
-_team_attr_data_find_for_dbus_name (gboolean is_port,
- const char *dbus_name)
+_team_attr_data_find_for_property_name (gboolean is_port,
+ const char *property_name)
{
const TeamAttrData *attr_data;
for (attr_data = team_attr_datas; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
if ( _team_attr_data_is_relevant (attr_data, is_port)
- && nm_streq (dbus_name, attr_data->dbus_name))
+ && nm_streq (property_name, attr_data->property_name))
return attr_data;
}
return NULL;
}
-static const NMValueTypUnion *
-_team_attr_data_get_default (const TeamAttrData *attr_data,
- gboolean is_port,
- const char *v_master_runner,
- NMValueTypUnion *value_tmp)
-{
- GPtrArray *v_ptrarray;
-
- /* unfortunately, the default certain values depends on other values :(
- *
- * For examle, master attributes depend on the "runner" setting.
- * and port settings default to the ethtool link-watcher. */
-
- if (is_port) {
-
- switch (attr_data->team_attr) {
- case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: {
- static GPtrArray *volatile gl_arr = NULL;
-
-again_port_link_watchers:
- v_ptrarray = g_atomic_pointer_get (&gl_arr);
- if (G_UNLIKELY (!v_ptrarray)) {
- v_ptrarray = g_ptr_array_new_full (1, (GDestroyNotify) nm_team_link_watcher_unref);
- g_ptr_array_add (v_ptrarray, nm_team_link_watcher_new_ethtool (0, 0, NULL));
- if (!g_atomic_pointer_compare_and_exchange (&gl_arr, NULL, v_ptrarray)) {
- g_ptr_array_unref (v_ptrarray);
- goto again_port_link_watchers;
- }
- }
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_ptrarray, v_ptrarray);
- }
- default:
- break;
- }
-
- } else {
-
- if (NM_IN_STRSET (v_master_runner, NULL,
- NM_SETTING_TEAM_RUNNER_DEFAULT)) {
- /* a runner %NULL is the same as NM_SETTING_TEAM_RUNNER_DEFAULT ("roundrobin").
- * In this case, the settings in attr_data are accurate. */
- return &attr_data->default_val;
- }
-
- switch (attr_data->team_attr) {
- case NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_int32, NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_int32, NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_string, "same_all");
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH:
- if (NM_IN_STRSET (v_master_runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE,
- NM_SETTING_TEAM_RUNNER_LACP)) {
- static GPtrArray *volatile gl_arr = NULL;
-
-again_master_runner_tx_hash:
- v_ptrarray = g_atomic_pointer_get (&gl_arr);
- if (G_UNLIKELY (!v_ptrarray)) {
- v_ptrarray = g_ptr_array_sized_new (3);
- g_ptr_array_add (v_ptrarray, "eth");
- g_ptr_array_add (v_ptrarray, "ipv4");
- g_ptr_array_add (v_ptrarray, "ipv6");
- if (!g_atomic_pointer_compare_and_exchange (&gl_arr, NULL, v_ptrarray)) {
- g_ptr_array_unref (v_ptrarray);
- goto again_master_runner_tx_hash;
- }
- }
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_ptrarray, v_ptrarray);
- }
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL:
- if (NM_IN_STRSET (v_master_runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE,
- NM_SETTING_TEAM_RUNNER_LACP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_int32, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_LACP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_bool, TRUE);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_LACP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_int32, NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_LACP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_int32, 0);
- break;
- case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY:
- if (nm_streq (v_master_runner, NM_SETTING_TEAM_RUNNER_LACP))
- return NM_VALUE_TYP_UNION_SET (value_tmp, v_string, NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT);
- break;
- default:
- break;
- }
- }
-
- return &attr_data->default_val;
-}
static int
_team_attr_data_cmp (const TeamAttrData *attr_data,
gboolean is_port,
@@ -455,44 +465,6 @@ _team_attr_data_copy (const TeamAttrData *attr_data,
nm_assert_not_reached ();
}
-static gboolean
-_team_attr_data_is_default (const TeamAttrData *attr_data,
- gboolean is_port,
- const char *v_master_runner,
- gconstpointer p_field)
-{
- const NMValueTypUnion *default_value;
- NMValueTypUnion value_tmp;
-
- _team_attr_data_ASSERT (attr_data);
- nm_assert (p_field);
-
- default_value = _team_attr_data_get_default (attr_data,
- is_port,
- v_master_runner,
- &value_tmp);
- if (_team_attr_data_equal (attr_data,
- is_port,
- default_value,
- p_field))
- return TRUE;
-
- if ( attr_data->value_type == NM_VALUE_TYPE_STRING
- && default_value->v_string) {
- const char *str0 = NULL;
-
- /* this is a string value, whose default is not NULL. In such a case,
- * NULL is also treated like the default. */
- if (_team_attr_data_equal (attr_data,
- is_port,
- &str0,
- p_field))
- return TRUE;
- }
-
- return FALSE;
-}
-
static void
_team_attr_data_to_json (const TeamAttrData *attr_data,
gboolean is_port,
@@ -574,6 +546,64 @@ _team_setting_ASSERT (const NMTeamSetting *self)
#endif
}
+static gboolean
+_team_setting_has_field (const NMTeamSetting *self,
+ const TeamAttrData *attr_data)
+{
+ _team_setting_ASSERT (self);
+ return NM_FLAGS_ALL (self->d.has_fields_mask, nm_team_attribute_to_flags (attr_data->team_attr));
+}
+
+static gboolean
+_team_setting_has_fields_any_v (const NMTeamSetting *self,
+ const NMTeamAttribute *team_attrs,
+ gsize n_team_attrs)
+{
+ gsize i;
+
+ for (i = 0; i < n_team_attrs; i++) {
+ const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, team_attrs[i]);
+
+ if (_team_setting_has_field (self, attr_data))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#define _team_setting_has_fields_any(self, ...) \
+ _team_setting_has_fields_any_v ((self), ((const NMTeamAttribute []) { __VA_ARGS__ }), NM_NARG (__VA_ARGS__))
+
+static void
+_team_setting_has_field_set (NMTeamSetting *self,
+ const TeamAttrData *attr_data,
+ SetFieldModeEnum set_field_mode)
+{
+ guint32 mask = nm_team_attribute_to_flags (attr_data->team_attr);
+
+ _team_setting_ASSERT (self);
+
+ switch (set_field_mode) {
+ case SET_FIELD_MODE_UNSET:
+ goto do_unset;
+ case SET_FIELD_MODE_SET:
+ goto do_set;
+ case SET_FIELD_MODE_SET_UNLESS_DEFAULT:
+ if (_team_attr_data_equal (attr_data,
+ self->d.is_port,
+ _team_setting_get_field (self, attr_data),
+ &attr_data->default_val))
+ goto do_unset;
+ goto do_set;
+ }
+ nm_assert_not_reached ();
+
+do_unset:
+ self->_data_priv.has_fields_mask &= ~mask;
+ return;
+do_set:
+ self->_data_priv.has_fields_mask |= mask;
+}
+
static gpointer
_team_setting_get_field (const NMTeamSetting *self,
const TeamAttrData *attr_data)
@@ -593,12 +623,20 @@ _team_setting_get_field (const NMTeamSetting *self,
static guint32
_team_setting_attribute_changed (NMTeamSetting *self,
- NMTeamAttribute team_attr,
- gboolean changed)
+ const TeamAttrData *attr_data,
+ gboolean changed,
+ SetFieldModeEnum set_field_mode,
+ ResetJsonEnum reset_json)
{
guint32 changed_flags;
- nm_assert (_team_attr_data_get (self->d.is_port, team_attr));
+ _team_setting_has_field_set (self, attr_data, set_field_mode);
+
+ if (!reset_json) {
+ return changed
+ ? nm_team_attribute_to_flags (attr_data->team_attr)
+ : 0u;
+ }
if (!changed) {
/* a regular attribute was set, but the value did not change.
@@ -614,7 +652,7 @@ _team_setting_attribute_changed (NMTeamSetting *self,
return 0;
changed_flags = nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
} else {
- changed_flags = nm_team_attribute_to_flags (team_attr)
+ changed_flags = nm_team_attribute_to_flags (attr_data->team_attr)
| nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
}
@@ -625,13 +663,28 @@ _team_setting_attribute_changed (NMTeamSetting *self,
return changed_flags;
}
-static void
+static guint32
+_team_setting_attribute_changed_attr (NMTeamSetting *self,
+ NMTeamAttribute team_attr,
+ gboolean changed,
+ SetFieldModeEnum set_field_mode,
+ ResetJsonEnum reset_json)
+{
+ return _team_setting_attribute_changed (self,
+ _team_attr_data_get (self->d.is_port, team_attr),
+ changed,
+ set_field_mode,
+ reset_json);
+}
+
+static gboolean
_team_setting_field_to_json (const NMTeamSetting *self,
GString *gstr,
gboolean prepend_delimiter,
- NMTeamAttribute team_attr)
+ const TeamAttrData *attr_data)
{
- const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+ if (!_team_setting_has_field (self, attr_data))
+ return FALSE;
if (prepend_delimiter)
nm_json_aux_gstr_append_delimiter (gstr);
@@ -639,13 +692,13 @@ _team_setting_field_to_json (const NMTeamSetting *self,
self->d.is_port,
gstr,
_team_setting_get_field (self, attr_data));
+ return TRUE;
}
static gboolean
_team_setting_fields_to_json_maybe (const NMTeamSetting *self,
GString *gstr,
gboolean prepend_delimiter,
- const bool is_default_lst[static _NM_TEAM_ATTRIBUTE_NUM],
const NMTeamAttribute *team_attrs_lst,
gsize team_attrs_lst_len)
{
@@ -653,14 +706,13 @@ _team_setting_fields_to_json_maybe (const NMTeamSetting *self,
gboolean any_added = FALSE;
for (i = 0; i < team_attrs_lst_len; i++) {
- NMTeamAttribute team_attr = team_attrs_lst[i];
-
- if (is_default_lst[team_attr])
- continue;
-
- _team_setting_field_to_json (self, gstr, prepend_delimiter, team_attr);
- any_added = TRUE;
- prepend_delimiter = TRUE;
+ if (_team_setting_field_to_json (self,
+ gstr,
+ prepend_delimiter,
+ _team_attr_data_get (self->d.is_port, team_attrs_lst[i]))) {
+ any_added = TRUE;
+ prepend_delimiter = TRUE;
+ }
}
return any_added;
}
@@ -673,39 +725,22 @@ _team_setting_set (NMTeamSetting *self,
{
guint32 changed_flags = 0;
const TeamAttrData *attr_data;
- const char *v_master_runner;
nm_assert ((!has_lst) == (!val_lst));
- if (!self->d.is_port) {
- if ( has_lst
- && has_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER])
- v_master_runner = val_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER].v_string;
- else {
- nm_assert (nm_streq0 (_team_attr_data_get (FALSE, NM_TEAM_ATTRIBUTE_MASTER_RUNNER)->default_val.v_string,
- NM_SETTING_TEAM_RUNNER_DEFAULT));
- v_master_runner = NM_SETTING_TEAM_RUNNER_DEFAULT;
- }
- } else
- v_master_runner = NULL;
-
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
- NMValueTypUnion value_tmp;
const NMValueTypUnion *p_val;
gconstpointer p_field;
+ gboolean has_field;
if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
continue;
- if ( has_lst
- && has_lst[attr_data->team_attr])
- p_val = &val_lst[attr_data->team_attr];
- else {
- p_val = _team_attr_data_get_default (attr_data,
- self->d.is_port,
- v_master_runner,
- &value_tmp);
- }
+ has_field = (has_lst && has_lst[attr_data->team_attr]);
+
+ p_val = has_field
+ ? &val_lst[attr_data->team_attr]
+ : &attr_data->default_val;
p_field = _team_setting_get_field (self, attr_data);
@@ -721,6 +756,14 @@ _team_setting_set (NMTeamSetting *self,
}
changed_flags |= nm_team_attribute_to_flags (attr_data->team_attr);
}
+
+ if (modify) {
+ _team_setting_has_field_set (self,
+ attr_data,
+ has_field
+ ? SET_FIELD_MODE_SET
+ : SET_FIELD_MODE_UNSET);
+ }
}
return changed_flags;
@@ -749,31 +792,54 @@ _nm_team_setting_value_get (const NMTeamSetting *self,
nm_assert (value_type == attr_data->value_type);
+ nm_assert ( _team_setting_has_field (self, attr_data)
+ || _team_attr_data_equal (attr_data,
+ self->d.is_port,
+ _team_setting_get_field (self, attr_data),
+ &attr_data->default_val));
return _team_setting_get_field (self, attr_data);
}
static guint32
_team_setting_value_set (NMTeamSetting *self,
- NMTeamAttribute team_attr,
- NMValueType value_type,
- gconstpointer val)
+ const TeamAttrData *attr_data,
+ gconstpointer val,
+ SetFieldModeEnum set_field_mode,
+ ResetJsonEnum reset_json)
{
- const TeamAttrData *attr_data;
gpointer p_field;
+ gboolean changed;
nm_assert (self);
-
- attr_data = _team_attr_data_get (self->d.is_port, team_attr);
-
+ _team_attr_data_ASSERT (attr_data);
nm_assert (val);
- nm_assert (value_type == attr_data->value_type);
p_field = _team_setting_get_field (self, attr_data);
- if (nm_value_type_equal (attr_data->value_type, p_field, val))
- return 0u;
- nm_value_type_copy (attr_data->value_type, p_field, val);
- return nm_team_attribute_to_flags (team_attr);
+ changed = !_team_attr_data_equal (attr_data, self->d.is_port, p_field, val);
+ if (changed)
+ nm_value_type_copy (attr_data->value_type, p_field, val);
+ return _team_setting_attribute_changed (self, attr_data, changed, set_field_mode, reset_json);
+}
+
+guint32
+nm_team_setting_value_reset (NMTeamSetting *self,
+ NMTeamAttribute team_attr,
+ gboolean to_default /* or else unset */)
+{
+ const TeamAttrData *attr_data;
+
+ nm_assert (self);
+
+ attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+
+ return _team_setting_value_set (self,
+ attr_data,
+ &attr_data->default_val,
+ to_default
+ ? SET_FIELD_MODE_SET
+ : SET_FIELD_MODE_UNSET,
+ RESET_JSON_YES);
}
guint32
@@ -782,12 +848,19 @@ _nm_team_setting_value_set (NMTeamSetting *self,
NMValueType value_type,
gconstpointer val)
{
- return _team_setting_attribute_changed (self,
- team_attr,
- (_team_setting_value_set (self,
- team_attr,
- value_type,
- val) != 0u));
+ const TeamAttrData *attr_data;
+
+ nm_assert (self);
+
+ attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+
+ nm_assert (value_type == attr_data->value_type);
+
+ return _team_setting_value_set (self,
+ attr_data,
+ val,
+ SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+ RESET_JSON_YES);
}
guint32
@@ -795,14 +868,19 @@ nm_team_setting_value_link_watchers_add (NMTeamSetting *self,
const NMTeamLinkWatcher *link_watcher)
{
guint i;
+ gboolean changed;
for (i = 0; i < self->d.link_watchers->len; i++) {
- if (nm_team_link_watcher_equal (self->d.link_watchers->pdata[i], link_watcher))
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, FALSE);
+ if (nm_team_link_watcher_equal (self->d.link_watchers->pdata[i], link_watcher)) {
+ changed = FALSE;
+ goto out;
+ }
}
+ changed = TRUE;
g_ptr_array_add ((GPtrArray *) self->d.link_watchers,
_nm_team_link_watcher_ref ((NMTeamLinkWatcher *) link_watcher));
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, TRUE);
+out:
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, changed, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
}
guint32
@@ -816,7 +894,7 @@ nm_team_setting_value_link_watchers_remove_by_value (NMTeamSetting *self,
link_watcher))
return nm_team_setting_value_link_watchers_remove (self, i);
}
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, FALSE);
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, FALSE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
}
guint32
@@ -824,21 +902,28 @@ nm_team_setting_value_link_watchers_remove (NMTeamSetting *self,
guint idx)
{
g_ptr_array_remove_index ((GPtrArray *) self->d.link_watchers, idx);
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, TRUE);
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, TRUE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
}
static guint32
_team_setting_value_link_watchers_set_list (NMTeamSetting *self,
const NMTeamLinkWatcher *const*arr,
- guint len)
+ guint len,
+ SetFieldModeEnum set_field_mode,
+ ResetJsonEnum reset_json)
{
+ gboolean changed;
+
if ( self->d.link_watchers->len == len
&& nm_team_link_watchers_cmp ((const NMTeamLinkWatcher *const*) self->d.link_watchers->pdata,
arr,
len,
- FALSE) == 0)
- return 0;
+ FALSE) == 0) {
+ changed = FALSE;
+ goto out;
+ }
+ changed = TRUE;
if (len == 0)
g_ptr_array_set_size ((GPtrArray *) self->d.link_watchers, 0);
else {
@@ -857,7 +942,8 @@ _team_setting_value_link_watchers_set_list (NMTeamSetting *self,
}
}
- return nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_LINK_WATCHERS);
+out:
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, changed, set_field_mode, reset_json);
}
guint32
@@ -865,11 +951,11 @@ nm_team_setting_value_link_watchers_set_list (NMTeamSetting *self,
const NMTeamLinkWatcher *const*arr,
guint len)
{
- return _team_setting_attribute_changed (self,
- NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
- (_team_setting_value_link_watchers_set_list (self,
- arr,
- len) != 0u));
+ return _team_setting_value_link_watchers_set_list (self,
+ arr,
+ len,
+ SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+ RESET_JSON_YES);
}
/*****************************************************************************/
@@ -878,18 +964,23 @@ guint32
nm_team_setting_value_master_runner_tx_hash_add (NMTeamSetting *self,
const char *txhash)
{
+ gboolean changed;
guint i;
if (!self->d.master.runner_tx_hash)
self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func (g_free);
else {
for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
- if (nm_streq (txhash, self->d.master.runner_tx_hash->pdata[i]))
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, FALSE);
+ if (nm_streq (txhash, self->d.master.runner_tx_hash->pdata[i])) {
+ changed = FALSE;
+ goto out;
+ }
}
}
+ changed = TRUE;
g_ptr_array_add ((GPtrArray *) self->d.master.runner_tx_hash, g_strdup (txhash));
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, TRUE);
+out:
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, changed, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
}
guint32
@@ -897,22 +988,29 @@ nm_team_setting_value_master_runner_tx_hash_remove (NMTeamSetting *self,
guint idx)
{
g_ptr_array_remove_index ((GPtrArray *) self->d.master.runner_tx_hash, idx);
- return _team_setting_attribute_changed (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, TRUE);
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, TRUE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
}
static guint32
_team_setting_value_master_runner_tx_hash_set_list (NMTeamSetting *self,
const char *const*arr,
- guint len)
+ guint len,
+ SetFieldModeEnum set_field_mode,
+ ResetJsonEnum reset_json)
{
_nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL;
+ gboolean changed;
guint i;
if (_nm_utils_strv_cmp_n (self->d.master.runner_tx_hash ? (const char *const*) self->d.master.runner_tx_hash->pdata : NULL,
self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len : 0u,
arr,
- len) == 0)
- return 0u;
+ len) == 0) {
+ changed = FALSE;
+ goto out;
+ }
+
+ changed = TRUE;
old_val_destroy = (GPtrArray *) g_steal_pointer (&self->_data_priv.master.runner_tx_hash);
@@ -924,7 +1022,8 @@ _team_setting_value_master_runner_tx_hash_set_list (NMTeamSetting *self,
g_ptr_array_add ((GPtrArray *) self->d.master.runner_tx_hash, g_strdup (arr[i]));
}
- return nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH);
+out:
+ return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, changed, set_field_mode, reset_json);
}
guint32
@@ -932,11 +1031,11 @@ nm_team_setting_value_master_runner_tx_hash_set_list (NMTeamSetting *self,
const char *const*arr,
guint len)
{
- return _team_setting_attribute_changed (self,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
- (_team_setting_value_master_runner_tx_hash_set_list (self,
- arr,
- len) != 0u));
+ return _team_setting_value_master_runner_tx_hash_set_list (self,
+ arr,
+ len,
+ SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+ RESET_JSON_YES);
}
/*****************************************************************************/
@@ -1361,7 +1460,7 @@ _link_watcher_from_variant (GVariant *watcher_var,
* Returns: (transfer full): a new floating #GVariant representing link watchers.
**/
GVariant *
-_nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers)
+_nm_utils_team_link_watchers_to_variant (const GPtrArray *link_watchers)
{
GVariantBuilder builder;
guint i;
@@ -1441,29 +1540,13 @@ nm_team_setting_config_get (const NMTeamSetting *self)
* Nothing to do. */
js_str = NULL;
} else {
- const TeamAttrData *attr_data;
- GString *gstr;
- bool is_default_lst[_NM_TEAM_ATTRIBUTE_NUM] = { FALSE, };
gboolean list_is_empty = TRUE;
- const char *v_master_runner;
+ GString *gstr;
gstr = g_string_new (NULL);
g_string_append (gstr, "{ ");
- v_master_runner = self->d.is_port
- ? NULL
- : self->d.master.runner;
-
- for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
- if (_team_attr_data_is_relevant (attr_data, self->d.is_port)) {
- is_default_lst[attr_data->team_attr] = _team_attr_data_is_default (attr_data,
- self->d.is_port,
- v_master_runner,
- _team_setting_get_field (self, attr_data));
- }
- }
-
if (self->d.is_port) {
static const NMTeamAttribute attr_lst_port[] = {
NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID,
@@ -1473,57 +1556,57 @@ nm_team_setting_config_get (const NMTeamSetting *self)
NM_TEAM_ATTRIBUTE_PORT_LACP_KEY,
};
- if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty, is_default_lst, attr_lst_port, G_N_ELEMENTS (attr_lst_port)))
+ if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty, attr_lst_port, G_N_ELEMENTS (attr_lst_port)))
list_is_empty = FALSE;
} else {
+ static const NMTeamAttribute attr_lst_runner_pt1[] = {
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+ };
+ static const NMTeamAttribute attr_lst_runner_pt2[] = {
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
+ };
+ static const NMTeamAttribute attr_lst_runner_pt3[] = {
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
+ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
+ };
+ static const NMTeamAttribute attr_lst_notify_peers[] = {
+ NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,
+ NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,
+ };
+ static const NMTeamAttribute attr_lst_mcast_rejoin[] = {
+ NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,
+ NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,
+ };
- if ( !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY]) {
- static const NMTeamAttribute attr_lst_runner_pt1[] = {
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
- };
- static const NMTeamAttribute attr_lst_runner_pt2[] = {
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
- };
- static const NMTeamAttribute attr_lst_runner_pt3[] = {
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
- NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
- };
+ if ( _team_setting_has_fields_any_v (self, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1))
+ || _team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))
+ || _team_setting_has_fields_any_v (self, attr_lst_runner_pt3, G_N_ELEMENTS (attr_lst_runner_pt3))) {
gboolean list_is_empty2 = TRUE;
if (!list_is_empty)
nm_json_aux_gstr_append_delimiter (gstr);
nm_json_aux_gstr_append_obj_name (gstr, "runner", '{');
- if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, is_default_lst, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1)))
+ if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1)))
list_is_empty2 = FALSE;
- if ( !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL]) {
+ if (_team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))) {
if (!list_is_empty2)
nm_json_aux_gstr_append_delimiter (gstr);
nm_json_aux_gstr_append_obj_name (gstr, "tx_balancer", '{');
- if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, is_default_lst, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2)))
+ if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2)))
nm_assert_not_reached ();
g_string_append (gstr, " }");
list_is_empty2 = FALSE;
}
- if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, is_default_lst, attr_lst_runner_pt3, G_N_ELEMENTS (attr_lst_runner_pt3)))
+ if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt3, G_N_ELEMENTS (attr_lst_runner_pt3)))
list_is_empty2 = FALSE;
nm_assert (!list_is_empty2);
@@ -1531,43 +1614,33 @@ nm_team_setting_config_get (const NMTeamSetting *self)
list_is_empty = FALSE;
}
- if ( !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL]) {
- static const NMTeamAttribute attr_lst_notify_peers[] = {
- NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,
- NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,
- };
-
+ if (_team_setting_has_fields_any_v (self, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers))) {
if (!list_is_empty)
nm_json_aux_gstr_append_delimiter (gstr);
nm_json_aux_gstr_append_obj_name (gstr, "notify_peers", '{');
- if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, is_default_lst, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers)))
+ if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers)))
nm_assert_not_reached ();
g_string_append (gstr, " }");
list_is_empty = FALSE;
}
- if ( !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT]
- || !is_default_lst[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL]) {
- static const NMTeamAttribute attr_lst_notify_peers[] = {
- NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,
- NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,
- };
-
+ if (_team_setting_has_fields_any_v (self, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin))) {
if (!list_is_empty)
nm_json_aux_gstr_append_delimiter (gstr);
nm_json_aux_gstr_append_obj_name (gstr, "mcast_rejoin", '{');
- if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, is_default_lst, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers)))
+ if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin)))
nm_assert_not_reached ();
g_string_append (gstr, " }");
list_is_empty = FALSE;
}
}
- if (!is_default_lst[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) {
- _team_setting_field_to_json (self, gstr, !list_is_empty, NM_TEAM_ATTRIBUTE_LINK_WATCHERS);
+ if (_team_setting_field_to_json (self,
+ gstr,
+ !list_is_empty,
+ _team_attr_data_get (self->d.is_port, NM_TEAM_ATTRIBUTE_LINK_WATCHERS)))
list_is_empty = FALSE;
- }
+
if (!list_is_empty)
g_string_append (gstr, " }");
@@ -1846,7 +1919,7 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
val_lst);
if ( !unrecognized_content
- && _team_setting_verify (self, NULL)) {
+ && _team_setting_verify_properties (self, NULL)) {
/* if we could parse everything without unexpected/unknown data,
* we switch into strictly validating mode. */
new_strict_validated = TRUE;
@@ -1871,103 +1944,165 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
/*****************************************************************************/
static void
+_team_setting_prefix_error_plain (gboolean is_port,
+ const char *property_name,
+ GError **error)
+{
+ g_prefix_error (error,
+ "%s.%s: ",
+ is_port
+ ? NM_SETTING_TEAM_PORT_SETTING_NAME
+ : NM_SETTING_TEAM_SETTING_NAME,
+ property_name);
+}
+
+static void
_team_setting_prefix_error (const NMTeamSetting *self,
- GError **error,
const char *prop_name_master,
- const char *prop_name_port)
+ const char *prop_name_port,
+ GError **error)
{
_team_setting_ASSERT (self);
nm_assert ( self->d.is_port
? (!!prop_name_port)
: (!!prop_name_master));
- g_prefix_error (error,
- "%s.%s: ",
- self->d.is_port
- ? NM_SETTING_TEAM_PORT_SETTING_NAME
- : NM_SETTING_TEAM_SETTING_NAME,
- self->d.is_port
- ? prop_name_master
- : prop_name_port);
+ _team_setting_prefix_error_plain (self->d.is_port,
+ self->d.is_port
+ ? prop_name_port
+ : prop_name_master,
+ error);
}
static gboolean
-_team_setting_verify (const NMTeamSetting *self,
- GError **error)
+_team_setting_verify_properties (const NMTeamSetting *self,
+ GError **error)
{
+ const TeamAttrData *attr_data;
guint i;
- const char *js_str;
- if (!self->d.is_port) {
- if (!self->d.master.runner) {
- g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
- _("missing runner"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_RUNNER, NULL);
- return FALSE;
- }
- if ( self->d.master.runner
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_BROADCAST) != 0
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_ROUNDROBIN) != 0
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_RANDOM) != 0
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP) != 0
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE) != 0
- && g_ascii_strcasecmp (self->d.master.runner, NM_SETTING_TEAM_RUNNER_LACP) != 0) {
- g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
- _("invalid runner \"%s\""), self->d.master.runner);
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_RUNNER, NULL);
- return FALSE;
- }
+ for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
+
+ if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
+ continue;
+ if (!_team_setting_has_field (self, attr_data))
+ continue;
+
+ if (attr_data->has_range) {
+ gconstpointer p_field;
- if (self->d.master.runner_tx_hash) {
- for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
- const char *val = self->d.master.runner_tx_hash->pdata[i];
+ p_field = _team_setting_get_field (self, attr_data);
+ if (attr_data->value_type == NM_VALUE_TYPE_INT32) {
+ gint32 v = *((const gint32 *) p_field);
- if (!val[0]) {
+ if ( v < attr_data->range.r_int32.min
+ || v > attr_data->range.r_int32.max) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
- _("invalid runner.tx-hash"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_RUNNER_TX_HASH, NULL);
+ _("value out or range"));
+ _team_setting_prefix_error_plain (self->d.is_port, attr_data->property_name, error);
return FALSE;
}
+ } else if (attr_data->value_type == NM_VALUE_TYPE_STRING) {
+ const char *v = *((const char *const*) p_field);
+
+ if (nm_utils_strv_find_first ((char **) attr_data->range.r_string.valid_names,
+ -1,
+ v) < 0) {
+ g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
+ _("invalid value"));
+ _team_setting_prefix_error_plain (self->d.is_port, attr_data->property_name, error);
+ return FALSE;
+ }
+ } else
+ nm_assert_not_reached ();
+ }
+
+ if ( !self->d.is_port
+ && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+ if (self->d.master.runner_tx_hash) {
+ for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
+ const char *val = self->d.master.runner_tx_hash->pdata[i];
+
+ if ( !val
+ || (nm_utils_strv_find_first ((char **) _valid_names_runner_tx_hash,
+ -1,
+ val) < 0)) {
+ g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
+ _("invalid runner-tx-hash"));
+ _team_setting_prefix_error_plain (self->d.is_port, NM_SETTING_TEAM_RUNNER_TX_HASH, error);
+ return FALSE;
+ }
+ }
}
}
}
- for (i = 0; i < self->d.link_watchers->len; i++) {
- NMTeamLinkWatcher *link_watcher = self->d.link_watchers->pdata[i];
- const char *name = nm_team_link_watcher_get_name (link_watcher);
-
- if (!NM_IN_STRSET (name,
- NM_TEAM_LINK_WATCHER_ETHTOOL,
- NM_TEAM_LINK_WATCHER_ARP_PING,
- NM_TEAM_LINK_WATCHER_NSNA_PING)) {
- if (!name) {
- g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING,
- _("missing link watcher name"));
+ if (!self->d.is_port) {
+
+ for (i = 0; i < G_N_ELEMENTS (_runner_compat_lst); i++) {
+ const RunnerCompatElem *e = &_runner_compat_lst[i];
+
+ nm_assert (NM_PTRARRAY_LEN (e->valid_runners) > 0);
+
+ attr_data = _team_attr_data_get (FALSE, e->team_attr);
+
+ if (!_team_setting_has_field (self, attr_data))
+ continue;
+ if ( self->d.master.runner
+ && (nm_utils_strv_find_first ((char **) e->valid_runners,
+ -1,
+ self->d.master.runner) >= 0))
+ continue;
+ if (e->valid_runners[1] == NULL) {
+ g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
+ _("%s is only allowed for runner %s"),
+ attr_data->property_name,
+ e->valid_runners[0]);
} else {
+ gs_free char *s = NULL;
+
+ s = g_strjoinv (",", (char **) e->valid_runners);
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
- _("unknown link watcher \"%s\""), name);
+ _("%s is only allowed for runners %s"),
+ attr_data->property_name,
+ s);
}
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS);
+ _team_setting_prefix_error_plain (self->d.is_port, NM_SETTING_TEAM_RUNNER, error);
return FALSE;
}
-
- if ( NM_IN_STRSET (name,
- NM_TEAM_LINK_WATCHER_ARP_PING,
- NM_TEAM_LINK_WATCHER_NSNA_PING)
- && !nm_team_link_watcher_get_target_host (link_watcher)) {
- g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING,
- _("missing target host"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS);
+ } else {
+ gboolean has_lacp_attrs;
+ gboolean has_activebackup_attrs;
+
+ has_lacp_attrs = _team_setting_has_fields_any (self, NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
+ NM_TEAM_ATTRIBUTE_PORT_LACP_KEY);
+ has_activebackup_attrs = _team_setting_has_fields_any (self, NM_TEAM_ATTRIBUTE_PORT_PRIO,
+ NM_TEAM_ATTRIBUTE_PORT_STICKY);
+ if (has_lacp_attrs && has_activebackup_attrs) {
+ g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
+ _("cannot set parameters for lacp and activebackup runners together"));
+ _team_setting_prefix_error (self, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS, error);
return FALSE;
}
- if ( nm_streq (name, NM_TEAM_LINK_WATCHER_ARP_PING)
- && !nm_team_link_watcher_get_source_host (link_watcher)) {
- g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING,
- _("missing source address"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS);
+ }
+
+ for (i = 0; i < self->d.link_watchers->len; i++) {
+ if (!self->d.link_watchers->pdata[i]) {
+ g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
+ _("missing link watcher"));
+ _team_setting_prefix_error (self, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS, error);
return FALSE;
}
}
+ return TRUE;
+}
+
+static gboolean
+_team_setting_verify_config (const NMTeamSetting *self,
+ GError **error)
+{
+ const char *js_str;
+
/* we always materialize the JSON string. That is because we want to validate the
* string length of the resulting JSON. */
js_str = nm_team_setting_config_get (self);
@@ -1976,19 +2111,19 @@ _team_setting_verify (const NMTeamSetting *self,
if (strlen (js_str) > 1*1024*1024) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("team config exceeds size limit"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG);
+ _team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
return FALSE;
}
if (!g_utf8_validate (js_str, -1, NULL)) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("team config is not valid UTF-8"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG);
+ _team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
return FALSE;
}
if (self->d.js_str_invalid) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("invalid json"));
- _team_setting_prefix_error (self, error, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG);
+ _team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
return FALSE;
}
}
@@ -2000,7 +2135,11 @@ gboolean
nm_team_setting_verify (const NMTeamSetting *self,
GError **error)
{
- return _team_setting_verify (self, error);
+ if (self->d.strict_validated) {
+ if (!_team_setting_verify_properties (self, error))
+ return FALSE;
+ }
+ return _team_setting_verify_config (self, error);
}
/*****************************************************************************/
@@ -2017,12 +2156,13 @@ nm_team_setting_cmp (const NMTeamSetting *self_a,
NM_CMP_FIELD_UNSAFE (self_a, self_b, d.is_port);
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
- if (_team_attr_data_is_relevant (attr_data, self_a->d.is_port)) {
- NM_CMP_RETURN (_team_attr_data_cmp (attr_data,
- self_a->d.is_port,
- _team_setting_get_field (self_a, attr_data),
- _team_setting_get_field (self_b, attr_data)));
- }
+ if (!_team_attr_data_is_relevant (attr_data, self_a->d.is_port))
+ continue;
+
+ NM_CMP_RETURN (_team_attr_data_cmp (attr_data,
+ self_a->d.is_port,
+ _team_setting_get_field (self_a, attr_data),
+ _team_setting_get_field (self_b, attr_data)));
}
if (!ignore_js_str) {
@@ -2038,7 +2178,7 @@ nm_team_setting_reset (NMTeamSetting *self,
const NMTeamSetting *src)
{
const TeamAttrData *attr_data;
- guint32 changed;
+ guint32 changed_flags;
_team_setting_ASSERT (self);
_team_setting_ASSERT (src);
@@ -2047,7 +2187,7 @@ nm_team_setting_reset (NMTeamSetting *self,
if (self == src)
return 0;
- changed = 0;
+ changed_flags = 0;
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
@@ -2061,21 +2201,23 @@ nm_team_setting_reset (NMTeamSetting *self,
self->d.is_port,
_team_setting_get_field (self, attr_data),
_team_setting_get_field (src, attr_data));
- changed |= nm_team_attribute_to_flags (attr_data->team_attr);
+ changed_flags |= nm_team_attribute_to_flags (attr_data->team_attr);
}
+ self->_data_priv.has_fields_mask = src->d.has_fields_mask;
+
if (!nm_streq0 (self->d._js_str, src->d._js_str)) {
g_free ((char *) self->_data_priv._js_str);
self->_data_priv._js_str = g_strdup (src->d._js_str);
- changed |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
- } else if (changed != 0)
- changed |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
+ changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
+ } else if (changed_flags != 0)
+ changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
self->_data_priv._js_str_need_synthetize = src->d._js_str_need_synthetize;
self->_data_priv.strict_validated = src->d.strict_validated;
self->_data_priv.js_str_invalid = src->d.js_str_invalid;
- return changed;
+ return changed_flags;
}
static void
@@ -2109,7 +2251,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
_nm_unused gs_unref_variant GVariant *v_val_free = v_val;
const GVariantType *variant_type = NULL;
- attr_data = _team_attr_data_find_for_dbus_name (self->d.is_port, v_key);
+ attr_data = _team_attr_data_find_for_property_name (self->d.is_port, v_key);
if (!attr_data) {
/* _nm_setting_new_from_dbus() already checks for unknown keys. Don't
* do that here. */
@@ -2136,10 +2278,9 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("invalid D-Bus type \"%s\""),
g_variant_get_type_string (v_val));
- _team_setting_prefix_error (self,
- error,
- attr_data->dbus_name,
- attr_data->dbus_name);
+ _team_setting_prefix_error_plain (self->d.is_port,
+ attr_data->property_name,
+ error);
return FALSE;
}
continue;
@@ -2162,9 +2303,9 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
_("invalid link-watchers: %s"),
local->message);
_team_setting_prefix_error (self,
- error,
NM_SETTING_TEAM_LINK_WATCHERS,
- NM_SETTING_TEAM_PORT_LINK_WATCHERS);
+ NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+ error);
return FALSE;
}
}
@@ -2184,7 +2325,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
NMValueTypUnion val;
- guint32 changed = 0u;
+ guint32 changed_flags = 0u;
if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
continue;
@@ -2193,27 +2334,32 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
nm_value_type_get_from_variant (attr_data->value_type, &val, variants[attr_data->team_attr], FALSE);
- changed = _team_setting_value_set (self,
- attr_data->team_attr,
- attr_data->value_type,
- &val);
+ changed_flags = _team_setting_value_set (self,
+ attr_data,
+ &val,
+ SET_FIELD_MODE_SET,
+ RESET_JSON_NO);
} else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
- changed = _team_setting_value_link_watchers_set_list (self,
- v_link_watchers ? (const NMTeamLinkWatcher *const *) v_link_watchers->pdata : NULL,
- v_link_watchers ? v_link_watchers->len : 0u);
+ changed_flags = _team_setting_value_link_watchers_set_list (self,
+ v_link_watchers ? (const NMTeamLinkWatcher *const *) v_link_watchers->pdata : NULL,
+ v_link_watchers ? v_link_watchers->len : 0u,
+ SET_FIELD_MODE_SET,
+ RESET_JSON_NO);
} else if ( !self->d.is_port
&& attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
gs_free const char **strv = NULL;
gsize len;
strv = g_variant_get_strv (variants[attr_data->team_attr], &len);
- changed = _team_setting_value_master_runner_tx_hash_set_list (self,
- strv,
- NM_MIN (len, (gsize) G_MAXUINT));
+ changed_flags = _team_setting_value_master_runner_tx_hash_set_list (self,
+ strv,
+ NM_MIN (len, (gsize) G_MAXUINT),
+ SET_FIELD_MODE_SET,
+ RESET_JSON_NO);
} else
nm_assert_not_reached ();
- extra_changed |= changed;
+ extra_changed |= changed_flags;
}
if ( !variants[NM_TEAM_ATTRIBUTE_CONFIG]
@@ -2273,6 +2419,55 @@ nm_team_setting_maybe_changed (NMSetting *source,
/*****************************************************************************/
NMTeamSetting *
+_nm_setting_get_team_setting (struct _NMSetting *setting)
+{
+ if (NM_IS_SETTING_TEAM (setting))
+ return _nm_setting_team_get_team_setting (NM_SETTING_TEAM (setting));
+ return _nm_setting_team_port_get_team_setting (NM_SETTING_TEAM_PORT (setting));
+}
+
+GVariant *
+_nm_team_settings_property_to_dbus (const NMSettInfoSetting *sett_info,
+ guint property_idx,
+ NMConnection *connection,
+ NMSetting *setting,
+ NMConnectionSerializationFlags flags)
+{
+ NMTeamSetting *self = _nm_setting_get_team_setting (setting);
+ const NMSettInfoProperty *property = &sett_info->property_infos[property_idx];
+ NMTeamAttribute team_attr = property->param_spec->param_id;
+ const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+
+ if (!_team_setting_has_field (self, attr_data))
+ return NULL;
+
+ if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
+ return nm_value_type_to_variant (attr_data->value_type,
+ _team_setting_get_field (self, attr_data));
+ }
+ if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS)
+ return _nm_utils_team_link_watchers_to_variant (self->d.link_watchers);
+ if ( !self->d.is_port
+ && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+ return g_variant_new_strv (self->d.master.runner_tx_hash ? (const char *const*) self->d.master.runner_tx_hash->pdata : NULL,
+ self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len : 0u);
+ }
+
+ nm_assert_not_reached ();
+ return NULL;
+}
+
+void
+_nm_team_settings_property_from_dbus_link_watchers (GVariant *dbus_value,
+ GValue *prop_value)
+{
+ g_value_take_boxed (prop_value,
+ _nm_utils_team_link_watchers_from_variant (dbus_value, FALSE, NULL));
+}
+
+/*****************************************************************************/
+
+NMTeamSetting *
nm_team_setting_new (gboolean is_port,
const char *js_str)
{
diff --git a/libnm-core/nm-team-utils.h b/libnm-core/nm-team-utils.h
index e443b27dd3..0e897da96a 100644
--- a/libnm-core/nm-team-utils.h
+++ b/libnm-core/nm-team-utils.h
@@ -96,6 +96,8 @@ struct _NMTeamSettingData {
bool is_port:1;
+ guint32 has_fields_mask;
+
union {
struct {
const GPtrArray *runner_tx_hash;
@@ -185,6 +187,10 @@ nm_team_setting_value_get_string (const NMTeamSetting *self,
/*****************************************************************************/
+guint32 nm_team_setting_value_reset (NMTeamSetting *self,
+ NMTeamAttribute team_attr,
+ gboolean to_default /* or else unset */);
+
guint32 _nm_team_setting_value_set (NMTeamSetting *self,
NMTeamAttribute team_attr,
NMValueType value_type,
@@ -269,7 +275,7 @@ gboolean nm_team_setting_reset_from_dbus (NMTeamSetting *self,
GPtrArray *_nm_utils_team_link_watchers_from_variant (GVariant *value,
gboolean strict_parsing,
GError **error);
-GVariant *_nm_utils_team_link_watchers_to_variant (GPtrArray *link_watchers);
+GVariant *_nm_utils_team_link_watchers_to_variant (const GPtrArray *link_watchers);
/*****************************************************************************/
@@ -277,4 +283,24 @@ gboolean nm_team_setting_maybe_changed (struct _NMSetting *source,
const GParamSpec *const*obj_properties,
guint32 changed);
+struct _NMSettingTeam;
+struct _NMSettingTeamPort;
+NMTeamSetting *_nm_setting_team_get_team_setting (struct _NMSettingTeam *setting);
+NMTeamSetting *_nm_setting_team_port_get_team_setting (struct _NMSettingTeamPort *setting);
+NMTeamSetting *_nm_setting_get_team_setting (struct _NMSetting *setting);
+
+/*****************************************************************************/
+
+#include "nm-connection.h"
+#include "nm-core-internal.h"
+
+GVariant *_nm_team_settings_property_to_dbus (const NMSettInfoSetting *sett_info,
+ guint property_idx,
+ NMConnection *connection,
+ NMSetting *setting,
+ NMConnectionSerializationFlags flags);
+
+void _nm_team_settings_property_from_dbus_link_watchers (GVariant *dbus_value,
+ GValue *prop_value);
+
#endif /* __NM_TEAM_UITLS_H__ */
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index a8d182c457..1c023b65bd 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -6863,10 +6863,6 @@ test_nm_utils_team_config_equal (void)
/* team config */
_team_config_equal_check ("{ }",
- "{ \"runner\" : { \"name\" : \"roundrobin\"} }",
- FALSE,
- TRUE);
- _team_config_equal_check ("{ }",
"{ \"runner\" : { \"name\" : \"random\"} }",
FALSE,
!WITH_JSON_VALIDATION);
@@ -6889,7 +6885,7 @@ test_nm_utils_team_config_equal (void)
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }",
"{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
FALSE,
- TRUE);
+ !WITH_JSON_VALIDATION);
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
"{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
FALSE,
@@ -6903,7 +6899,7 @@ test_nm_utils_team_config_equal (void)
_team_config_equal_check ("{ }",
"{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
TRUE,
- TRUE);
+ !WITH_JSON_VALIDATION);
_team_config_equal_check ("{ }",
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
TRUE,
@@ -6911,7 +6907,7 @@ test_nm_utils_team_config_equal (void)
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
TRUE,
- TRUE);
+ !WITH_JSON_VALIDATION);
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
TRUE,
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 8741d97737..5c0b731137 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -1057,11 +1057,11 @@ static void
test_runner_roundrobin_sync_from_config (void)
{
_test_team_config_sync ("",
- 0, 0, 0, 0,
- NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
+ -1, -1, -1, -1,
+ NULL,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
}
@@ -1069,11 +1069,11 @@ static void
test_runner_broadcast_sync_from_config (void)
{
_test_team_config_sync ("{\"runner\": {\"name\": \"broadcast\"}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_BROADCAST,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
}
@@ -1081,11 +1081,11 @@ static void
test_runner_random_sync_from_config (void)
{
_test_team_config_sync ("{\"runner\": {\"name\": \"random\"}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_RANDOM,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
}
@@ -1093,12 +1093,11 @@ static void
test_runner_activebackup_sync_from_config (void)
{
_test_team_config_sync ("{\"runner\": {\"name\": \"activebackup\"}}",
- NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT, 0,
- NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
- NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT,
+ NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
}
@@ -1113,29 +1112,29 @@ test_runner_loadbalance_sync_from_config (void)
g_ptr_array_add (tx_hash, g_strdup ("ipv6"));
_test_team_config_sync ("{\"runner\": {\"name\": \"loadbalance\"}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_LOADBALANCE,
NULL,
- tx_hash, NULL, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
- FALSE, FALSE, -1, -1, NULL,
+ NULL, NULL, -1,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
_test_team_config_sync ("{\"runner\": {\"name\": \"loadbalance\", "
"\"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"]}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_LOADBALANCE,
NULL,
- tx_hash, NULL, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
- FALSE, FALSE, -1, -1, NULL,
+ tx_hash, NULL, -1,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
_test_team_config_sync ("{\"runner\": {\"name\": \"loadbalance\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"], "
"\"tx_balancer\": {\"name\": \"basic\", \"balancing_interval\": 30}}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_LOADBALANCE,
NULL,
tx_hash, "basic", 30,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
NULL);
}
@@ -1150,21 +1149,21 @@ test_runner_lacp_sync_from_config (void)
g_ptr_array_add (tx_hash, g_strdup ("ipv6"));
_test_team_config_sync ("{\"runner\": {\"name\": \"lacp\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"]}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_LACP,
NULL,
- tx_hash, NULL, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
- TRUE, FALSE, NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT, 0,
- NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT,
+ tx_hash, NULL, -1,
+ TRUE, FALSE, -1, -1,
+ NULL,
NULL);
_test_team_config_sync ("{\"runner\": {\"name\": \"lacp\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"], "
"\"active\": false, \"fast_rate\": true, \"sys_prio\": 10, \"min_ports\": 5, "
"\"agg_select_policy\": \"port_config\"}}",
- 0, 0, 0, 0,
+ -1, -1, -1, -1,
NM_SETTING_TEAM_RUNNER_LACP,
NULL,
- tx_hash, NULL, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
+ tx_hash, NULL, -1,
FALSE, TRUE, 10, 5, "port_config",
NULL);
}
@@ -1177,11 +1176,11 @@ test_watcher_ethtool_sync_from_config (void)
link_watchers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref);
g_ptr_array_add (link_watchers, nm_team_link_watcher_new_ethtool (0, 0, NULL));
_test_team_config_sync ("{\"link_watch\": {\"name\": \"ethtool\"}}",
- 0, 0, 0, 0,
- "roundrobin",
+ -1, -1, -1, -1,
+ NULL,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
link_watchers);
}
@@ -1193,11 +1192,11 @@ test_watcher_nsna_ping_sync_from_config (void)
link_watchers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref);
g_ptr_array_add (link_watchers, nm_team_link_watcher_new_nsna_ping (0, 0, 3, "target.host", NULL));
_test_team_config_sync ("{\"link_watch\": {\"name\": \"nsna_ping\", \"target_host\": \"target.host\"}}",
- 0, 0, 0, 0,
- "roundrobin",
+ -1, -1, -1, -1,
+ NULL,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
link_watchers);
}
@@ -1211,11 +1210,11 @@ test_watcher_arp_ping_sync_from_config (void)
nm_team_link_watcher_new_arp_ping (0, 0, 3, "target.host", "source.host", 0, NULL));
_test_team_config_sync ("{\"link_watch\": {\"name\": \"arp_ping\", \"target_host\": \"target.host\", "
"\"source_host\": \"source.host\"}}",
- 0, 0, 0, 0,
- "roundrobin",
+ -1, -1, -1, -1,
+ NULL,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
link_watchers);
}
@@ -1240,11 +1239,11 @@ test_multiple_watchers_sync_from_config (void)
"\"validate_active\": true, \"validate_inactive\": true, \"send_always\": true}, "
"{\"name\": \"nsna_ping\", \"init_wait\": 3, \"interval\": 6, \"missed_max\": 9, "
"\"target_host\": \"target.host\"}]}",
- 0, 0, 0, 0,
- "roundrobin",
+ -1, -1, -1, -1,
+ NULL,
NULL,
NULL, NULL, -1,
- FALSE, FALSE, -1, -1, NULL,
+ TRUE, FALSE, -1, -1, NULL,
link_watchers);
}
@@ -1300,52 +1299,52 @@ _test_team_port_config_sync (const char *team_port_config,
static void
test_team_port_default (void)
{
- _test_team_port_config_sync ("", -1, 0, FALSE, 255, 0, NULL);
+ _test_team_port_config_sync ("", -1, 0, FALSE, -1, -1, NULL);
}
static void
test_team_port_queue_id (void)
{
_test_team_port_config_sync ("{\"queue_id\": 3}",
- 3, 0, FALSE, 255, 0, NULL);
+ 3, 0, FALSE, -1, -1, NULL);
_test_team_port_config_sync ("{\"queue_id\": 0}",
- 0, 0, FALSE, 255, 0, NULL);
+ 0, 0, FALSE, -1, -1, NULL);
}
static void
test_team_port_prio (void)
{
_test_team_port_config_sync ("{\"prio\": 6}",
- -1, 6, FALSE, 255, 0, NULL);
+ -1, 6, FALSE, -1, -1, NULL);
_test_team_port_config_sync ("{\"prio\": 0}",
- -1, 0, FALSE, 255, 0, NULL);
+ -1, 0, FALSE, -1, -1, NULL);
}
static void
test_team_port_sticky (void)
{
_test_team_port_config_sync ("{\"sticky\": true}",
- -1, 0, TRUE, 255, 0, NULL);
+ -1, 0, TRUE, -1, -1, NULL);
_test_team_port_config_sync ("{\"sticky\": false}",
- -1, 0, FALSE, 255, 0, NULL);
+ -1, 0, FALSE, -1, -1, NULL);
}
static void
test_team_port_lacp_prio (void)
{
_test_team_port_config_sync ("{\"lacp_prio\": 9}",
- -1, 0, FALSE, 9, 0, NULL);
+ -1, 0, FALSE, 9, -1, NULL);
_test_team_port_config_sync ("{\"lacp_prio\": 0}",
- -1, 0, FALSE, 0, 0, NULL);
+ -1, 0, FALSE, 0, -1, NULL);
}
static void
test_team_port_lacp_key (void)
{
_test_team_port_config_sync ("{\"lacp_key\": 12}",
- -1, 0, FALSE, 255, 12, NULL);
+ -1, 0, FALSE, -1, 12, NULL);
_test_team_port_config_sync ("{\"lacp_key\": 0}",
- -1, 0, FALSE, 255, 0, NULL);
+ -1, 0, FALSE, -1, 0, NULL);
}
static void
@@ -1386,20 +1385,6 @@ _check_team_setting (NMSetting *setting)
g_assert (NM_IS_SETTING_TEAM (setting) || is_port);
- setting_clone = nm_setting_duplicate (setting);
-
- if (!is_port) {
- if (nm_setting_team_get_runner (NM_SETTING_TEAM (setting)) == NULL) {
- /* such a setting is invalid. We must first coerce it so that it becomes
- * valid. */
- setting = setting_clone;
- g_object_set (setting,
- NM_SETTING_TEAM_RUNNER,
- NM_SETTING_TEAM_RUNNER_DEFAULT,
- NULL);
- }
- }
-
setting2 = g_object_new (G_OBJECT_TYPE (setting),
is_port
? NM_SETTING_TEAM_PORT_CONFIG
@@ -1420,6 +1405,7 @@ _check_team_setting (NMSetting *setting)
* For that, we have to "drop" the JSON and we do that by resetting the property.
* This causes JSON to be regenerated and it's in a normalized form that will compare
* equal. */
+ setting_clone = nm_setting_duplicate (setting);
setting = setting_clone;
if (is_port) {
g_object_set (setting,
@@ -1499,6 +1485,12 @@ test_team_setting (void)
NULL);
_check_team_setting (setting);
g_assert_cmpstr (nm_setting_team_get_config (NM_SETTING_TEAM (setting)), ==, "{ \"runner\": { \"tx_balancer\": { \"balancing_interval\": 5 }, \"sys_prio\": 10 } }");
+
+ g_object_set (setting,
+ NM_SETTING_TEAM_CONFIG,
+ "{ \"runner\": { \"tx_hash\": [ \"eth\", \"l3\" ] } }",
+ NULL);
+ _check_team_setting (setting);
}
/*****************************************************************************/