mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-25 11:30:27 +01:00
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:
commit
4071b1544d
6 changed files with 102 additions and 19 deletions
|
|
@ -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, \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue