From fa8e896f941f40700199d025f19b22bd748a08e7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 25 Nov 2017 22:45:32 +0100 Subject: [PATCH] libnm-core: add action support to NMSettingTCConfig The actions are not too useful my themselves, but it will be possible to embed them into traffic filters in subsequent commits. (cherry picked from commit 7c8ce778fb183b6068f263b56d7c6ab459c163a0) --- libnm-core/nm-setting-tc-config.c | 235 ++++++++++++++++++++++++++++++ libnm-core/nm-setting-tc-config.h | 35 +++++ libnm/libnm.ver | 10 ++ 3 files changed, 280 insertions(+) diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index b77b91eafb..588b05de0f 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -249,6 +249,241 @@ nm_tc_qdisc_get_parent (NMTCQdisc *qdisc) /*****************************************************************************/ +G_DEFINE_BOXED_TYPE (NMTCAction, nm_tc_action, nm_tc_action_dup, nm_tc_action_unref) + +struct NMTCAction { + guint refcount; + + char *kind; + + GHashTable *attributes; +}; + +/** + * nm_tc_action_new: + * @kind: name of the queueing discipline + * @error: location to store error, or %NULL + * + * Creates a new #NMTCAction object. + * + * Returns: (transfer full): the new #NMTCAction object, or %NULL on error + * + * Since: 1.10.2 + **/ +NMTCAction * +nm_tc_action_new (const char *kind, + GError **error) +{ + NMTCAction *action; + + action = g_slice_new0 (NMTCAction); + action->refcount = 1; + + action->kind = g_strdup (kind); + + return action; +} + +/** + * nm_tc_action_ref: + * @action: the #NMTCAction + * + * Increases the reference count of the object. + * + * Since: 1.10.2 + **/ +void +nm_tc_action_ref (NMTCAction *action) +{ + g_return_if_fail (action != NULL); + g_return_if_fail (action->refcount > 0); + + action->refcount++; +} + +/** + * nm_tc_action_unref: + * @action: the #NMTCAction + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.10.2 + **/ +void +nm_tc_action_unref (NMTCAction *action) +{ + g_return_if_fail (action != NULL); + g_return_if_fail (action->refcount > 0); + + action->refcount--; + if (action->refcount == 0) { + g_free (action->kind); + if (action->attributes) + g_hash_table_unref (action->attributes); + g_slice_free (NMTCAction, action); + } +} + +/** + * nm_tc_action_equal: + * @action: the #NMTCAction + * @other: the #NMTCAction to compare @action to. + * + * Determines if two #NMTCAction objects contain the same kind, family, + * handle, parent and info. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.10.2 + **/ +gboolean +nm_tc_action_equal (NMTCAction *action, NMTCAction *other) +{ + if (action == NULL && other == NULL) + return TRUE; + + if (action == NULL || other == NULL) + return FALSE; + + g_return_val_if_fail (action->refcount > 0, FALSE); + g_return_val_if_fail (other->refcount > 0, FALSE); + + if (g_strcmp0 (action->kind, other->kind) != 0) + return FALSE; + + return TRUE; +} + +/** + * nm_tc_action_dup: + * @action: the #NMTCAction + * + * Creates a copy of @action + * + * Returns: (transfer full): a copy of @action + * + * Since: 1.10.2 + **/ +NMTCAction * +nm_tc_action_dup (NMTCAction *action) +{ + NMTCAction *copy; + + g_return_val_if_fail (action != NULL, NULL); + g_return_val_if_fail (action->refcount > 0, NULL); + + copy = nm_tc_action_new (action->kind, NULL); + + if (action->attributes) { + GHashTableIter iter; + const char *key; + GVariant *value; + + g_hash_table_iter_init (&iter, action->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) + nm_tc_action_set_attribute (copy, key, value); + } + + return copy; +} + +/** + * nm_tc_action_get_kind: + * @action: the #NMTCAction + * + * Returns: + * + * Since: 1.10.2 + **/ +const char * +nm_tc_action_get_kind (NMTCAction *action) +{ + g_return_val_if_fail (action != NULL, NULL); + g_return_val_if_fail (action->refcount > 0, NULL); + + return action->kind; +} + +/** + * nm_tc_action_get_attribute_names: + * @action: the #NMTCAction + * + * Gets an array of attribute names defined on @action. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names, + **/ +char ** +nm_tc_action_get_attribute_names (NMTCAction *action) +{ + GHashTableIter iter; + const char *key; + GPtrArray *names; + + g_return_val_if_fail (action != NULL, NULL); + + names = g_ptr_array_new (); + + if (action->attributes) { + g_hash_table_iter_init (&iter, action->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) + g_ptr_array_add (names, g_strdup (key)); + } + g_ptr_array_add (names, NULL); + + return (char **) g_ptr_array_free (names, FALSE); +} + +/** + * nm_tc_action_get_attribute: + * @action: the #NMTCAction + * @name: the name of an action attribute + * + * Gets the value of the attribute with name @name on @action + * + * Returns: (transfer none): the value of the attribute with name @name on + * @action, or %NULL if @action has no such attribute. + **/ +GVariant * +nm_tc_action_get_attribute (NMTCAction *action, const char *name) +{ + g_return_val_if_fail (action != NULL, NULL); + g_return_val_if_fail (name != NULL && *name != '\0', NULL); + + if (action->attributes) + return g_hash_table_lookup (action->attributes, name); + else + return NULL; +} + +/** + * nm_tc_action_set_attribute: + * @action: the #NMTCAction + * @name: the name of an action attribute + * @value: (transfer none) (allow-none): the value + * + * Sets or clears the named attribute on @action to the given value. + **/ +void +nm_tc_action_set_attribute (NMTCAction *action, const char *name, GVariant *value) +{ + g_return_if_fail (action != NULL); + g_return_if_fail (name != NULL && *name != '\0'); + g_return_if_fail (strcmp (name, "kind") != 0); + + if (!action->attributes) { + action->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert (action->attributes, g_strdup (name), g_variant_ref_sink (value)); + else + g_hash_table_remove (action->attributes, name); +} + +/*****************************************************************************/ + enum { PROP_0, PROP_QDISCS, diff --git a/libnm-core/nm-setting-tc-config.h b/libnm-core/nm-setting-tc-config.h index 5592f22283..9d68fe8e0b 100644 --- a/libnm-core/nm-setting-tc-config.h +++ b/libnm-core/nm-setting-tc-config.h @@ -61,6 +61,41 @@ void nm_tc_qdisc_set_handle (NMTCQdisc *qdisc, NM_AVAILABLE_IN_1_10_2 guint32 nm_tc_qdisc_get_parent (NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_10_2 +typedef struct NMTCAction NMTCAction; + +NM_AVAILABLE_IN_1_10_2 +GType nm_tc_action_get_type (void); + +NM_AVAILABLE_IN_1_10_2 +NMTCAction *nm_tc_action_new (const char *kind, + GError **error); + +NM_AVAILABLE_IN_1_10_2 +void nm_tc_action_ref (NMTCAction *action); +NM_AVAILABLE_IN_1_10_2 +void nm_tc_action_unref (NMTCAction *action); +NM_AVAILABLE_IN_1_10_2 +gboolean nm_tc_action_equal (NMTCAction *action, + NMTCAction *other); + +NM_AVAILABLE_IN_1_10_2 +NMTCAction *nm_tc_action_dup (NMTCAction *action); + + +NM_AVAILABLE_IN_1_10_2 +const char *nm_tc_action_get_kind (NMTCAction *action); + +NM_AVAILABLE_IN_1_10_2 +char **nm_tc_action_get_attribute_names (NMTCAction *action); +NM_AVAILABLE_IN_1_10_2 +GVariant *nm_tc_action_get_attribute (NMTCAction *action, + const char *name); +NM_AVAILABLE_IN_1_10_2 +void nm_tc_action_set_attribute (NMTCAction *action, + const char *name, + GVariant *value); + #define NM_TYPE_SETTING_TC_CONFIG (nm_setting_tc_config_get_type ()) #define NM_SETTING_TC_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TC_CONFIG, NMSettingTCConfig)) #define NM_SETTING_TC_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_TC_CONFIG, NMSettingTCConfigClass)) diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 4bf4bb21b1..e71236b11e 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1270,6 +1270,16 @@ global: nm_setting_team_remove_link_watcher_by_value; nm_setting_team_remove_runner_tx_hash; nm_setting_team_remove_runner_tx_hash_by_value; + nm_tc_action_dup; + nm_tc_action_equal; + nm_tc_action_get_attribute; + nm_tc_action_get_attribute_names; + nm_tc_action_get_kind; + nm_tc_action_get_type; + nm_tc_action_new; + nm_tc_action_ref; + nm_tc_action_set_attribute; + nm_tc_action_unref; nm_tc_qdisc_dup; nm_tc_qdisc_equal; nm_tc_qdisc_get_handle;