From 9d0eeb30b646d2b60781d0881cf7959cbaaa3142 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 18 Nov 2017 17:16:50 +0100 Subject: [PATCH] keyfile: add ability to read/write qdiscs from tc setting The format for qdiscs is qdisc.=[handle ] [...] E.g.: [tc] qdisc.root=fq_codel handle de4d: qdisc.ffff:fff1=ingress That is pretty much what is supported at this point. --- libnm-core/nm-keyfile-reader.c | 55 +++++++++++++++++++++++++++++++++- libnm-core/nm-keyfile-writer.c | 38 ++++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c index 09a482be64..19c9881f6b 100644 --- a/libnm-core/nm-keyfile-reader.c +++ b/libnm-core/nm-keyfile-reader.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 - 2009 Novell, Inc. - * Copyright (C) 2008 - 2015 Red Hat, Inc. + * Copyright (C) 2008 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -30,6 +30,7 @@ #include #include #include +#include #include "nm-common-macros.h" #include "nm-core-internal.h" @@ -1313,6 +1314,54 @@ team_config_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key g_object_set (G_OBJECT (setting), key, conf, NULL); } +static void +qdisc_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char *setting_name = nm_setting_get_name (setting); + GPtrArray *qdiscs; + gchar **keys = NULL; + gsize n_keys = 0; + int i; + + qdiscs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_qdisc_unref); + + keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, setting_name, &n_keys, NULL); + if (!keys || n_keys == 0) + return; + + for (i = 0; i < n_keys; i++) { + NMTCQdisc *qdisc; + const char *qdisc_parent; + gs_free char *qdisc_rest = NULL; + gs_free char *qdisc_str = NULL; + gs_free_error GError *err = NULL; + + if (!g_str_has_prefix (keys[i], "qdisc.")) + continue; + + qdisc_parent = keys[i] + sizeof ("qdisc.") - 1; + qdisc_rest = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, keys[i], NULL); + qdisc_str = g_strdup_printf ("%s%s %s", + _nm_utils_parse_tc_handle (qdisc_parent, NULL) != TC_H_UNSPEC ? "parent " : "", + qdisc_parent, + qdisc_rest); + + qdisc = nm_utils_tc_qdisc_from_str (qdisc_str, &err); + if (!qdisc) { + handle_warn (info, keys[i], NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid qdisc: %s"), + err->message); + } else { + g_ptr_array_add (qdiscs, qdisc); + } + } + + if (qdiscs->len >= 1) + g_object_set (setting, key, qdiscs, NULL); + + g_ptr_array_unref (qdiscs); +} + typedef struct { const char *setting_name; const char *key; @@ -1439,6 +1488,10 @@ static KeyParser key_parsers[] = { NM_SETTING_TEAM_CONFIG, TRUE, team_config_parser }, + { NM_SETTING_TC_CONFIG_SETTING_NAME, + NM_SETTING_TC_CONFIG_QDISCS, + FALSE, + qdisc_parser }, { NULL, NULL, FALSE } }; diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c index 236dad8027..ce7ea4b1c1 100644 --- a/libnm-core/nm-keyfile-writer.c +++ b/libnm-core/nm-keyfile-writer.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2015 Red Hat, Inc. + * Copyright (C) 2008 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -253,6 +253,39 @@ route_writer (KeyfileWriterInfo *info, write_ip_values (info->keyfile, setting_name, array, NULL, TRUE); } +static void +qdisc_writer (KeyfileWriterInfo *info, + NMSetting *setting, + const char *key, + const GValue *value) +{ + gsize i; + GPtrArray *array; + + array = (GPtrArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + for (i = 0; i < array->len; i++) { + NMTCQdisc *qdisc = array->pdata[i]; + GString *key_name = g_string_sized_new (16); + GString *value_str = g_string_sized_new (60); + + g_string_append (key_name, "qdisc."); + _nm_utils_string_append_tc_parent (key_name, NULL, + nm_tc_qdisc_get_parent (qdisc)); + _nm_utils_string_append_tc_qdisc_rest (value_str, qdisc); + + nm_keyfile_plugin_kf_set_string (info->keyfile, + NM_SETTING_TC_CONFIG_SETTING_NAME, + key_name->str, + value_str->str); + + g_string_free (key_name, TRUE); + g_string_free (value_str, TRUE); + } +} + static void write_hash_of_string (GKeyFile *file, NMSetting *setting, @@ -585,6 +618,9 @@ static KeyWriter key_writers[] = { { NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, cert_writer }, + { NM_SETTING_TC_CONFIG_SETTING_NAME, + NM_SETTING_TC_CONFIG_QDISCS, + qdisc_writer }, { NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, null_writer},