diff options
Diffstat (limited to 'libnm-core/nm-utils.c')
-rw-r--r-- | libnm-core/nm-utils.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 68c6647784..af05cdfb6e 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2309,6 +2309,15 @@ static const NMVariantAttributeSpec * const tc_object_attribute_spec[] = { NULL, }; +typedef struct { + const char *kind; + const NMVariantAttributeSpec * const *attrs; +} NMQdiscAttributeSpec; + +static const NMQdiscAttributeSpec *const tc_qdisc_attribute_spec[] = { + NULL, +}; + /*****************************************************************************/ /** @@ -2323,8 +2332,12 @@ static const NMVariantAttributeSpec * const tc_object_attribute_spec[] = { void _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc) { + gs_unref_hashtable GHashTable *ht = NULL; guint32 handle = nm_tc_qdisc_get_handle (qdisc); const char *kind = nm_tc_qdisc_get_kind (qdisc); + gs_strfreev char **attr_names = NULL; + gs_free char *str = NULL; + guint i; if (handle != TC_H_UNSPEC && strcmp (kind, "ingress") != 0) { g_string_append (string, "handle "); @@ -2333,6 +2346,20 @@ _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc) } g_string_append (string, kind); + + attr_names = nm_tc_qdisc_get_attribute_names (qdisc); + if (attr_names[0]) + ht = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); + for (i = 0; attr_names[i]; i++) { + g_hash_table_insert (ht, attr_names[i], + nm_tc_qdisc_get_attribute (qdisc, attr_names[i])); + } + + if (i) { + str = nm_utils_format_variant_attributes (ht, ' ', ' '); + g_string_append_c (string, ' '); + g_string_append (string, str); + } } /** @@ -2455,21 +2482,36 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error) gs_free char *kind = NULL; gs_free char *rest = NULL; NMTCQdisc *qdisc = NULL; - gs_unref_hashtable GHashTable *ht = NULL; + gs_unref_hashtable GHashTable *options = NULL; + GHashTableIter iter; + gpointer key, value; + guint i; nm_assert (str); nm_assert (!error || !*error); - ht = nm_utils_parse_variant_attributes (str, - ' ', ' ', FALSE, - tc_object_attribute_spec, - error); - if (!ht) - return NULL; - if (!_tc_read_common_opts (str, &handle, &parent, &kind, &rest, error)) return NULL; + for (i = 0; rest && tc_qdisc_attribute_spec[i]; i++) { + if (strcmp (tc_qdisc_attribute_spec[i]->kind, kind) == 0) { + options = nm_utils_parse_variant_attributes (rest, + ' ', ' ', FALSE, + tc_qdisc_attribute_spec[i]->attrs, + error); + if (!options) + return NULL; + break; + } + } + nm_clear_pointer (&rest, g_free); + + if (options) { + value = g_hash_table_lookup (options, ""); + if (value) + rest = g_variant_dup_string (value, NULL); + } + if (rest) { g_set_error (error, 1, 0, _("unsupported qdisc option: '%s'."), rest); return NULL; @@ -2481,8 +2523,15 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error) nm_tc_qdisc_set_handle (qdisc, handle); + if (options) { + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, &key, &value)) + nm_tc_qdisc_set_attribute (qdisc, key, g_variant_ref_sink (value)); + } + return qdisc; } + /*****************************************************************************/ static const NMVariantAttributeSpec * const tc_action_simple_attribute_spec[] = { |