summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-07-08 09:43:30 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-07-08 09:43:30 +0200
commit4071b1544d6657839c190ca86bf0c1090f1978dc (patch)
treec31d8b6cd1a9b299815ab06b91b609547cade43a
parenta5133e708e85e02b9cbf199c0840e00f118b59c7 (diff)
parentce432a3abc49a52ed253f0e37707aad33c146336 (diff)
downloadNetworkManager-4071b1544d6657839c190ca86bf0c1090f1978dc.tar.gz
tc: merge branch 'bg/tc-port-mirroring-rh1436535'
Some tc improvements to support port mirroring. https://bugzilla.redhat.com/show_bug.cgi?id=1436535 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/545
-rw-r--r--libnm-core/nm-utils-private.h10
-rw-r--r--libnm-core/nm-utils.c17
-rw-r--r--libnm-core/tests/test-setting.c51
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c25
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h14
-rw-r--r--src/platform/nm-linux-platform.c4
6 files changed, 102 insertions, 19 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..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);
@@ -2895,7 +2905,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 +5818,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/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;
@@ -2444,6 +2444,50 @@ test_tc_config_tfilter (void)
}
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)
{
gs_unref_object NMSettingTCConfig *s_tc = NULL;
@@ -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);
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c
index fa85c66217..9479e64934 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));
@@ -5062,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;
}
@@ -5074,6 +5089,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 +5116,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);
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;