summaryrefslogtreecommitdiff
path: root/libnm-core/nm-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-utils.c')
-rw-r--r--libnm-core/nm-utils.c65
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[] = {