From 4831edaa78a6772eb569ee1387ac1c7b671b26ed Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Thu, 26 Oct 2017 11:39:58 +0200 Subject: [PATCH 1/9] libnm-core: add functions to align team json config to exposed properties (cherry picked from commit dadf710ee370b928a1e3e4cd0c515eecc7bea108) --- libnm-core/nm-core-internal.h | 13 +- libnm-core/nm-utils.c | 311 ++++++++++++++++++++++++++++++++++ 2 files changed, 323 insertions(+), 1 deletion(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index f6b63712c7..8f4e110eb6 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -445,7 +445,18 @@ gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr); /*****************************************************************************/ -gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port); +gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port); +GValue *_nm_utils_team_config_get (const char *conf, + const char *key, + const char *key2, + const char *key3, + gboolean port_config); + +gboolean _nm_utils_team_config_set (char **conf, + const char *key, + const char *key2, + const char *key3, + const GValue *value); /*****************************************************************************/ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index d2301bbd41..c492d528da 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4301,6 +4301,25 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) /*****************************************************************************/ #if WITH_JANSSON + +/* Added in Jansson v2.4 (released Sep 23 2012), but travis.ci has v2.2. */ +#ifndef json_boolean +#define json_boolean(val) ((val) ? json_true() : json_false()) +#endif + +/* Added in Jansson v2.5 (released Sep 19 2013), but travis.ci has v2.2. */ +#ifndef json_array_foreach +#define json_array_foreach(array, index, value) \ + for (index = 0; \ + index < json_array_size(array) && (value = json_array_get(array, index)); \ + index++) +#endif + +/* Added in Jansson v2.7 */ +#ifndef json_boolean_value +#define json_boolean_value json_is_true +#endif + /** * nm_utils_is_json_object: * @str: the JSON string to test @@ -4446,6 +4465,278 @@ out: return ret; } + + +static void +_json_add_object (json_t *json, + const char *key1, + const char *key2, + const char *key3, + json_t *value) +{ + json_t *json_element, *json_link; + + json_element = json_object_get (json, key1); + if (!json_element) { + json_element = value; + if (key2) { + if (key3) { + json_element = json_object (); + json_object_set_new (json_element, key3, value); + } + json_link = json_object (); + json_object_set_new (json_link, key2, json_element); + json_element = json_link; + } + json_object_set_new (json, key1, json_element); + return; + } + + if (!key2) + goto key_already_there; + + json_link = json_element; + json_element = json_object_get (json_element, key2); + if (!json_element) { + json_element = value; + if (key3) { + json_element = json_object (); + json_object_set_new (json_element, key3, value); + } + json_object_set_new (json_link, key2, json_element); + return; + } + + if (!key3) + goto key_already_there; + + json_link = json_element; + json_element = json_object_get (json_element, key3); + if (!json_element) { + json_object_set_new (json_link, key3, value); + return; + } + +key_already_there: + json_decref (value); +} + +GValue * +_nm_utils_team_config_get (const char *conf, + const char *key, + const char *key2, + const char *key3, + gboolean port_config) +{ + json_t *json; + json_t *json_element; + GValue *value = NULL; + json_error_t jerror; + const char *runner = NULL; + + if (!key) + return NULL; + + json = json_loads (conf ?: "{}", JSON_REJECT_DUPLICATES, &jerror); + + /* Invalid json in conf */ + if (!json) + return NULL; + + /* Some properties are added by teamd when missing from the initial + * configuration. Add them with the default value if necessary, depending + * on the configuration type. + */ + if (port_config) { + _json_add_object (json, "link_watch", "name", NULL, json_string ("ethtool")); + } else { + /* Retrieve runner or add default one */ + json_element = json_object_get (json, "runner"); + if (json_element) { + runner = json_string_value (json_object_get (json_element, "name")); + } else { + json_element = json_object (); + json_object_set_new (json, "runner", json_element); + } + if (!runner) { + runner = "roundrobin"; + json_object_set_new (json_element, "name", json_string (runner)); + } + + + if (nm_streq (runner, "activebackup")) { + _json_add_object (json, "notify_peers", "count", NULL, json_integer (1)); + _json_add_object (json, "mcast_rejoin", "count", NULL, json_integer (1)); + _json_add_object (json, "runner", "hwaddr_policy", NULL, json_string ("same_all")); + } else if (nm_streq (runner, "loadbalance") || nm_streq (runner, "lacp")) { + json_element = json_array (); + json_array_append_new (json_element, json_string ("eth")); + json_array_append_new (json_element, json_string ("ipv4")); + json_array_append_new (json_element, json_string ("ipv6")); + _json_add_object (json, "runner", "tx_hash", NULL, json_element); + } + } + json_element = json_object_get (json, key); + if (json_element && key2) + json_element = json_object_get (json_element, key2); + if (json_element && key3) + json_element = json_object_get (json_element, key3); + + if (json_element) { + value = g_new0 (GValue, 1); + if (json_is_string (json_element)) { + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, json_string_value (json_element)); + } else if (json_is_integer (json_element)) { + g_value_init (value, G_TYPE_INT); + g_value_set_int (value, json_integer_value (json_element)); + } else if (json_is_boolean (json_element)) { + g_value_init (value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, json_boolean_value (json_element)); + } else if (json_is_array (json_element)) { + GPtrArray *data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); + json_t *str_element; + int index; + + json_array_foreach (json_element, index, str_element) { + if (json_is_string (str_element)) + g_ptr_array_add (data, g_strdup (json_string_value (str_element))); + } + if (data->len) { + g_value_init (value, G_TYPE_STRV); + g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (data)); + } + g_ptr_array_free (data, TRUE); + } else { + g_assert_not_reached (); + g_free (value); + value = NULL; + } + } + + if (json) + json_decref (json); + + return value; +} + +/* if conf is updated in place returns TRUE */ +gboolean +_nm_utils_team_config_set (char **conf, + const char *key, + const char *key2, + const char *key3, + const GValue *value) +{ + json_t *json, *json_element, *json_link, *json_value = NULL; + json_error_t jerror; + gboolean updated = FALSE; + char **strv; + const char *iter_key = key; + int i; + + json = json_loads (*conf?: "{}", JSON_REJECT_DUPLICATES, &jerror); + if (!json) + return FALSE; + + /* no new value? delete element */ + if (!value) { + json_element = json; + json_link = NULL; + + if (key2) { + json_link = json; + json_element = json_object_get (json, key); + if (!json_element) + goto done; + iter_key = key2; + } + if (key3) { + json_link = json_element; + json_element = json_object_get (json_element, key2); + if (!json_element) + goto done; + iter_key = key3; + } + if (json_object_del (json_element, iter_key) != 0) + goto done; + + updated = TRUE; + + /* 1st level key only */ + if (!json_link) + goto done; + + if (json_object_size (json_element) == 0) + json_object_del (json_link, (key3 ? key2 : key)); + + if (key3 && json_object_size (json_link) == 0) + json_object_del (json, key); + + goto done; + } + + /* insert new value */ + updated = TRUE; + if (G_VALUE_HOLDS_STRING (value)) + json_value = json_string (g_value_get_string (value)); + else if (G_VALUE_HOLDS_INT (value)) + json_value = json_integer (g_value_get_int (value)); + else if (G_VALUE_HOLDS_BOOLEAN (value)) + json_value = json_boolean (g_value_get_boolean (value)); + else if (G_VALUE_HOLDS_BOXED (value)) { + strv = g_value_get_boxed (value); + if (strv) { + json_value = json_array (); + for (i = 0; strv[i]; i++) + json_array_append_new (json_value, json_string (strv[i])); + } else + return FALSE; + } else { + g_assert_not_reached (); + updated = FALSE; + goto done; + } + + /* Simplest case: first level key only */ + json_element = json; + json_link = NULL; + + if (key2) { + json_link = json; + json_element = json_object_get (json, iter_key); + if (!json_element) { + json_element = json_object (); + json_object_set_new (json_link, iter_key, json_element); + } + iter_key = key2; + } + if (key3) { + json_link = json_element; + json_element = json_object_get (json_link, iter_key); + if (!json_element) { + json_element = json_object (); + json_object_set_new (json_link, iter_key, json_element); + } + iter_key = key3; + } + + json_object_set_new (json_element, iter_key, json_value); + +done: + if (updated) { + g_free (*conf); + *conf = json_dumps (json, 0); + /* Don't save an empty config */ + if (nm_streq0 (*conf, "{}")) { + g_free (*conf); + *conf = NULL; + } + } + json_decref (json); + return updated; +} + #else /* WITH_JANSSON */ gboolean @@ -4500,6 +4791,26 @@ _nm_utils_team_config_equal (const char *conf1, { return nm_streq0 (conf1, conf2); } + +GValue * +_nm_utils_team_config_get (const char *conf, + const char *key, + const char *key2, + const char *key3, + gboolean port_config) +{ + return NULL; +} + +gboolean +_nm_utils_team_config_set (char **conf, + const char *key, + const char *key2, + const char *key3, + const GValue *value) +{ + return FALSE; +} #endif static char * From 6812997c3868c52828a8c3a2226afc5f46d77ba7 Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Mon, 30 Oct 2017 15:04:52 +0100 Subject: [PATCH 2/9] libnm-core: add inline functions to update team json config Add functions and structure to simplify json config and team property enforcement. These will be used in both NMSettingTeam and NMSettingTeamPort. (cherry picked from commit b4c9bcd49f4b961b7065965bf69dfd5b43a27061) --- libnm-core/nm-utils-private.h | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index 03c8790764..aaf80363f5 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -78,4 +78,85 @@ void _nm_utils_bytes_from_dbus (GVariant *dbus_value, char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length); + +/* JSON to GValue conversion macros */ + +typedef struct { + const char *key1; + const char *key2; + const char *key3; +} _NMUtilsTeamPropertyKeys; + +static inline int +_nm_utils_json_extract_int (char *conf, + _NMUtilsTeamPropertyKeys key) +{ + gs_free GValue *t_value = NULL; + int ret; + + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + if (!t_value) + return 0; + + ret = g_value_get_int (t_value); + g_value_unset (t_value); + return ret; +} + +static inline gboolean +_nm_utils_json_extract_boolean (char *conf, + _NMUtilsTeamPropertyKeys key) +{ + gs_free GValue *t_value = NULL; + gboolean ret; + + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + if (!t_value) + return FALSE; + + ret = g_value_get_boolean (t_value); + g_value_unset (t_value); + return ret; +} + +static inline char * +_nm_utils_json_extract_string (char *conf, + _NMUtilsTeamPropertyKeys key) +{ + gs_free GValue *t_value = NULL; + char *ret; + + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + if (!t_value) + return NULL; + + ret = g_value_dup_string (t_value); + g_value_unset (t_value); + return ret; +} + +static inline char ** +_nm_utils_json_extract_strv (char *conf, + _NMUtilsTeamPropertyKeys key) +{ + gs_free GValue *t_value = NULL; + char **ret; + + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + if (!t_value) + return NULL; + + ret = g_strdupv (g_value_get_boxed (t_value)); + g_value_unset (t_value); + return ret; +} + +static inline void +_nm_utils_json_append_gvalue (char **conf, + _NMUtilsTeamPropertyKeys key, + const GValue *val) +{ + _nm_utils_team_config_set (conf, key.key1, key.key2, key.key3, val); +} + #endif From b42ad17e2de2d7e0eccf4bab767d6f5a10d418fd Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Thu, 12 Oct 2017 12:02:06 +0200 Subject: [PATCH 3/9] libnm-core: add explicit team properties to NMSettingTeam (cherry picked from commit 9715969b77300f47478b58482375dcd07dba1e85) --- clients/common/settings-docs.c.in | 14 + libnm-core/nm-setting-team.c | 656 ++++++++++++++++++++++++++++++ libnm-core/nm-setting-team.h | 59 ++- libnm/libnm.ver | 18 + 4 files changed, 745 insertions(+), 2 deletions(-) diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in index 3547c833a7..c83ed9c8d5 100644 --- a/clients/common/settings-docs.c.in +++ b/clients/common/settings-docs.c.in @@ -316,7 +316,21 @@ #define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.") #define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.") #define DESCRIBE_DOC_NM_SETTING_TEAM_CONFIG N_("The JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_COUNT N_("Corresponds to the teamd mcast_rejoin.count.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL N_("Corresponds to the teamd mcast_rejoin.interval.") #define DESCRIBE_DOC_NM_SETTING_TEAM_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_COUNT N_("Corresponds to the teamd notify_peers.count.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL N_("Corresponds to the teamd notify_peers.interval.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER N_("Corresponds to the teamd runner.name. Permitted values are: \"roundrobin\", \"broadcast\", \"activebackup\", \"loadbalance\", \"lacp\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_ACTIVE N_("Corresponds to the teamd runner.active.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY N_("Corresponds to the teamd runner.agg_select_policy.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_FAST_RATE N_("Corresponds to the teamd runner.fast_rate.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_HWADDR_POLICY N_("Corresponds to the teamd runner.hwaddr_policy.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_MIN_PORTS N_("Corresponds to the teamd runner.min_ports.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_SYS_PRIO N_("Corresponds to the teamd runner.sys_prio.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER N_("Corresponds to the teamd runner.tx_balancer.name.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL N_("Corresponds to the teamd runner.tx_balancer.interval.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_HASH N_("Corresponds to the teamd runner.tx_hash.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_CONFIG N_("The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") #define DESCRIBE_DOC_NM_SETTING_TUN_GROUP N_("The group ID which will own the device. If set to NULL everyone will be able to use the device.") diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 0a09c4a677..2126e4dbfe 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -44,11 +44,39 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM) typedef struct { char *config; + gint notify_peers_count; + gint notify_peers_interval; + gint mcast_rejoin_count; + gint mcast_rejoin_interval; + char *runner; + char *runner_hwaddr_policy; + GPtrArray *runner_tx_hash; + char *runner_tx_balancer; + gint runner_tx_balancer_interval; + gboolean runner_active; + gboolean runner_fast_rate; + gint runner_sys_prio; + gint runner_min_ports; + char *runner_agg_select_policy; } NMSettingTeamPrivate; enum { PROP_0, PROP_CONFIG, + PROP_NOTIFY_PEERS_COUNT, + PROP_NOTIFY_PEERS_INTERVAL, + PROP_MCAST_REJOIN_COUNT, + PROP_MCAST_REJOIN_INTERVAL, + PROP_RUNNER, + PROP_RUNNER_HWADDR_POLICY, + PROP_RUNNER_TX_HASH, + PROP_RUNNER_TX_BALANCER, + PROP_RUNNER_TX_BALANCER_INTERVAL, + PROP_RUNNER_ACTIVE, + PROP_RUNNER_FAST_RATE, + PROP_RUNNER_SYS_PRIO, + PROP_RUNNER_MIN_PORTS, + PROP_RUNNER_AGG_SELECT_POLICY, LAST_PROP }; @@ -79,6 +107,339 @@ nm_setting_team_get_config (NMSettingTeam *setting) return NM_SETTING_TEAM_GET_PRIVATE (setting)->config; } +/** + * nm_setting_team_get_notify_peers_count: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:notify-peers-count property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_notify_peers_count (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->notify_peers_count; +} + +/** + * nm_setting_team_get_notify_peers_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:notify-peers-interval property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_notify_peers_interval (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->notify_peers_interval; +} + +/** + * nm_setting_team_get_mcast_rejoin_count: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:mcast-rejoin-count property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_mcast_rejoin_count (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->mcast_rejoin_count; +} + +/** + * nm_setting_team_get_mcast_rejoin_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:mcast-rejoin-interval property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_mcast_rejoin_interval (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->mcast_rejoin_interval; +} + +/** + * nm_setting_team_get_runner: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner property of the setting + * + * Since: 1.10.2 + **/ +const char * +nm_setting_team_get_runner (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner; +} + +/** + * nm_setting_team_get_runner_hwaddr_policy: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-hwaddr-policy property of the setting + * + * Since: 1.10.2 + **/ +const char * +nm_setting_team_get_runner_hwaddr_policy (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_hwaddr_policy; +} + +/** + * nm_setting_team_get_runner_tx_balancer: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-tx-balancer property of the setting + * + * Since: 1.10.2 + **/ +const char * +nm_setting_team_get_runner_tx_balancer (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_tx_balancer; +} + +/** + * nm_setting_team_get_runner_tx_balancer_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-tx-balancer_interval property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_runner_tx_balancer_interval (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_tx_balancer_interval; +} + +/** + * nm_setting_team_get_runner_active: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner_active property of the setting + * + * Since: 1.10.2 + **/ +gboolean +nm_setting_team_get_runner_active (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_active; +} + +/** + * nm_setting_team_get_runner_fast_rate: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-fast-rate property of the setting + * + * Since: 1.10.2 + **/ +gboolean +nm_setting_team_get_runner_fast_rate (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_fast_rate; +} + +/** + * nm_setting_team_get_runner_sys_prio: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-sys-prio property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_runner_sys_prio (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_sys_prio; +} + +/** + * nm_setting_team_get_runner_min_ports: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-min-ports property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_get_runner_min_ports (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_min_ports; +} + +/** + * nm_setting_team_get_runner_agg_select_policy: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-agg-select-policy property of the setting + * + * Since: 1.10.2 + **/ +const char * +nm_setting_team_get_runner_agg_select_policy (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_agg_select_policy; +} + +/** + * nm_setting_team_remove_runner_tx_hash_by_value: + * @setting: the #NMSetetingTeam + * @txhash: the txhash element to remove + * + * Removes the txhash element #txhash + * + * Returns: %TRUE if the txhash element was found and removed; %FALSE if it was not. + * + * Since: 1.10.2 + **/ +gboolean +nm_setting_team_remove_runner_tx_hash_by_value (NMSettingTeam *setting, + const char *txhash) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + guint i; + + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE); + g_return_val_if_fail (txhash != NULL, FALSE); + g_return_val_if_fail (txhash[0] != '\0', FALSE); + + for (i = 0; i < priv->runner_tx_hash->len; i++) { + if (nm_streq (txhash, priv->runner_tx_hash->pdata[i])) { + g_ptr_array_remove_index (priv->runner_tx_hash, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_team_get_num_runner_tx_hash: + * @setting: the #NMSettingTeam + * + * Returns: the number of elements in txhash + * + * Since: 1.10.2 + **/ +guint +nm_setting_team_get_num_runner_tx_hash (NMSettingTeam *setting) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0); + + return priv->runner_tx_hash ? priv->runner_tx_hash->len : 0; +} + +/** + * nm_setting_team_get_runner_tx_hash + * @setting: the #NMSettingTeam + * @idx: index number of the txhash element to return + * + * Returns: the txhash element at index @idx + * + * Since: 1.10.2 + **/ +const char * +nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, int idx) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + g_return_val_if_fail (idx >= 0 && idx < priv->runner_tx_hash->len, NULL); + + return priv->runner_tx_hash->pdata[idx]; +} + +/** + * nm_setting_team_remove_runner_tx_hash: + * @setting: the #NMSettingTeam + * @idx: index number of the element to remove from txhash + * + * Removes the txhash element at index @idx. + * + * Since: 1.10.2 + **/ +void +nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, int idx) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + + g_return_if_fail (NM_IS_SETTING_TEAM (setting)); + g_return_if_fail (idx >= 0 && idx < priv->runner_tx_hash->len); + + g_ptr_array_remove_index (priv->runner_tx_hash, idx); + g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH); +} + +/** + * nm_setting_team_add_runner_tx_hash: + * @setting: the #NMSettingTeam + * @txhash: the element to add to txhash + * + * Adds a new txhash element to the setting. + * + * Returns: %TRUE if the txhash element was added; %FALSE if the element + * was already knnown. + * + * Since: 1.10.2 + **/ +gboolean +nm_setting_team_add_runner_tx_hash (NMSettingTeam *setting, const char *txhash) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + guint i; + + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE); + g_return_val_if_fail (txhash != NULL, FALSE); + g_return_val_if_fail (txhash[0] != '\0', FALSE); + + if (!priv->runner_tx_hash) + priv->runner_tx_hash = g_ptr_array_new_with_free_func (g_free); + for (i = 0; i < priv->runner_tx_hash->len; i++) { + if (nm_streq (txhash, priv->runner_tx_hash->pdata[i])) + return FALSE; + } + + g_ptr_array_add (priv->runner_tx_hash, g_strdup (txhash)); + g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH); + return TRUE; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -108,6 +469,19 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } + if ( priv->runner + && g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_BROADCAST) + && g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_ROUNDROBIN) + && g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP) + && g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE) + && g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_LACP)) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, + _("invalid runner \"%s\""), priv->runner); + + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_TEAM_RUNNER); + return FALSE; + } + /* NOTE: normalizable/normalizable-errors must appear at the end with decreasing severity. * Take care to properly order statements with priv->config above. */ @@ -142,6 +516,10 @@ compare_property (NMSetting *setting, static void nm_setting_team_init (NMSettingTeam *setting) { + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + + priv->runner = g_strdup (NM_SETTING_TEAM_RUNNER_ROUNDROBIN); + priv->runner_tx_hash = g_ptr_array_new_with_free_func (g_free); } static void @@ -150,6 +528,11 @@ finalize (GObject *object) NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object); g_free (priv->config); + g_free (priv->runner); + g_free (priv->runner_hwaddr_policy); + g_free (priv->runner_tx_balancer); + g_free (priv->runner_agg_select_policy); + g_ptr_array_unref (priv->runner_tx_hash); G_OBJECT_CLASS (nm_setting_team_parent_class)->finalize (object); } @@ -165,6 +548,36 @@ set_property (GObject *object, guint prop_id, g_free (priv->config); priv->config = g_value_dup_string (value); break; + case PROP_NOTIFY_PEERS_COUNT: + break; + case PROP_NOTIFY_PEERS_INTERVAL: + break; + case PROP_MCAST_REJOIN_COUNT: + break; + case PROP_MCAST_REJOIN_INTERVAL: + break; + case PROP_RUNNER: + g_free (priv->runner); + priv->runner = g_value_dup_string (value); + break; + case PROP_RUNNER_HWADDR_POLICY: + break; + case PROP_RUNNER_TX_HASH: + break; + case PROP_RUNNER_TX_BALANCER: + break; + case PROP_RUNNER_TX_BALANCER_INTERVAL: + break; + case PROP_RUNNER_ACTIVE: + break; + case PROP_RUNNER_FAST_RATE: + break; + case PROP_RUNNER_SYS_PRIO: + break; + case PROP_RUNNER_MIN_PORTS: + break; + case PROP_RUNNER_AGG_SELECT_POLICY: + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -176,11 +589,55 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingTeam *setting = NM_SETTING_TEAM (object); + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); switch (prop_id) { case PROP_CONFIG: g_value_set_string (value, nm_setting_team_get_config (setting)); break; + case PROP_NOTIFY_PEERS_COUNT: + g_value_set_int (value, priv->notify_peers_count); + break; + case PROP_NOTIFY_PEERS_INTERVAL: + g_value_set_int (value, priv->notify_peers_interval); + break; + case PROP_MCAST_REJOIN_COUNT: + g_value_set_int (value, priv->mcast_rejoin_count); + break; + case PROP_MCAST_REJOIN_INTERVAL: + g_value_set_int (value, priv->mcast_rejoin_interval); + break; + case PROP_RUNNER: + g_value_set_string (value, nm_setting_team_get_runner (setting)); + break; + case PROP_RUNNER_HWADDR_POLICY: + g_value_set_string (value, nm_setting_team_get_runner_hwaddr_policy (setting)); + break; + case PROP_RUNNER_TX_HASH: + g_value_take_boxed (value, priv->runner_tx_hash ? + _nm_utils_ptrarray_to_strv (priv->runner_tx_hash): NULL); + break; + case PROP_RUNNER_TX_BALANCER: + g_value_set_string (value, nm_setting_team_get_runner_tx_balancer (setting)); + break; + case PROP_RUNNER_TX_BALANCER_INTERVAL: + g_value_set_int (value, priv->runner_tx_balancer_interval); + break; + case PROP_RUNNER_ACTIVE: + g_value_set_boolean (value, nm_setting_team_get_runner_active (setting)); + break; + case PROP_RUNNER_FAST_RATE: + g_value_set_boolean (value, nm_setting_team_get_runner_fast_rate (setting)); + break; + case PROP_RUNNER_SYS_PRIO: + g_value_set_int (value, priv->runner_sys_prio); + break; + case PROP_RUNNER_MIN_PORTS: + g_value_set_int (value, priv->runner_min_ports); + break; + case PROP_RUNNER_AGG_SELECT_POLICY: + g_value_set_string (value, nm_setting_team_get_runner_agg_select_policy (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -225,6 +682,205 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingTeam:notify-peers-count: + * + * Corresponds to the teamd notify_peers.count. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_NOTIFY_PEERS_COUNT, + g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:notify-peers-interval: + * + * Corresponds to the teamd notify_peers.interval. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_NOTIFY_PEERS_INTERVAL, + g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:mcast-rejoin-count: + * + * Corresponds to the teamd mcast_rejoin.count. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_MCAST_REJOIN_COUNT, + g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_COUNT, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:mcast-rejoin-interval: + * + * Corresponds to the teamd mcast_rejoin.interval. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_MCAST_REJOIN_INTERVAL, + g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner: + * + * Corresponds to the teamd runner.name. + * Permitted values are: "roundrobin", "broadcast", "activebackup", + * "loadbalance", "lacp". + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER, + g_param_spec_string (NM_SETTING_TEAM_RUNNER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-hwaddr-policy: + * + * Corresponds to the teamd runner.hwaddr_policy. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_HWADDR_POLICY, + g_param_spec_string (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-tx-hash: + * + * Corresponds to the teamd runner.tx_hash. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_TX_HASH, + g_param_spec_boxed (NM_SETTING_TEAM_RUNNER_TX_HASH, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-tx-balancer: + * + * Corresponds to the teamd runner.tx_balancer.name. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_TX_BALANCER, + g_param_spec_string (NM_SETTING_TEAM_RUNNER_TX_BALANCER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-tx-balancer-interval: + * + * Corresponds to the teamd runner.tx_balancer.interval. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_TX_BALANCER_INTERVAL, + g_param_spec_int (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-active: + * + * Corresponds to the teamd runner.active. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_ACTIVE, + g_param_spec_boolean (NM_SETTING_TEAM_RUNNER_ACTIVE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-fast-rate: + * + * Corresponds to the teamd runner.fast_rate. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_FAST_RATE, + g_param_spec_boolean (NM_SETTING_TEAM_RUNNER_FAST_RATE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-sys-prio: + * + * Corresponds to the teamd runner.sys_prio. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_SYS_PRIO, + g_param_spec_int (NM_SETTING_TEAM_RUNNER_SYS_PRIO, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-min-ports: + * + * Corresponds to the teamd runner.min_ports. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_MIN_PORTS, + g_param_spec_int (NM_SETTING_TEAM_RUNNER_MIN_PORTS, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeam:runner-agg-select-policy: + * + * Corresponds to the teamd runner.agg_select_policy. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_RUNNER_AGG_SELECT_POLICY, + g_param_spec_string (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* ---dbus--- * property: interface-name * format: string diff --git a/libnm-core/nm-setting-team.h b/libnm-core/nm-setting-team.h index 532963aacb..a86f3f86fa 100644 --- a/libnm-core/nm-setting-team.h +++ b/libnm-core/nm-setting-team.h @@ -38,7 +38,27 @@ G_BEGIN_DECLS #define NM_SETTING_TEAM_SETTING_NAME "team" -#define NM_SETTING_TEAM_CONFIG "config" +#define NM_SETTING_TEAM_CONFIG "config" +#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT "notify-peers-count" +#define NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL "notify-peers-interval" +#define NM_SETTING_TEAM_MCAST_REJOIN_COUNT "mcast-rejoin-count" +#define NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL "mcast-rejoin-interval" +#define NM_SETTING_TEAM_RUNNER "runner" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY "runner-hwaddr-policy" +#define NM_SETTING_TEAM_RUNNER_TX_HASH "runner-tx-hash" +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER "runner-tx-balancer" +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL "runner-tx-balancer-interval" +#define NM_SETTING_TEAM_RUNNER_ACTIVE "runner-active" +#define NM_SETTING_TEAM_RUNNER_FAST_RATE "runner-fast-rate" +#define NM_SETTING_TEAM_RUNNER_SYS_PRIO "runner-sys-prio" +#define NM_SETTING_TEAM_RUNNER_MIN_PORTS "runner-min-ports" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY "runner-agg-select-policy" + +#define NM_SETTING_TEAM_RUNNER_BROADCAST "broadcast" +#define NM_SETTING_TEAM_RUNNER_ROUNDROBIN "roundrobin" +#define NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP "activebackup" +#define NM_SETTING_TEAM_RUNNER_LOADBALANCE "loadbalance" +#define NM_SETTING_TEAM_RUNNER_LACP "lacp" /** * NMSettingTeam: @@ -61,7 +81,42 @@ GType nm_setting_team_get_type (void); NMSetting * nm_setting_team_new (void); const char * nm_setting_team_get_config (NMSettingTeam *setting); - +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_notify_peers_count (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_notify_peers_interval (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_mcast_rejoin_count (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_mcast_rejoin_interval (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +const char * nm_setting_team_get_runner (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +const char * nm_setting_team_get_runner_hwaddr_policy (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +const char * nm_setting_team_get_runner_tx_balancer (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_runner_tx_balancer_interval (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_setting_team_get_runner_active (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_setting_team_get_runner_fast_rate (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_runner_sys_prio (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_get_runner_min_ports (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +const char * nm_setting_team_get_runner_agg_select_policy (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_setting_team_remove_runner_tx_hash_by_value (NMSettingTeam *setting, const char *txhash); +NM_AVAILABLE_IN_1_10_2 +guint nm_setting_team_get_num_runner_tx_hash (NMSettingTeam *setting); +NM_AVAILABLE_IN_1_10_2 +const char *nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, int idx); +NM_AVAILABLE_IN_1_10_2 +void nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, int idx); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_setting_team_add_runner_tx_hash (NMSettingTeam *setting, const char *txhash); G_END_DECLS #endif /* __NM_SETTING_TEAM_H__ */ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 83c838cbc4..389889a3e1 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1226,5 +1226,23 @@ libnm_1_10_2 { global: nm_remote_connection_update2; nm_remote_connection_update2_finish; + nm_setting_team_add_runner_tx_hash; + nm_setting_team_get_mcast_rejoin_count; + nm_setting_team_get_mcast_rejoin_interval; + nm_setting_team_get_notify_peers_count; + nm_setting_team_get_notify_peers_interval; + nm_setting_team_get_num_runner_tx_hash; + nm_setting_team_get_runner; + nm_setting_team_get_runner_hwaddr_policy; + nm_setting_team_get_runner_tx_balancer; + nm_setting_team_get_runner_tx_balancer_interval; + nm_setting_team_get_runner_tx_hash; + nm_setting_team_get_runner_active; + nm_setting_team_get_runner_fast_rate; + nm_setting_team_get_runner_sys_prio; + nm_setting_team_get_runner_min_ports; + nm_setting_team_get_runner_agg_select_policy; + nm_setting_team_remove_runner_tx_hash; + nm_setting_team_remove_runner_tx_hash_by_value; nm_settings_update2_flags_get_type; } libnm_1_10_0; From 4926ca42e7b57f435259ef5146a09bc1856d494b Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Fri, 20 Oct 2017 11:55:29 +0200 Subject: [PATCH 4/9] libnm-core: enforce team config and properties alignment Ensure .config is aligned when an explicit team property is set and vice versa. (cherry picked from commit fc3b7d61e29a56106a0ecb55deb7fcdcf7d9b691) --- libnm-core/nm-setting-team.c | 161 ++++++++++++++++++++++++++++++++++- libnm-core/nm-setting-team.h | 10 +++ 2 files changed, 169 insertions(+), 2 deletions(-) diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 2126e4dbfe..499ca459ff 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -60,6 +60,7 @@ typedef struct { char *runner_agg_select_policy; } NMSettingTeamPrivate; +/* Keep aligned with _prop_to_keys[] */ enum { PROP_0, PROP_CONFIG, @@ -80,6 +81,26 @@ enum { LAST_PROP }; +/* Keep aligned with team properties enum */ +static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = { + [PROP_0] = { NULL, NULL, NULL }, + [PROP_CONFIG] = { NULL, NULL, NULL }, + [PROP_NOTIFY_PEERS_COUNT] = { "notify_peers", "count", NULL }, + [PROP_NOTIFY_PEERS_INTERVAL] = { "notify_peers", "interval", NULL }, + [PROP_MCAST_REJOIN_COUNT] = { "mcast_rejoin", "count", NULL }, + [PROP_MCAST_REJOIN_INTERVAL] = { "mcast_rejoin", "interval", NULL }, + [PROP_RUNNER] = { "runner", "name", NULL }, + [PROP_RUNNER_HWADDR_POLICY] = { "runner", "hwaddr_policy", NULL }, + [PROP_RUNNER_TX_HASH] = { "runner", "tx_hash", NULL }, + [PROP_RUNNER_TX_BALANCER] = { "runner", "tx_balancer", "name" }, + [PROP_RUNNER_TX_BALANCER_INTERVAL] = { "runner", "tx_balancer", "interval" }, + [PROP_RUNNER_ACTIVE] = { "runner", "active", NULL }, + [PROP_RUNNER_FAST_RATE] = { "runner", "fast_rate", NULL }, + [PROP_RUNNER_SYS_PRIO] = { "runner", "sys_prio", NULL }, + [PROP_RUNNER_MIN_PORTS] = { "runner", "min_ports", NULL }, + [PROP_RUNNER_AGG_SELECT_POLICY] = { "runner", "agg_select_policy", NULL }, +}; + /** * nm_setting_team_new: * @@ -519,7 +540,6 @@ nm_setting_team_init (NMSettingTeam *setting) NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); priv->runner = g_strdup (NM_SETTING_TEAM_RUNNER_ROUNDROBIN); - priv->runner_tx_hash = g_ptr_array_new_with_free_func (g_free); } static void @@ -532,56 +552,193 @@ finalize (GObject *object) g_free (priv->runner_hwaddr_policy); g_free (priv->runner_tx_balancer); g_free (priv->runner_agg_select_policy); - g_ptr_array_unref (priv->runner_tx_hash); + if (priv->runner_tx_hash) + g_ptr_array_unref (priv->runner_tx_hash); G_OBJECT_CLASS (nm_setting_team_parent_class)->finalize (object); } + +#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id]) + +static void +_align_team_properties (NMSettingTeam *setting) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); + char **strv; + int i; + + priv->notify_peers_count = JSON_TO_VAL (int, PROP_NOTIFY_PEERS_COUNT); + priv->notify_peers_interval = JSON_TO_VAL (int, PROP_NOTIFY_PEERS_INTERVAL); + priv->mcast_rejoin_count = JSON_TO_VAL (int, PROP_MCAST_REJOIN_COUNT); + priv->mcast_rejoin_interval = JSON_TO_VAL (int, PROP_MCAST_REJOIN_INTERVAL); + priv->runner_tx_balancer_interval = JSON_TO_VAL (int, PROP_RUNNER_TX_BALANCER_INTERVAL); + priv->runner_sys_prio = JSON_TO_VAL (int, PROP_RUNNER_SYS_PRIO); + priv->runner_min_ports = JSON_TO_VAL (int, PROP_RUNNER_MIN_PORTS); + + priv->runner_active = JSON_TO_VAL (boolean, PROP_RUNNER_ACTIVE); + priv->runner_fast_rate = JSON_TO_VAL (boolean, PROP_RUNNER_FAST_RATE); + + g_free (priv->runner); + g_free (priv->runner_hwaddr_policy); + g_free (priv->runner_tx_balancer); + g_free (priv->runner_agg_select_policy); + priv->runner = JSON_TO_VAL (string, PROP_RUNNER); + priv->runner_hwaddr_policy = JSON_TO_VAL (string, PROP_RUNNER_HWADDR_POLICY); + priv->runner_tx_balancer = JSON_TO_VAL (string, PROP_RUNNER_TX_BALANCER); + priv->runner_agg_select_policy = JSON_TO_VAL (string, PROP_RUNNER_AGG_SELECT_POLICY); + + if (priv->runner_tx_hash) { + g_ptr_array_unref (priv->runner_tx_hash); + priv->runner_tx_hash = NULL; + } + strv = JSON_TO_VAL (strv, PROP_RUNNER_TX_HASH); + if (strv) { + for (i = 0; strv[i]; i++) + nm_setting_team_add_runner_tx_hash (setting, strv[i]); + g_strfreev (strv); + } +} + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { + NMSettingTeam *setting = NM_SETTING_TEAM (object); NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object); + const GValue *align_value = NULL; + gboolean align_config = FALSE; + char **strv; switch (prop_id) { case PROP_CONFIG: g_free (priv->config); priv->config = g_value_dup_string (value); + _align_team_properties (setting); break; case PROP_NOTIFY_PEERS_COUNT: + if (priv->notify_peers_count == g_value_get_int (value)) + break; + priv->notify_peers_count = g_value_get_int (value); + if (priv->notify_peers_count) + align_value = value; + align_config = TRUE; break; case PROP_NOTIFY_PEERS_INTERVAL: + if (priv->notify_peers_interval == g_value_get_int (value)) + break; + priv->notify_peers_interval = g_value_get_int (value); + if (priv->notify_peers_interval) + align_value = value; + align_config = TRUE; break; case PROP_MCAST_REJOIN_COUNT: + if (priv->mcast_rejoin_count == g_value_get_int (value)) + break; + priv->mcast_rejoin_count = g_value_get_int (value); + if (priv->mcast_rejoin_count) + align_value = value; + align_config = TRUE; break; case PROP_MCAST_REJOIN_INTERVAL: + if (priv->mcast_rejoin_interval == g_value_get_int (value)) + break; + priv->mcast_rejoin_interval = g_value_get_int (value); + if (priv->mcast_rejoin_interval) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER: g_free (priv->runner); priv->runner = g_value_dup_string (value); + if (priv->runner && !nm_streq (priv->runner, "roundrobin")) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_HWADDR_POLICY: + g_free (priv->runner_hwaddr_policy); + priv->runner_hwaddr_policy = g_value_dup_string (value); + if ( priv->runner_hwaddr_policy + && !nm_streq (priv->runner_hwaddr_policy, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL)) { + align_value = value; + } + align_config = TRUE; break; case PROP_RUNNER_TX_HASH: + if (priv->runner_tx_hash) + g_ptr_array_unref (priv->runner_tx_hash); + strv = g_value_get_boxed (value); + if (strv && strv[0]) { + priv->runner_tx_hash = _nm_utils_strv_to_ptrarray (strv); + align_value = value; + } else + priv->runner_tx_hash = NULL; + align_config = TRUE; break; case PROP_RUNNER_TX_BALANCER: + g_free (priv->runner_tx_balancer); + priv->runner_tx_balancer = g_value_dup_string (value); + if (priv->runner_tx_balancer) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_TX_BALANCER_INTERVAL: + if (priv->runner_tx_balancer_interval == g_value_get_int (value)) + break; + priv->runner_tx_balancer_interval = g_value_get_int (value); + if (priv->runner_tx_balancer_interval) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_ACTIVE: + if (priv->runner_active == g_value_get_boolean (value)) + break; + priv->runner_active = g_value_get_boolean (value); + if (priv->runner_active) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_FAST_RATE: + if (priv->runner_fast_rate == g_value_get_boolean (value)) + break; + priv->runner_fast_rate = g_value_get_boolean (value); + if (priv->runner_fast_rate) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_SYS_PRIO: + if (priv->runner_sys_prio == g_value_get_int (value)) + break; + priv->runner_sys_prio = g_value_get_int (value); + if (priv->runner_sys_prio) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_MIN_PORTS: + if (priv->runner_min_ports == g_value_get_int (value)) + break; + priv->runner_min_ports = g_value_get_int (value); + if (priv->runner_min_ports) + align_value = value; + align_config = TRUE; break; case PROP_RUNNER_AGG_SELECT_POLICY: + g_free (priv->runner_agg_select_policy); + priv->runner_agg_select_policy = g_value_dup_string (value); + if ( priv->runner_agg_select_policy + && !nm_streq (priv->runner_agg_select_policy, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO)) + align_value = value; + align_config = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + + if (align_config) + _nm_utils_json_append_gvalue (&priv->config, _prop_to_keys[prop_id], align_value); } static void diff --git a/libnm-core/nm-setting-team.h b/libnm-core/nm-setting-team.h index a86f3f86fa..992709c30b 100644 --- a/libnm-core/nm-setting-team.h +++ b/libnm-core/nm-setting-team.h @@ -60,6 +60,16 @@ G_BEGIN_DECLS #define NM_SETTING_TEAM_RUNNER_LOADBALANCE "loadbalance" #define NM_SETTING_TEAM_RUNNER_LACP "lacp" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL "same_all" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE "by_active" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE "only_active" + +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO "lacp_prio" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE "lacp_prio_stable" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH "bandwidth" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT "count" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG "port_config" + /** * NMSettingTeam: * From 316a6ea3bea9d6d8136a520724a3cd0c8cecf9e4 Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Thu, 12 Oct 2017 18:08:08 +0200 Subject: [PATCH 5/9] cli: add team properties (cherry picked from commit e1220c933f84a457c16f4b21ccdacd335d2755c4) --- clients/common/nm-meta-setting-desc.c | 179 ++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index c6c018b2ec..51c04486fa 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -461,6 +461,7 @@ _get_text_hidden (NMMetaAccessorGetType get_type) return NM_META_TEXT_HIDDEN; } + /*****************************************************************************/ G_GNUC_PRINTF (4, 5) @@ -3652,6 +3653,60 @@ _validate_fcn_team_config (const char *value, char **out_to_free, GError **error RETURN_STR_TO_FREE (json); } +static gboolean +_is_valid_team_runner_tx_hash_element (const char *tx_hash_element) +{ + const char *valid_tx_hashes[] = { "eth", "vlan", "ipv4", "ipv6", "ip", + "l3", "tcp", "udp", "sctp", "l4", NULL }; + if (nmc_string_is_valid (tx_hash_element, valid_tx_hashes, NULL)) + return TRUE; + return FALSE; +} + +static gboolean +_set_fcn_team_runner_tx_hash (ARGS_SET_FCN) +{ + char **strv = NULL; + guint i = 0; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + strv = _nm_utils_strv_cleanup (g_strsplit_set (value, " \t,", 0), + TRUE, TRUE, TRUE); + if (!verify_string_list (strv, property_info->property_name, + _is_valid_team_runner_tx_hash_element, + error)) { + g_strfreev (strv); + return FALSE; + } + + while (strv && strv[i]) + nm_setting_team_add_runner_tx_hash (NM_SETTING_TEAM (setting), strv[i++]); + g_strfreev (strv); + + return TRUE; +} + +static gboolean +_validate_and_remove_team_runner_tx_hash (NMSettingTeam *setting, + const char *tx_hash, + GError **error) +{ + if (!nm_setting_team_remove_runner_tx_hash_by_value (setting, tx_hash)) { + g_set_error (error, 1, 0, + _("the property doesn't contain string '%s'"), + tx_hash); + return FALSE; + } + + return TRUE; +} +DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_runner_tx_hash, + NM_SETTING_TEAM, + nm_setting_team_get_num_runner_tx_hash, + nm_setting_team_remove_runner_tx_hash, + _validate_and_remove_team_runner_tx_hash) + static gconstpointer _get_fcn_vlan_flags (ARGS_GET_FCN) { @@ -6010,6 +6065,130 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .validate_fcn = _validate_fcn_team_config, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "disabled", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_COUNT, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "disabled", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_BROADCAST, + NM_SETTING_TEAM_RUNNER_ROUNDROBIN, + NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NM_SETTING_TEAM_RUNNER_LACP), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_HASH, + .property_type = DEFINE_PROPERTY_TYPE ( + .get_fcn = _get_fcn_gobject, + .set_fcn = _set_fcn_team_runner_tx_hash, + .remove_fcn = _remove_fcn_team_runner_tx_hash, + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC ("basic"), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 50, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_ACTIVE, + .property_type = & _pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_FAST_RATE, + .property_type = & _pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_SYS_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 255, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_MIN_PORTS, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG), + ), + ), NULL }; From 7d9553da5003972816b1a105865dba988178d133 Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Mon, 30 Oct 2017 12:27:58 +0100 Subject: [PATCH 6/9] libnm-core: add explicit team properties to NMSettingTeamPort (cherry picked from commit 1c99d379eb7ef1947beb4176a9611e404d1b220f) --- clients/common/settings-docs.c.in | 5 + libnm-core/nm-setting-team-port.c | 198 ++++++++++++++++++++++++++++++ libnm-core/nm-setting-team-port.h | 15 +++ libnm/libnm.ver | 5 + 4 files changed, 223 insertions(+) diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in index c83ed9c8d5..3d6f012bf7 100644 --- a/clients/common/settings-docs.c.in +++ b/clients/common/settings-docs.c.in @@ -332,7 +332,12 @@ #define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL N_("Corresponds to the teamd runner.tx_balancer.interval.") #define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_HASH N_("Corresponds to the teamd runner.tx_hash.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_CONFIG N_("The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_KEY N_("Corresponds to the teamd ports.PORTIFNAME.lacp_key.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.lacp_prio.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.prio.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_QUEUE_ID N_("Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_STICKY N_("Corresponds to the teamd ports.PORTIFNAME.sticky.") #define DESCRIBE_DOC_NM_SETTING_TUN_GROUP N_("The group ID which will own the device. If set to NULL everyone will be able to use the device.") #define DESCRIBE_DOC_NM_SETTING_TUN_MODE N_("The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.") #define DESCRIBE_DOC_NM_SETTING_TUN_MULTI_QUEUE N_("If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.") diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index c030966579..c29444c489 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -47,11 +47,21 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM_PORT) typedef struct { char *config; + int queue_id; + int prio; + gboolean sticky; + int lacp_prio; + int lacp_key; } NMSettingTeamPortPrivate; enum { PROP_0, PROP_CONFIG, + PROP_QUEUE_ID, + PROP_PRIO, + PROP_STICKY, + PROP_LACP_PRIO, + PROP_LACP_KEY, LAST_PROP }; @@ -82,6 +92,86 @@ nm_setting_team_port_get_config (NMSettingTeamPort *setting) return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->config; } +/** + * nm_setting_team_port_get_queue_id: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:queue_id property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_port_get_queue_id (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), -1); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->queue_id; +} + +/** + * nm_setting_team_port_get_prio: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:prio property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_port_get_prio (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->prio; +} + +/** + * nm_setting_team_port_get_sticky: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:sticky property of the setting + * + * Since: 1.10.2 + **/ +gboolean +nm_setting_team_port_get_sticky (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), FALSE); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->sticky; +} + +/** + * nm_setting_team_port_get_lacp_prio: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:lacp-prio property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_port_get_lacp_prio (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->lacp_prio; +} + +/** + * nm_setting_team_port_get_lacp_key: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:lacp-key property of the setting + * + * Since: 1.10.2 + **/ +gint +nm_setting_team_port_get_lacp_key (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->lacp_key; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -171,6 +261,10 @@ compare_property (NMSetting *setting, static void nm_setting_team_port_init (NMSettingTeamPort *setting) { + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting); + + priv->queue_id = -1; + priv->lacp_prio = 255; } static void @@ -184,6 +278,21 @@ set_property (GObject *object, guint prop_id, g_free (priv->config); priv->config = g_value_dup_string (value); break; + case PROP_QUEUE_ID: + priv->queue_id = g_value_get_int (value); + break; + case PROP_PRIO: + priv->prio = g_value_get_int (value); + break; + case PROP_STICKY: + priv->sticky = g_value_get_boolean (value); + break; + case PROP_LACP_PRIO: + priv->lacp_prio = g_value_get_int (value); + break; + case PROP_LACP_KEY: + priv->lacp_key = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -195,11 +304,27 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingTeamPort *setting = NM_SETTING_TEAM_PORT (object); + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting); switch (prop_id) { case PROP_CONFIG: g_value_set_string (value, nm_setting_team_port_get_config (setting)); break; + case PROP_QUEUE_ID: + g_value_set_int (value, priv->queue_id); + break; + case PROP_PRIO: + g_value_set_int (value, priv->prio); + break; + case PROP_STICKY: + g_value_set_boolean (value, priv->sticky); + break; + case PROP_LACP_PRIO: + g_value_set_int (value, priv->lacp_prio); + break; + case PROP_LACP_KEY: + g_value_set_int (value, priv->lacp_key); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -253,4 +378,77 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeamPort:queue-id: + * + * Corresponds to the teamd ports.PORTIFNAME.queue_id. + * When set to -1 means the parameter is skipped from the json config. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_QUEUE_ID, + g_param_spec_int (NM_SETTING_TEAM_PORT_QUEUE_ID, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeamPort:prio: + * + * Corresponds to the teamd ports.PORTIFNAME.prio. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_PRIO, + g_param_spec_int (NM_SETTING_TEAM_PORT_PRIO, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeamPort:sticky: + * + * Corresponds to the teamd ports.PORTIFNAME.sticky. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_STICKY, + g_param_spec_boolean (NM_SETTING_TEAM_PORT_STICKY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeamPort:lacp-prio: + * + * Corresponds to the teamd ports.PORTIFNAME.lacp_prio. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_LACP_PRIO, + g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_PRIO, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingTeamPort:lacp-key: + * + * Corresponds to the teamd ports.PORTIFNAME.lacp_key. + * + * Since: 1.10.2 + **/ + g_object_class_install_property + (object_class, PROP_LACP_KEY, + g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_KEY, "", "", + G_MININT32, G_MAXINT32, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + } diff --git a/libnm-core/nm-setting-team-port.h b/libnm-core/nm-setting-team-port.h index 4fcc51083a..1b69bf73b4 100644 --- a/libnm-core/nm-setting-team-port.h +++ b/libnm-core/nm-setting-team-port.h @@ -39,6 +39,11 @@ G_BEGIN_DECLS #define NM_SETTING_TEAM_PORT_SETTING_NAME "team-port" #define NM_SETTING_TEAM_PORT_CONFIG "config" +#define NM_SETTING_TEAM_PORT_QUEUE_ID "queue-id" +#define NM_SETTING_TEAM_PORT_PRIO "prio" +#define NM_SETTING_TEAM_PORT_STICKY "sticky" +#define NM_SETTING_TEAM_PORT_LACP_PRIO "lacp-prio" +#define NM_SETTING_TEAM_PORT_LACP_KEY "lacp-key" /** * NMSettingTeamPort: @@ -61,6 +66,16 @@ GType nm_setting_team_port_get_type (void); NMSetting * nm_setting_team_port_new (void); const char * nm_setting_team_port_get_config (NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_port_get_queue_id (NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_port_get_prio (NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_setting_team_port_get_sticky (NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_port_get_lacp_prio (NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_10_2 +gint nm_setting_team_port_get_lacp_key (NMSettingTeamPort *setting); G_END_DECLS diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 389889a3e1..ad9615430b 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1242,6 +1242,11 @@ global: nm_setting_team_get_runner_sys_prio; nm_setting_team_get_runner_min_ports; nm_setting_team_get_runner_agg_select_policy; + nm_setting_team_port_get_queue_id; + nm_setting_team_port_get_prio; + nm_setting_team_port_get_sticky; + nm_setting_team_port_get_lacp_prio; + nm_setting_team_port_get_lacp_key; nm_setting_team_remove_runner_tx_hash; nm_setting_team_remove_runner_tx_hash_by_value; nm_settings_update2_flags_get_type; From 8b171fd8aefa19f39a6f8f4ffa0b0715d2bdd5fa Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Mon, 30 Oct 2017 16:24:04 +0100 Subject: [PATCH 7/9] libnm-core: enforce team-port config and properties alignment Ensure .config is aligned when an explicit team-port is set and vice versa (cherry picked from commit ec60e01d39e7477e4d19aa24d7832b368b7ee125) --- libnm-core/nm-setting-team-port.c | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index c29444c489..a069eee240 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -54,6 +54,7 @@ typedef struct { int lacp_key; } NMSettingTeamPortPrivate; +/* Keep aligned with _prop_to_keys[] */ enum { PROP_0, PROP_CONFIG, @@ -65,6 +66,18 @@ enum { LAST_PROP }; +/* Keep aligned with team-port properties enum */ +static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = { + [PROP_0] = { NULL, NULL, NULL }, + [PROP_CONFIG] = { NULL, NULL, NULL }, + [PROP_QUEUE_ID] = { "queue_id", NULL, NULL }, + [PROP_PRIO] = { "prio", NULL, NULL }, + [PROP_STICKY] = { "sticky", NULL, NULL }, + [PROP_LACP_PRIO] = { "lacp_prio", NULL, NULL }, + [PROP_LACP_KEY] = { "lacp_key", NULL, NULL }, +}; + + /** * nm_setting_team_port_new: * @@ -267,36 +280,73 @@ nm_setting_team_port_init (NMSettingTeamPort *setting) priv->lacp_prio = 255; } +#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id]) + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (object); + const GValue *align_value = NULL; + gboolean align_config = FALSE; switch (prop_id) { case PROP_CONFIG: g_free (priv->config); priv->config = g_value_dup_string (value); + priv->queue_id = JSON_TO_VAL (int, PROP_QUEUE_ID); + priv->prio = JSON_TO_VAL (int, PROP_PRIO); + priv->sticky = JSON_TO_VAL (boolean, PROP_STICKY); + priv->lacp_prio = JSON_TO_VAL (int, PROP_LACP_PRIO); + priv->lacp_key = JSON_TO_VAL (int, PROP_LACP_KEY); break; case PROP_QUEUE_ID: + if (priv->queue_id == g_value_get_int (value)) + break; priv->queue_id = g_value_get_int (value); + if (priv->queue_id > -1) + align_value = value; + align_config = TRUE; break; case PROP_PRIO: + if (priv->prio == g_value_get_int (value)) + break; priv->prio = g_value_get_int (value); + if (priv->prio) + align_value = value; + align_config = TRUE; break; case PROP_STICKY: + if (priv->sticky == g_value_get_boolean (value)) + break; priv->sticky = g_value_get_boolean (value); + if (priv->sticky) + align_value = value; + align_config = TRUE; break; case PROP_LACP_PRIO: + if (priv->lacp_prio == g_value_get_int (value)) + break; priv->lacp_prio = g_value_get_int (value); + /* from libteam sources: lacp_prio default value is 0xff */ + if (priv->lacp_prio != 255) + align_value = value; + align_config = TRUE; break; case PROP_LACP_KEY: + if (priv->lacp_key == g_value_get_int (value)) + break; priv->lacp_key = g_value_get_int (value); + if (priv->lacp_key > 0) + align_value = value; + align_config = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + if (align_config) + _nm_utils_json_append_gvalue (&priv->config, _prop_to_keys[prop_id], align_value); } static void From 5b9f4202d619454dd0df2e7836cfba7e1e9e11aa Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Mon, 30 Oct 2017 17:33:03 +0100 Subject: [PATCH 8/9] cli: add team-port properties (cherry picked from commit 81527f1a092b97499ed924e583e1576433a7aa4e) --- clients/common/nm-meta-setting-desc.c | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 51c04486fa..9467719811 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -6205,6 +6205,53 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .validate_fcn = _validate_fcn_team_config, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_QUEUE_ID, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = -1, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_STICKY, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 255, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_KEY, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), NULL }; From 921635d3aed0b38869ae06157721f25e304ab3ea Mon Sep 17 00:00:00 2001 From: Francesco Giudici Date: Wed, 8 Nov 2017 18:10:27 +0100 Subject: [PATCH 9/9] libnm-core: enforce team and team-port defaults Rework a bit the way default values are check, set and aligned. (cherry picked from commit 3e34e404b475cd44fea7448e9b2b5176de709ef8) --- libnm-core/nm-setting-team-port.c | 26 ++++++++-------- libnm-core/nm-setting-team-port.h | 3 ++ libnm-core/nm-setting-team.c | 49 ++++++++++++++++++------------- libnm-core/nm-setting-team.h | 8 +++++ libnm-core/nm-utils-private.h | 31 ++++++++++++------- libnm-core/nm-utils.c | 14 +++++---- 6 files changed, 81 insertions(+), 50 deletions(-) diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index a069eee240..f97920dc38 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -68,13 +68,13 @@ enum { /* Keep aligned with team-port properties enum */ static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = { - [PROP_0] = { NULL, NULL, NULL }, - [PROP_CONFIG] = { NULL, NULL, NULL }, - [PROP_QUEUE_ID] = { "queue_id", NULL, NULL }, - [PROP_PRIO] = { "prio", NULL, NULL }, - [PROP_STICKY] = { "sticky", NULL, NULL }, - [PROP_LACP_PRIO] = { "lacp_prio", NULL, NULL }, - [PROP_LACP_KEY] = { "lacp_key", NULL, NULL }, + [PROP_0] = { NULL, NULL, NULL, 0 }, + [PROP_CONFIG] = { NULL, NULL, NULL, 0 }, + [PROP_QUEUE_ID] = { "queue_id", NULL, NULL, NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT }, + [PROP_PRIO] = { "prio", NULL, NULL, 0 }, + [PROP_STICKY] = { "sticky", NULL, NULL, 0 }, + [PROP_LACP_PRIO] = { "lacp_prio", NULL, NULL, NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT }, + [PROP_LACP_KEY] = { "lacp_key", NULL, NULL, 0 }, }; @@ -276,11 +276,11 @@ nm_setting_team_port_init (NMSettingTeamPort *setting) { NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting); - priv->queue_id = -1; - priv->lacp_prio = 255; + priv->queue_id = NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT; + priv->lacp_prio = NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT; } -#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id]) +#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id], TRUE) static void set_property (GObject *object, guint prop_id, @@ -304,7 +304,7 @@ set_property (GObject *object, guint prop_id, if (priv->queue_id == g_value_get_int (value)) break; priv->queue_id = g_value_get_int (value); - if (priv->queue_id > -1) + if (priv->queue_id != NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT) align_value = value; align_config = TRUE; break; @@ -329,7 +329,7 @@ set_property (GObject *object, guint prop_id, break; priv->lacp_prio = g_value_get_int (value); /* from libteam sources: lacp_prio default value is 0xff */ - if (priv->lacp_prio != 255) + if (priv->lacp_prio != NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT) align_value = value; align_config = TRUE; break; @@ -337,7 +337,7 @@ set_property (GObject *object, guint prop_id, if (priv->lacp_key == g_value_get_int (value)) break; priv->lacp_key = g_value_get_int (value); - if (priv->lacp_key > 0) + if (priv->lacp_key) align_value = value; align_config = TRUE; break; diff --git a/libnm-core/nm-setting-team-port.h b/libnm-core/nm-setting-team-port.h index 1b69bf73b4..825f648154 100644 --- a/libnm-core/nm-setting-team-port.h +++ b/libnm-core/nm-setting-team-port.h @@ -45,6 +45,9 @@ G_BEGIN_DECLS #define NM_SETTING_TEAM_PORT_LACP_PRIO "lacp-prio" #define NM_SETTING_TEAM_PORT_LACP_KEY "lacp-key" +#define NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT -1 +#define NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT 255 + /** * NMSettingTeamPort: * diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 499ca459ff..75e47f3859 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -83,22 +83,26 @@ enum { /* Keep aligned with team properties enum */ static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = { - [PROP_0] = { NULL, NULL, NULL }, - [PROP_CONFIG] = { NULL, NULL, NULL }, - [PROP_NOTIFY_PEERS_COUNT] = { "notify_peers", "count", NULL }, - [PROP_NOTIFY_PEERS_INTERVAL] = { "notify_peers", "interval", NULL }, - [PROP_MCAST_REJOIN_COUNT] = { "mcast_rejoin", "count", NULL }, - [PROP_MCAST_REJOIN_INTERVAL] = { "mcast_rejoin", "interval", NULL }, - [PROP_RUNNER] = { "runner", "name", NULL }, - [PROP_RUNNER_HWADDR_POLICY] = { "runner", "hwaddr_policy", NULL }, - [PROP_RUNNER_TX_HASH] = { "runner", "tx_hash", NULL }, - [PROP_RUNNER_TX_BALANCER] = { "runner", "tx_balancer", "name" }, - [PROP_RUNNER_TX_BALANCER_INTERVAL] = { "runner", "tx_balancer", "interval" }, - [PROP_RUNNER_ACTIVE] = { "runner", "active", NULL }, - [PROP_RUNNER_FAST_RATE] = { "runner", "fast_rate", NULL }, - [PROP_RUNNER_SYS_PRIO] = { "runner", "sys_prio", NULL }, - [PROP_RUNNER_MIN_PORTS] = { "runner", "min_ports", NULL }, - [PROP_RUNNER_AGG_SELECT_POLICY] = { "runner", "agg_select_policy", NULL }, + [PROP_0] = { NULL, NULL, NULL, 0 }, + [PROP_CONFIG] = { NULL, NULL, NULL, 0 }, + [PROP_NOTIFY_PEERS_COUNT] = { "notify_peers", "count", NULL, 0 }, + [PROP_NOTIFY_PEERS_INTERVAL] = { "notify_peers", "interval", NULL, 0 }, + [PROP_MCAST_REJOIN_COUNT] = { "mcast_rejoin", "count", NULL, 0 }, + [PROP_MCAST_REJOIN_INTERVAL] = { "mcast_rejoin", "interval", NULL, 0 }, + [PROP_RUNNER] = { "runner", "name", NULL, + {.default_str = NM_SETTING_TEAM_RUNNER_DEFAULT} }, + [PROP_RUNNER_HWADDR_POLICY] = { "runner", "hwaddr_policy", NULL, 0 }, + [PROP_RUNNER_TX_HASH] = { "runner", "tx_hash", NULL, 0 }, + [PROP_RUNNER_TX_BALANCER] = { "runner", "tx_balancer", "name", 0 }, + [PROP_RUNNER_TX_BALANCER_INTERVAL] = { "runner", "tx_balancer", "interval", + NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT }, + [PROP_RUNNER_ACTIVE] = { "runner", "active", NULL, 0 }, + [PROP_RUNNER_FAST_RATE] = { "runner", "fast_rate", NULL, 0 }, + [PROP_RUNNER_SYS_PRIO] = { "runner", "sys_prio", NULL, + NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT }, + [PROP_RUNNER_MIN_PORTS] = { "runner", "min_ports", NULL, 0 }, + [PROP_RUNNER_AGG_SELECT_POLICY] = { "runner", "agg_select_policy", NULL, + {.default_str = NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT} }, }; /** @@ -540,6 +544,8 @@ nm_setting_team_init (NMSettingTeam *setting) NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); priv->runner = g_strdup (NM_SETTING_TEAM_RUNNER_ROUNDROBIN); + priv->runner_sys_prio = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT; + priv->runner_tx_balancer_interval = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT; } static void @@ -559,7 +565,7 @@ finalize (GObject *object) } -#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id]) +#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id], FALSE) static void _align_team_properties (NMSettingTeam *setting) @@ -651,7 +657,9 @@ set_property (GObject *object, guint prop_id, case PROP_RUNNER: g_free (priv->runner); priv->runner = g_value_dup_string (value); - if (priv->runner && !nm_streq (priv->runner, "roundrobin")) + if ( priv->runner + && !nm_streq (priv->runner, + NM_SETTING_TEAM_RUNNER_DEFAULT)) align_value = value; align_config = TRUE; break; @@ -687,7 +695,8 @@ set_property (GObject *object, guint prop_id, if (priv->runner_tx_balancer_interval == g_value_get_int (value)) break; priv->runner_tx_balancer_interval = g_value_get_int (value); - if (priv->runner_tx_balancer_interval) + if (priv->runner_tx_balancer_interval != + NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT) align_value = value; align_config = TRUE; break; @@ -711,7 +720,7 @@ set_property (GObject *object, guint prop_id, if (priv->runner_sys_prio == g_value_get_int (value)) break; priv->runner_sys_prio = g_value_get_int (value); - if (priv->runner_sys_prio) + if (priv->runner_sys_prio != NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT) align_value = value; align_config = TRUE; break; diff --git a/libnm-core/nm-setting-team.h b/libnm-core/nm-setting-team.h index 992709c30b..e3af68d4e7 100644 --- a/libnm-core/nm-setting-team.h +++ b/libnm-core/nm-setting-team.h @@ -70,6 +70,14 @@ G_BEGIN_DECLS #define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT "count" #define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG "port_config" +#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT 1 +#define NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT 1 +#define NM_SETTING_TEAM_RUNNER_DEFAULT NM_SETTING_TEAM_RUNNER_ROUNDROBIN +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT 50 +#define NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT 255 +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO + /** * NMSettingTeam: * diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index aaf80363f5..6b8d58726a 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -85,18 +85,24 @@ typedef struct { const char *key1; const char *key2; const char *key3; + union { + int default_int; + gboolean default_bool; + const char *default_str; + }; } _NMUtilsTeamPropertyKeys; static inline int _nm_utils_json_extract_int (char *conf, - _NMUtilsTeamPropertyKeys key) + _NMUtilsTeamPropertyKeys key, + gboolean is_port) { gs_free GValue *t_value = NULL; int ret; - t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port); if (!t_value) - return 0; + return key.default_int; ret = g_value_get_int (t_value); g_value_unset (t_value); @@ -105,14 +111,15 @@ _nm_utils_json_extract_int (char *conf, static inline gboolean _nm_utils_json_extract_boolean (char *conf, - _NMUtilsTeamPropertyKeys key) + _NMUtilsTeamPropertyKeys key, + gboolean is_port) { gs_free GValue *t_value = NULL; gboolean ret; - t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port); if (!t_value) - return FALSE; + return key.default_bool; ret = g_value_get_boolean (t_value); g_value_unset (t_value); @@ -121,14 +128,15 @@ _nm_utils_json_extract_boolean (char *conf, static inline char * _nm_utils_json_extract_string (char *conf, - _NMUtilsTeamPropertyKeys key) + _NMUtilsTeamPropertyKeys key, + gboolean is_port) { gs_free GValue *t_value = NULL; char *ret; - t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port); if (!t_value) - return NULL; + return g_strdup (key.default_str); ret = g_value_dup_string (t_value); g_value_unset (t_value); @@ -137,12 +145,13 @@ _nm_utils_json_extract_string (char *conf, static inline char ** _nm_utils_json_extract_strv (char *conf, - _NMUtilsTeamPropertyKeys key) + _NMUtilsTeamPropertyKeys key, + gboolean is_port) { gs_free GValue *t_value = NULL; char **ret; - t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, FALSE); + t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port); if (!t_value) return NULL; diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index c492d528da..a31744df0c 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4559,16 +4559,18 @@ _nm_utils_team_config_get (const char *conf, json_object_set_new (json, "runner", json_element); } if (!runner) { - runner = "roundrobin"; + runner = NM_SETTING_TEAM_RUNNER_DEFAULT; json_object_set_new (json_element, "name", json_string (runner)); } - if (nm_streq (runner, "activebackup")) { - _json_add_object (json, "notify_peers", "count", NULL, json_integer (1)); - _json_add_object (json, "mcast_rejoin", "count", NULL, json_integer (1)); - _json_add_object (json, "runner", "hwaddr_policy", NULL, json_string ("same_all")); - } else if (nm_streq (runner, "loadbalance") || nm_streq (runner, "lacp")) { + if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) { + _json_add_object (json, "notify_peers", "count", NULL, + json_integer (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT)); + _json_add_object (json, "mcast_rejoin", "count", NULL, + json_integer (NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT)); + } else if ( nm_streq (runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE) + || nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) { json_element = json_array (); json_array_append_new (json_element, json_string ("eth")); json_array_append_new (json_element, json_string ("ipv4"));