about summary refs log tree commit diff
path: root/libnm-core/nm-keyfile-reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-keyfile-reader.c')
-rw-r--r--libnm-core/nm-keyfile-reader.c122
1 files changed, 115 insertions, 7 deletions
diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c
index 0ac417cd..20b5a3fc 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 <sys/types.h>
 #include <arpa/inet.h>
 #include <string.h>
+#include <linux/pkt_sched.h>
 
 #include "nm-common-macros.h"
 #include "nm-core-internal.h"
@@ -1313,6 +1314,102 @@ 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;
+	gs_strfreev 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);
+}
+
+static void
+tfilter_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+{
+	const char *setting_name = nm_setting_get_name (setting);
+	GPtrArray *tfilters;
+	gs_strfreev gchar **keys = NULL;
+	gsize n_keys = 0;
+	int i;
+
+	tfilters = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_tfilter_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++) {
+		NMTCTfilter *tfilter;
+		const char *tfilter_parent;
+		gs_free char *tfilter_rest = NULL;
+		gs_free char *tfilter_str = NULL;
+		gs_free_error GError *err = NULL;
+
+		if (!g_str_has_prefix (keys[i], "tfilter."))
+			continue;
+
+		tfilter_parent = keys[i] + sizeof ("tfilter.") - 1;
+		tfilter_rest = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, keys[i], NULL);
+		tfilter_str = g_strdup_printf ("%s%s %s",
+		                             _nm_utils_parse_tc_handle (tfilter_parent, NULL) != TC_H_UNSPEC ? "parent " : "",
+		                             tfilter_parent,
+		                             tfilter_rest);
+
+		tfilter = nm_utils_tc_tfilter_from_str (tfilter_str, &err);
+		if (!tfilter) {
+			handle_warn (info, keys[i], NM_KEYFILE_WARN_SEVERITY_WARN,
+			             _("invalid tfilter: %s"),
+			             err->message);
+		} else {
+			g_ptr_array_add (tfilters, tfilter);
+		}
+	}
+
+	if (tfilters->len >= 1)
+		g_object_set (setting, key, tfilters, NULL);
+
+	g_ptr_array_unref (tfilters);
+}
+
 typedef struct {
 	const char *setting_name;
 	const char *key;
@@ -1439,6 +1536,14 @@ 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 },
+        { NM_SETTING_TC_CONFIG_SETTING_NAME,
+          NM_SETTING_TC_CONFIG_TFILTERS,
+	  FALSE,
+          tfilter_parser },
 	{ NULL, NULL, FALSE }
 };
 
@@ -1480,6 +1585,13 @@ read_one_setting_value (NMSetting *setting,
 	    && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY))
 		return;
 
+	if (   (   NM_IS_SETTING_TEAM (setting)
+	        || NM_IS_SETTING_TEAM_PORT (setting))
+	    && !NM_IN_STRSET (key, NM_SETTING_TEAM_CONFIG)) {
+		/* silently ignore all team properties (except "config"). */
+		return;
+	}
+
 	setting_name = nm_setting_get_name (setting);
 
 	/* Look through the list of handlers for non-standard format key values */
@@ -1491,15 +1603,11 @@ read_one_setting_value (NMSetting *setting,
 		parser++;
 	}
 
-	/* VPN properties don't have the exact key name */
 	if (NM_IS_SETTING_VPN (setting))
 		check_for_key = FALSE;
-
-	if (NM_IS_SETTING_USER (setting))
+	else if (NM_IS_SETTING_USER (setting))
 		check_for_key = FALSE;
-
-	/* Bonding 'options' don't have the exact key name. The options are right under [bond] group. */
-	if (NM_IS_SETTING_BOND (setting))
+	else if (NM_IS_SETTING_BOND (setting))
 		check_for_key = FALSE;
 
 	/* Check for the exact key in the GKeyFile if required.  Most setting