From d0d35aa278da490408f33ee90e30d556e22bc647 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 18 Jun 2020 13:28:53 +0200 Subject: platform: support creation of prio qdisc Support the creation of parameterless 'prio' qdiscs. The kernel needs a TCA_OPTIONS attribute initialized with default values. We currently don't support modifying the qdisc parameters. --- src/platform/nm-linux-platform.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index a0edd13c9e..40451df820 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -4757,6 +4757,10 @@ _nl_msg_new_qdisc (int nlmsg_type, NLA_PUT_U32 (msg, TCA_TBF_BURST, qdisc->tbf.burst); nla_nest_end (msg, tc_options); + } else if (nm_streq (qdisc->kind, "prio")) { + struct tc_prio_qopt opt = {3, { 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 } }; + + NLA_PUT (msg, TCA_OPTIONS, sizeof (opt), &opt); } else { if (!(tc_options = nla_nest_start (msg, TCA_OPTIONS))) goto nla_put_failure; -- cgit v1.2.1 From ee946ca27d432a7eef3b223e8c8d48f05fa4d8c2 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 7 Jul 2020 18:03:48 +0200 Subject: libnm-core: pass variant-attribute-spec to format function The output of nm_utils_format_variant_attributes() must be accepted by nm_utils_parse_variant_attributes(), producing the initial attributes. The latter has a special handling of some attributes, depending on the input NMVariantAttributeSpec list. For example, if the NMVariantAttributeSpec is a boolean with the 'no_value' flag, the parser doesn't look for a value. Pass the NMVariantAttributeSpec list to the format function so that it can behave in the same way as the parse one. --- libnm-core/nm-utils-private.h | 10 ---------- libnm-core/nm-utils.c | 3 ++- shared/nm-glib-aux/nm-shared-utils.c | 15 +++++++++++++++ shared/nm-glib-aux/nm-shared-utils.h | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index dd3785be0f..75e8b5bd86 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -13,16 +13,6 @@ #include "nm-setting-private.h" #include "nm-setting-ip-config.h" -struct _NMVariantAttributeSpec { - char *name; - const GVariantType *type; - bool v4:1; - bool v6:1; - bool no_value:1; - bool consumes_rest:1; - char str_type; -}; - #define NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(_name, _type, ...) \ (&((const NMVariantAttributeSpec) { \ .name = _name, \ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 3803c124e1..85f7b4a673 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2895,7 +2895,7 @@ nm_utils_sriov_vf_to_str (const NMSriovVF *vf, gboolean omit_index, GError **err if (num_attrs > 0) { if (!omit_index) g_string_append_c (str, ' '); - _nm_utils_format_variant_attributes_full (str, values, num_attrs, ' ', '='); + _nm_utils_format_variant_attributes_full (str, values, num_attrs, NULL, ' ', '='); } vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans); @@ -5808,6 +5808,7 @@ nm_utils_format_variant_attributes (GHashTable *attributes, char key_value_separator) { return _nm_utils_format_variant_attributes (attributes, + NULL, attr_separator, key_value_separator); } diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index fa85c66217..e6be79649f 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -5021,9 +5021,11 @@ void _nm_utils_format_variant_attributes_full (GString *str, const NMUtilsNamedValue *values, guint num_values, + const NMVariantAttributeSpec *const *spec, char attr_separator, char key_value_separator) { + const NMVariantAttributeSpec *const *s; const char *name, *value; GVariant *variant; char *escaped; @@ -5035,6 +5037,17 @@ _nm_utils_format_variant_attributes_full (GString *str, name = values[i].name; variant = values[i].value_ptr; value = NULL; + s = NULL; + + if (spec) { + for (s = spec; *s; s++) { + if (nm_streq0 ((*s)->name, name)) + break; + } + + if (!*s) + continue; + } if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) value = nm_sprintf_buf (buf, "%u", g_variant_get_uint32 (variant)); @@ -5074,6 +5087,7 @@ _nm_utils_format_variant_attributes_full (GString *str, char * _nm_utils_format_variant_attributes (GHashTable *attributes, + const NMVariantAttributeSpec *const *spec, char attr_separator, char key_value_separator) { @@ -5100,6 +5114,7 @@ _nm_utils_format_variant_attributes (GHashTable *attributes, _nm_utils_format_variant_attributes_full (str, values, len, + spec, attr_separator, key_value_separator); return g_string_free (str, FALSE); diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 52f5146e30..ac091d8230 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -2068,13 +2068,27 @@ nm_strvarray_set_strv (GArray **array, const char *const*strv) /*****************************************************************************/ +struct _NMVariantAttributeSpec { + char *name; + const GVariantType *type; + bool v4:1; + bool v6:1; + bool no_value:1; + bool consumes_rest:1; + char str_type; +}; + +typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec; + void _nm_utils_format_variant_attributes_full (GString *str, const NMUtilsNamedValue *values, guint num_values, + const NMVariantAttributeSpec *const *spec, char attr_separator, char key_value_separator); char *_nm_utils_format_variant_attributes (GHashTable *attributes, + const NMVariantAttributeSpec *const *spec, char attr_separator, char key_value_separator); -- cgit v1.2.1 From 4599be093e97d032b0a888c7deeeb84343a9005b Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 7 Jul 2020 18:07:43 +0200 Subject: libnm-core: don't print value for no-value attributes --- shared/nm-glib-aux/nm-shared-utils.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index e6be79649f..9479e64934 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -5075,11 +5075,13 @@ _nm_utils_format_variant_attributes_full (GString *str, g_string_append (str, escaped); g_free (escaped); - g_string_append_c (str, key_value_separator); + if (!s || !*s || !(*s)->no_value) { + g_string_append_c (str, key_value_separator); - escaped = attribute_escape (value, attr_separator, key_value_separator); - g_string_append (str, escaped); - g_free (escaped); + escaped = attribute_escape (value, attr_separator, key_value_separator); + g_string_append (str, escaped); + g_free (escaped); + } sep = attr_separator; } -- cgit v1.2.1 From 7c60895d1e195598c48299691cba1e6ce9c558be Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 18 Jun 2020 11:39:02 +0200 Subject: libnm-core: pass variant-attribute-spec for tc actions --- libnm-core/nm-utils.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 85f7b4a673..4127abb54d 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2591,11 +2591,21 @@ _string_append_tc_action (GString *string, NMTCAction *action, GError **error) { const char *kind = nm_tc_action_get_kind (action); gs_free char *str = NULL; + const NMVariantAttributeSpec *const *attrs; + + if (nm_streq (kind, "simple")) + attrs = tc_action_simple_attribute_spec; + else if (nm_streq (kind, "mirred")) + attrs = tc_action_mirred_attribute_spec; + else + attrs = NULL; + g_string_append (string, kind); - str = nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action), - ' ', ' '); + str = _nm_utils_format_variant_attributes (_nm_tc_action_get_attributes (action), + attrs, + ' ', ' '); if (str) { g_string_append_c (string, ' '); g_string_append (string, str); -- cgit v1.2.1 From ce432a3abc49a52ed253f0e37707aad33c146336 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 11 May 2020 15:36:10 +0200 Subject: libnm-core: add test for mirred tc filter --- libnm-core/tests/test-setting.c | 51 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index 11ee376f32..1a32d91a49 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -2389,7 +2389,7 @@ test_tc_config_action (void) } static void -test_tc_config_tfilter (void) +test_tc_config_tfilter_matchall_sdata (void) { NMTCAction *action1; NMTCTfilter *tfilter1, *tfilter2; @@ -2443,6 +2443,50 @@ test_tc_config_tfilter (void) nm_tc_tfilter_unref (tfilter2); } +static void +test_tc_config_tfilter_matchall_mirred (void) +{ + NMTCAction *action; + NMTCTfilter *tfilter1; + GError *error = NULL; + gs_strfreev char **attr_names = NULL; + gs_free char *str; + GVariant *variant; + + tfilter1 = nm_utils_tc_tfilter_from_str ("parent ffff: matchall action mirred ingress mirror dev eth0", &error); + nmtst_assert_success (tfilter1, error); + g_assert_cmpint (nm_tc_tfilter_get_parent (tfilter1), ==, TC_H_MAKE (0xffff << 16, 0)); + g_assert_cmpstr (nm_tc_tfilter_get_kind (tfilter1), ==, "matchall"); + + action = nm_tc_tfilter_get_action (tfilter1); + nm_assert (action); + g_assert_cmpstr (nm_tc_action_get_kind (action), ==, "mirred"); + attr_names = nm_tc_action_get_attribute_names (action); + g_assert (attr_names); + g_assert_cmpint (g_strv_length (attr_names), ==, 3); + + variant = nm_tc_action_get_attribute (action, "ingress"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert (g_variant_get_boolean (variant)); + + variant = nm_tc_action_get_attribute (action, "mirror"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert (g_variant_get_boolean (variant)); + + variant = nm_tc_action_get_attribute (action, "dev"); + g_assert (variant); + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "eth0"); + + str = nm_utils_tc_tfilter_to_str (tfilter1, &error); + nmtst_assert_success (str, error); + g_assert_cmpstr (str, ==, "parent ffff: matchall action mirred dev eth0 ingress mirror"); + + nm_tc_tfilter_unref (tfilter1); +} + static void test_tc_config_setting_valid (void) { @@ -4040,7 +4084,10 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/tc_config/qdisc", test_tc_config_qdisc); g_test_add_func ("/libnm/settings/tc_config/action", test_tc_config_action); - g_test_add_func ("/libnm/settings/tc_config/tfilter", test_tc_config_tfilter); + g_test_add_func ("/libnm/settings/tc_config/tfilter/matchall_sdata", + test_tc_config_tfilter_matchall_sdata); + g_test_add_func ("/libnm/settings/tc_config/tfilter/matchall_mirred", + test_tc_config_tfilter_matchall_mirred); g_test_add_func ("/libnm/settings/tc_config/setting/valid", test_tc_config_setting_valid); g_test_add_func ("/libnm/settings/tc_config/setting/duplicates", test_tc_config_setting_duplicates); g_test_add_func ("/libnm/settings/tc_config/dbus", test_tc_config_dbus); -- cgit v1.2.1