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
This commit is contained in:
Beniamino Galvani 2020-07-08 09:43:30 +02:00
commit 4071b1544d
6 changed files with 102 additions and 19 deletions

View file

@ -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, \

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;