keyfile: add ability to read/write tc filters

The idea is

  tfilter.<parent>=[handle <handle>] <tfilter> [<options>] [action [<action options>...]]

What works now:

  [tc]
  qdisc.root=handle 1234: fq_codel
  qdisc.ffff:fff1=ingress
  tfilter.1234:=matchall action drop
  tfilter.ffff:=matchall action simple sdata Hello
This commit is contained in:
Lubomir Rintel 2017-11-18 17:16:50 +01:00
parent 7cd2b6178d
commit 2e8fc6947d
2 changed files with 88 additions and 0 deletions

View file

@ -1362,6 +1362,54 @@ qdisc_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
g_ptr_array_unref (qdiscs); 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 { typedef struct {
const char *setting_name; const char *setting_name;
const char *key; const char *key;
@ -1492,6 +1540,10 @@ static KeyParser key_parsers[] = {
NM_SETTING_TC_CONFIG_QDISCS, NM_SETTING_TC_CONFIG_QDISCS,
FALSE, FALSE,
qdisc_parser }, qdisc_parser },
{ NM_SETTING_TC_CONFIG_SETTING_NAME,
NM_SETTING_TC_CONFIG_TFILTERS,
FALSE,
tfilter_parser },
{ NULL, NULL, FALSE } { NULL, NULL, FALSE }
}; };

View file

@ -286,6 +286,39 @@ qdisc_writer (KeyfileWriterInfo *info,
} }
} }
static void
tfilter_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++) {
NMTCTfilter *tfilter = array->pdata[i];
GString *key_name = g_string_sized_new (16);
GString *value_str = g_string_sized_new (60);
g_string_append (key_name, "tfilter.");
_nm_utils_string_append_tc_parent (key_name, NULL,
nm_tc_tfilter_get_parent (tfilter));
_nm_utils_string_append_tc_tfilter_rest (value_str, tfilter, NULL);
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 static void
write_hash_of_string (GKeyFile *file, write_hash_of_string (GKeyFile *file,
NMSetting *setting, NMSetting *setting,
@ -621,6 +654,9 @@ static KeyWriter key_writers[] = {
{ NM_SETTING_TC_CONFIG_SETTING_NAME, { NM_SETTING_TC_CONFIG_SETTING_NAME,
NM_SETTING_TC_CONFIG_QDISCS, NM_SETTING_TC_CONFIG_QDISCS,
qdisc_writer }, qdisc_writer },
{ NM_SETTING_TC_CONFIG_SETTING_NAME,
NM_SETTING_TC_CONFIG_TFILTERS,
tfilter_writer },
{ NM_SETTING_TEAM_SETTING_NAME, { NM_SETTING_TEAM_SETTING_NAME,
NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
null_writer}, null_writer},