mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 18:08:05 +02:00
libnm,platform: merge branch 'th/various-cleanup-platform-libnm'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/131
This commit is contained in:
commit
5d851c0f9c
12 changed files with 357 additions and 214 deletions
|
|
@ -1212,25 +1212,22 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
|
|||
g_hash_table_remove (route->attributes, name);
|
||||
}
|
||||
|
||||
#define ATTR_SPEC_PTR(name, type, v4, v6, str_type) \
|
||||
&(NMVariantAttributeSpec) { name, type, v4, v6, FALSE, FALSE, str_type }
|
||||
|
||||
static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a'),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, FALSE, TRUE, 'p'),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, FALSE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_INITRWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_MTU, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, G_VARIANT_TYPE_BOOLEAN, TRUE, TRUE, 0 ),
|
||||
static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, .v4 = TRUE, .v6 = TRUE, .str_type = 'a', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, .v6 = TRUE, .str_type = 'p', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, .v4 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_INITRWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_MTU, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -365,17 +365,14 @@ nm_sriov_vf_get_attribute (const NMSriovVF *vf, const char *name)
|
|||
return g_hash_table_lookup (vf->attributes, name);
|
||||
}
|
||||
|
||||
#define SRIOV_ATTR_SPEC_PTR(name, type, str_type) \
|
||||
&(NMVariantAttributeSpec) { name, type, FALSE, FALSE, FALSE, FALSE, str_type }
|
||||
|
||||
const NMVariantAttributeSpec * const _nm_sriov_vf_attribute_spec[] = {
|
||||
SRIOV_ATTR_SPEC_PTR (NM_SRIOV_VF_ATTRIBUTE_MAC, G_VARIANT_TYPE_STRING, 'm'),
|
||||
SRIOV_ATTR_SPEC_PTR (NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, G_VARIANT_TYPE_BOOLEAN, 0),
|
||||
SRIOV_ATTR_SPEC_PTR (NM_SRIOV_VF_ATTRIBUTE_TRUST, G_VARIANT_TYPE_BOOLEAN, 0),
|
||||
SRIOV_ATTR_SPEC_PTR (NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, G_VARIANT_TYPE_UINT32, 0),
|
||||
SRIOV_ATTR_SPEC_PTR (NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, G_VARIANT_TYPE_UINT32, 0),
|
||||
const NMVariantAttributeSpec *const _nm_sriov_vf_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_SRIOV_VF_ATTRIBUTE_MAC, G_VARIANT_TYPE_STRING, .str_type = 'm', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, G_VARIANT_TYPE_BOOLEAN, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_SRIOV_VF_ATTRIBUTE_TRUST, G_VARIANT_TYPE_BOOLEAN, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, G_VARIANT_TYPE_UINT32, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, G_VARIANT_TYPE_UINT32, ),
|
||||
/* D-Bus only, synthetic attributes */
|
||||
SRIOV_ATTR_SPEC_PTR ("vlans", G_VARIANT_TYPE_STRING, 'd'),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("vlans", G_VARIANT_TYPE_STRING, .str_type = 'd', ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,13 @@ struct _NMVariantAttributeSpec {
|
|||
char str_type;
|
||||
};
|
||||
|
||||
#define NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(_name, _type, ...) \
|
||||
(&((const NMVariantAttributeSpec) { \
|
||||
.name = _name, \
|
||||
.type = _type, \
|
||||
__VA_ARGS__ \
|
||||
}))
|
||||
|
||||
gboolean _nm_utils_string_slist_validate (GSList *list,
|
||||
const char **valid_values);
|
||||
|
||||
|
|
|
|||
|
|
@ -2279,50 +2279,76 @@ _nm_utils_string_append_tc_parent (GString *string, const char *prefix, guint32
|
|||
guint32
|
||||
_nm_utils_parse_tc_handle (const char *str, GError **error)
|
||||
{
|
||||
gint64 maj, min;
|
||||
char *sep;
|
||||
gint64 maj;
|
||||
gint64 min = 0;
|
||||
const char *sep;
|
||||
|
||||
maj = g_ascii_strtoll (str, &sep, 0x10);
|
||||
if (*sep == ':')
|
||||
min = g_ascii_strtoll (&sep[1], &sep, 0x10);
|
||||
else
|
||||
min = 0;
|
||||
nm_assert (str);
|
||||
|
||||
if (*sep != '\0' || maj <= 0 || maj > 0xffff || min < 0 || min > 0xffff) {
|
||||
g_set_error (error, 1, 0, _("'%s' is not a valid handle."), str);
|
||||
return TC_H_UNSPEC;
|
||||
maj = g_ascii_strtoll (str, (char **) &sep, 0x10);
|
||||
if (sep == str)
|
||||
goto fail;
|
||||
|
||||
sep = nm_str_skip_leading_spaces (sep);
|
||||
|
||||
if (sep[0] == ':') {
|
||||
const char *str2 = &sep[1];
|
||||
|
||||
min = g_ascii_strtoll (str2, (char **) &sep, 0x10);
|
||||
sep = nm_str_skip_leading_spaces (sep);
|
||||
if (sep[0] != '\0')
|
||||
goto fail;
|
||||
} else if (sep[0] != '\0')
|
||||
goto fail;
|
||||
|
||||
if ( maj <= 0
|
||||
|| maj > 0xffff
|
||||
|| min < 0
|
||||
|| min > 0xffff
|
||||
|| !NM_STRCHAR_ALL (str, ch, ( g_ascii_isxdigit (ch)
|
||||
|| ch == ':'
|
||||
|| g_ascii_isspace (ch)))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TC_H_MAKE (maj << 16, min);
|
||||
return TC_H_MAKE (((guint32) maj) << 16, (guint32) min);
|
||||
fail:
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("'%s' is not a valid handle."), str);
|
||||
return TC_H_UNSPEC;
|
||||
}
|
||||
|
||||
#define TC_ATTR_SPEC_PTR(name, type, no_value, consumes_rest, str_type) \
|
||||
&(NMVariantAttributeSpec) { name, type, FALSE, FALSE, no_value, consumes_rest, str_type }
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_object_attribute_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("root", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("parent", G_VARIANT_TYPE_STRING, FALSE, FALSE, 'a' ),
|
||||
TC_ATTR_SPEC_PTR ("handle", G_VARIANT_TYPE_STRING, FALSE, FALSE, 'a' ),
|
||||
TC_ATTR_SPEC_PTR ("kind", G_VARIANT_TYPE_STRING, TRUE, FALSE, 'a' ),
|
||||
TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ),
|
||||
static const NMVariantAttributeSpec *const tc_object_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("root", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("parent", G_VARIANT_TYPE_STRING, .str_type = 'a', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("handle", G_VARIANT_TYPE_STRING, .str_type = 'a', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_qdisc_fq_codel_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("limit", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("flows", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("target", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("interval", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("quantum", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("ce_threshold", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("memory", G_VARIANT_TYPE_UINT32, FALSE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("ecn", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
static const NMVariantAttributeSpec *const tc_qdisc_fq_codel_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("limit", G_VARIANT_TYPE_UINT32, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("flows", G_VARIANT_TYPE_UINT32, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("target", G_VARIANT_TYPE_UINT32, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("interval", G_VARIANT_TYPE_UINT32, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("quantum", G_VARIANT_TYPE_UINT32, ),
|
||||
|
||||
/* 0x83126E97u is not a valid value (it means "disabled"). We should reject that
|
||||
* value. Or alternatively, reject all values >= MAX_INT(32). */
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ce_threshold", G_VARIANT_TYPE_UINT32, ),
|
||||
|
||||
/* kernel clamps the value at 2^31. Possibly such values should be rejected from configuration
|
||||
* as they cannot be configured. Leaving the attribute unspecified causes kernel to choose
|
||||
* a default (currently 32MB). */
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("memory_limit", G_VARIANT_TYPE_UINT32, ),
|
||||
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ecn", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *kind;
|
||||
const NMVariantAttributeSpec * const *attrs;
|
||||
const NMVariantAttributeSpec *const *attrs;
|
||||
} NMQdiscAttributeSpec;
|
||||
|
||||
static const NMQdiscAttributeSpec *const tc_qdisc_attribute_spec[] = {
|
||||
|
|
@ -2536,23 +2562,23 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_action_simple_attribute_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("sdata", G_VARIANT_TYPE_BYTESTRING, FALSE, FALSE, 0 ),
|
||||
static const NMVariantAttributeSpec *const tc_action_simple_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("sdata", G_VARIANT_TYPE_BYTESTRING, ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_action_mirred_attribute_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("egress", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("ingress", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("mirror", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("redirect", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("dev", G_VARIANT_TYPE_STRING, TRUE, FALSE, 'a' ),
|
||||
static const NMVariantAttributeSpec *const tc_action_mirred_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("egress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("ingress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("mirror", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("redirect", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("dev", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_action_attribute_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("kind", G_VARIANT_TYPE_STRING, TRUE, FALSE, 'a' ),
|
||||
TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ),
|
||||
static const NMVariantAttributeSpec *const tc_action_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, .str_type = 'a', ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -2621,7 +2647,7 @@ nm_utils_tc_action_from_str (const char *str, GError **error)
|
|||
gs_unref_hashtable GHashTable *ht = NULL;
|
||||
gs_unref_hashtable GHashTable *options = NULL;
|
||||
GVariant *variant;
|
||||
const NMVariantAttributeSpec * const *attrs;
|
||||
const NMVariantAttributeSpec *const *attrs;
|
||||
|
||||
nm_assert (str);
|
||||
nm_assert (!error || !*error);
|
||||
|
|
@ -2749,9 +2775,9 @@ nm_utils_tc_tfilter_to_str (NMTCTfilter *tfilter, GError **error)
|
|||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
static const NMVariantAttributeSpec * const tc_tfilter_attribute_spec[] = {
|
||||
TC_ATTR_SPEC_PTR ("action", G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
TC_ATTR_SPEC_PTR ("", G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a' ),
|
||||
static const NMVariantAttributeSpec *const tc_tfilter_attribute_spec[] = {
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("action", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ),
|
||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE ("", G_VARIANT_TYPE_STRING, .no_value = TRUE, .consumes_rest = TRUE, .str_type = 'a', ),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -6441,7 +6467,7 @@ nm_utils_parse_variant_attributes (const char *string,
|
|||
gs_unref_hashtable GHashTable *ht = NULL;
|
||||
const char *ptr = string, *start = NULL, *sep;
|
||||
GVariant *variant;
|
||||
const NMVariantAttributeSpec * const *s;
|
||||
const NMVariantAttributeSpec *const *s;
|
||||
|
||||
g_return_val_if_fail (string, NULL);
|
||||
g_return_val_if_fail (attr_separator, NULL);
|
||||
|
|
|
|||
|
|
@ -3088,6 +3088,60 @@ test_routing_rule (gconstpointer test_data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_parse_tc_handle (void)
|
||||
{
|
||||
#define _parse_tc_handle(str, exp) \
|
||||
G_STMT_START { \
|
||||
gs_free_error GError *_error = NULL; \
|
||||
GError **_perror = nmtst_get_rand_bool () ? &_error : NULL; \
|
||||
guint32 _v; \
|
||||
const guint32 _v_exp = (exp); \
|
||||
\
|
||||
_v = _nm_utils_parse_tc_handle (""str"", _perror); \
|
||||
\
|
||||
if (_v != _v_exp) \
|
||||
g_error ("%s:%d: \"%s\" gave %08x but %08x expected.", __FILE__, __LINE__, ""str"", _v, _v_exp); \
|
||||
\
|
||||
if (_v == TC_H_UNSPEC) \
|
||||
g_assert (!_perror || *_perror); \
|
||||
else \
|
||||
g_assert (!_perror || !*_perror); \
|
||||
\
|
||||
} G_STMT_END
|
||||
|
||||
#define _parse_tc_handle_inval(str) _parse_tc_handle (str, TC_H_UNSPEC)
|
||||
#define _parse_tc_handle_valid(str, maj, min) _parse_tc_handle (str, TC_H_MAKE (((guint32) (maj)) << 16, ((guint16) (min))))
|
||||
|
||||
_parse_tc_handle_inval ("");
|
||||
_parse_tc_handle_inval (" ");
|
||||
_parse_tc_handle_inval (" \n");
|
||||
_parse_tc_handle_valid ("1", 1, 0);
|
||||
_parse_tc_handle_valid(" 1 ", 1, 0);
|
||||
_parse_tc_handle_valid ("1:", 1, 0);
|
||||
_parse_tc_handle_valid ("1: ", 1, 0);
|
||||
_parse_tc_handle_valid ("1:0", 1, 0);
|
||||
_parse_tc_handle_valid ("1 :0", 1, 0);
|
||||
_parse_tc_handle_valid ("1 \t\n\f\r:0", 1, 0);
|
||||
_parse_tc_handle_inval ("1 \t\n\f\r\v:0");
|
||||
_parse_tc_handle_valid (" 1 : 0 ", 1, 0);
|
||||
_parse_tc_handle_inval (" \t\v\n1: 0");
|
||||
_parse_tc_handle_valid ("1:2", 1, 2);
|
||||
_parse_tc_handle_valid ("01:02", 1, 2);
|
||||
_parse_tc_handle_inval ("0x01:0x02");
|
||||
_parse_tc_handle_valid (" 01: 02", 1, 2);
|
||||
_parse_tc_handle_valid ("019: 020", 0x19, 0x20);
|
||||
_parse_tc_handle_valid ("FFFF: 020", 0xFFFF, 0x20);
|
||||
_parse_tc_handle_valid ("FfFF: ffff", 0xFFFF, 0xFFFF);
|
||||
_parse_tc_handle_valid ("FFFF", 0xFFFF, 0);
|
||||
_parse_tc_handle_inval ("0xFFFF");
|
||||
_parse_tc_handle_inval ("10000");
|
||||
_parse_tc_handle_valid ("\t\n\f\r FFFF", 0xFFFF, 0);
|
||||
_parse_tc_handle_inval ("\t\n\f\r \vFFFF");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int
|
||||
|
|
@ -3173,5 +3227,7 @@ main (int argc, char **argv)
|
|||
|
||||
g_test_add_data_func ("/libnm/settings/routing-rule/1", GINT_TO_POINTER (0), test_routing_rule);
|
||||
|
||||
g_test_add_func ("/libnm/parse-tc-handle", test_parse_tc_handle);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -734,10 +734,7 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
|
|||
gint64 v;
|
||||
const char *s = NULL;
|
||||
|
||||
if (str) {
|
||||
while (g_ascii_isspace (str[0]))
|
||||
str++;
|
||||
}
|
||||
str = nm_str_skip_leading_spaces (str);
|
||||
if (!str || !str[0]) {
|
||||
errno = EINVAL;
|
||||
return fallback;
|
||||
|
|
@ -748,9 +745,9 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
|
|||
|
||||
if (errno != 0)
|
||||
return fallback;
|
||||
|
||||
if (s[0] != '\0') {
|
||||
while (g_ascii_isspace (s[0]))
|
||||
s++;
|
||||
s = nm_str_skip_leading_spaces (s);
|
||||
if (s[0] != '\0') {
|
||||
errno = EINVAL;
|
||||
return fallback;
|
||||
|
|
|
|||
|
|
@ -6500,7 +6500,7 @@ tc_commit (NMDevice *self)
|
|||
NMSettingTCConfig *s_tc = NULL;
|
||||
int ip_ifindex;
|
||||
guint nqdiscs, ntfilters;
|
||||
int i;
|
||||
guint i;
|
||||
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
if (connection)
|
||||
|
|
@ -6508,7 +6508,7 @@ tc_commit (NMDevice *self)
|
|||
|
||||
ip_ifindex = nm_device_get_ip_ifindex (self);
|
||||
if (!ip_ifindex)
|
||||
return s_tc == NULL;
|
||||
return s_tc == NULL;
|
||||
|
||||
if (s_tc) {
|
||||
nqdiscs = nm_setting_tc_config_get_num_qdiscs (s_tc);
|
||||
|
|
@ -6520,7 +6520,12 @@ tc_commit (NMDevice *self)
|
|||
NMPlatformQdisc *qdisc = NMP_OBJECT_CAST_QDISC (q);
|
||||
|
||||
qdisc->ifindex = ip_ifindex;
|
||||
|
||||
/* Note: kind string is still owned by NMTCTfilter.
|
||||
* This qdisc instance must not be kept alive beyond this function.
|
||||
* nm_platform_qdisc_sync() promises to do that. */
|
||||
qdisc->kind = nm_tc_qdisc_get_kind (s_qdisc);
|
||||
|
||||
qdisc->addr_family = AF_UNSPEC;
|
||||
qdisc->handle = nm_tc_qdisc_get_handle (s_qdisc);
|
||||
qdisc->parent = nm_tc_qdisc_get_parent (s_qdisc);
|
||||
|
|
@ -6537,14 +6542,14 @@ tc_commit (NMDevice *self)
|
|||
} G_STMT_END
|
||||
|
||||
if (strcmp (qdisc->kind, "fq_codel") == 0) {
|
||||
GET_ATTR("limit", qdisc->fq_codel.limit, UINT32, uint32, 0);
|
||||
GET_ATTR("flows", qdisc->fq_codel.flows, UINT32, uint32, 0);
|
||||
GET_ATTR("target", qdisc->fq_codel.target, UINT32, uint32, 0);
|
||||
GET_ATTR("interval", qdisc->fq_codel.interval, UINT32, uint32, 0);
|
||||
GET_ATTR("quantum", qdisc->fq_codel.quantum, UINT32, uint32, 0);
|
||||
GET_ATTR("ce_threshold", qdisc->fq_codel.ce_threshold, UINT32, uint32, -1);
|
||||
GET_ATTR("memory", qdisc->fq_codel.memory, UINT32, uint32, -1);
|
||||
GET_ATTR("ecn", qdisc->fq_codel.ecn, BOOLEAN, boolean, FALSE);
|
||||
GET_ATTR ("limit", qdisc->fq_codel.limit, UINT32, uint32, 0);
|
||||
GET_ATTR ("flows", qdisc->fq_codel.flows, UINT32, uint32, 0);
|
||||
GET_ATTR ("target", qdisc->fq_codel.target, UINT32, uint32, 0);
|
||||
GET_ATTR ("interval", qdisc->fq_codel.interval, UINT32, uint32, 0);
|
||||
GET_ATTR ("quantum", qdisc->fq_codel.quantum, UINT32, uint32, 0);
|
||||
GET_ATTR ("ce_threshold", qdisc->fq_codel.ce_threshold, UINT32, uint32, NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED);
|
||||
GET_ATTR ("memory_limit", qdisc->fq_codel.memory_limit, UINT32, uint32, NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET);
|
||||
GET_ATTR ("ecn", qdisc->fq_codel.ecn, BOOLEAN, boolean, FALSE);
|
||||
}
|
||||
|
||||
#undef GET_ADDR
|
||||
|
|
@ -6562,7 +6567,12 @@ tc_commit (NMDevice *self)
|
|||
NMPlatformTfilter *tfilter = NMP_OBJECT_CAST_TFILTER (q);
|
||||
|
||||
tfilter->ifindex = ip_ifindex;
|
||||
|
||||
/* Note: kind string is still owned by NMTCTfilter.
|
||||
* This tfilter instance must not be kept alive beyond this function.
|
||||
* nm_platform_tfilter_sync() promises to do that. */
|
||||
tfilter->kind = nm_tc_tfilter_get_kind (s_tfilter);
|
||||
|
||||
tfilter->addr_family = AF_UNSPEC;
|
||||
tfilter->handle = nm_tc_tfilter_get_handle (s_tfilter);
|
||||
tfilter->parent = nm_tc_tfilter_get_parent (s_tfilter);
|
||||
|
|
@ -6572,7 +6582,11 @@ tc_commit (NMDevice *self)
|
|||
if (action) {
|
||||
GVariant *var;
|
||||
|
||||
/* Note: kind string is still owned by NMTCAction.
|
||||
* This tfilter instance must not be kept alive beyond this function.
|
||||
* nm_platform_tfilter_sync() promises to do that. */
|
||||
tfilter->action.kind = nm_tc_action_get_kind (action);
|
||||
|
||||
if (strcmp (tfilter->action.kind, "simple") == 0) {
|
||||
var = nm_tc_action_get_attribute (action, "sdata");
|
||||
if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_BYTESTRING)) {
|
||||
|
|
@ -6595,9 +6609,12 @@ tc_commit (NMDevice *self)
|
|||
|
||||
var = nm_tc_action_get_attribute (action, "dev");
|
||||
if (var && g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)) {
|
||||
int ifindex = nm_platform_link_get_ifindex (nm_device_get_platform (self),
|
||||
g_variant_get_string (var, NULL));
|
||||
tfilter->action.mirred.ifindex = ifindex;
|
||||
int ifindex;
|
||||
|
||||
ifindex = nm_platform_link_get_ifindex (nm_device_get_platform (self),
|
||||
g_variant_get_string (var, NULL));
|
||||
if (ifindex > 0)
|
||||
tfilter->action.mirred.ifindex = ifindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3515,6 +3515,11 @@ _new_from_nl_qdisc (struct nlmsghdr *nlh, gboolean id_only)
|
|||
obj->qdisc.parent = tcm->tcm_parent;
|
||||
obj->qdisc.info = tcm->tcm_info;
|
||||
|
||||
if (nm_streq0 (obj->qdisc.kind, "fq_codel")) {
|
||||
obj->qdisc.fq_codel.memory_limit = NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET;
|
||||
obj->qdisc.fq_codel.ce_threshold = NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED;
|
||||
}
|
||||
|
||||
if (tb[TCA_OPTIONS]) {
|
||||
struct nlattr *options_attr;
|
||||
int remaining;
|
||||
|
|
@ -3544,10 +3549,10 @@ _new_from_nl_qdisc (struct nlmsghdr *nlh, gboolean id_only)
|
|||
obj->qdisc.fq_codel.ce_threshold = nla_get_u32 (options_attr);
|
||||
break;
|
||||
case TCA_FQ_CODEL_MEMORY_LIMIT:
|
||||
obj->qdisc.fq_codel.memory = nla_get_u32 (options_attr);
|
||||
obj->qdisc.fq_codel.memory_limit = nla_get_u32 (options_attr);
|
||||
break;
|
||||
case TCA_FQ_CODEL_ECN:
|
||||
obj->qdisc.fq_codel.ecn = nla_get_u32 (options_attr);
|
||||
obj->qdisc.fq_codel.ecn = !!nla_get_u32 (options_attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3676,7 +3681,7 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg,
|
|||
|
||||
return TRUE;
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -3827,7 +3832,7 @@ _nl_msg_new_link_set_linkinfo_vlan (struct nl_msg *msg,
|
|||
|
||||
return TRUE;
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static struct nl_msg *
|
||||
|
|
@ -4239,12 +4244,12 @@ _nl_msg_new_qdisc (int nlmsg_type,
|
|||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_INTERVAL, qdisc->fq_codel.interval);
|
||||
if (qdisc->fq_codel.quantum)
|
||||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_QUANTUM, qdisc->fq_codel.quantum);
|
||||
if (qdisc->fq_codel.ce_threshold != -1)
|
||||
if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED)
|
||||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_CE_THRESHOLD, qdisc->fq_codel.ce_threshold);
|
||||
if (qdisc->fq_codel.memory != -1)
|
||||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_MEMORY_LIMIT, qdisc->fq_codel.memory);
|
||||
if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET)
|
||||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_MEMORY_LIMIT, qdisc->fq_codel.memory_limit);
|
||||
if (qdisc->fq_codel.ecn)
|
||||
NLA_PUT_S32 (msg, TCA_FQ_CODEL_ECN, qdisc->fq_codel.ecn);
|
||||
NLA_PUT_U32 (msg, TCA_FQ_CODEL_ECN, qdisc->fq_codel.ecn);
|
||||
}
|
||||
|
||||
nla_nest_end (msg, tc_options);
|
||||
|
|
@ -4255,83 +4260,6 @@ nla_put_failure:
|
|||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_add_action_simple (struct nl_msg *msg,
|
||||
const NMPlatformActionSimple *simple)
|
||||
{
|
||||
struct nlattr *act_options;
|
||||
struct tc_defact sel = { 0, };
|
||||
|
||||
if (!(act_options = nla_nest_start (msg, TCA_ACT_OPTIONS)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT (msg, TCA_DEF_PARMS, sizeof (sel), &sel);
|
||||
NLA_PUT (msg, TCA_DEF_DATA, sizeof (simple->sdata), simple->sdata);
|
||||
|
||||
nla_nest_end (msg, act_options);
|
||||
|
||||
return TRUE;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_add_action_mirred (struct nl_msg *msg,
|
||||
const NMPlatformActionMirred *mirred)
|
||||
{
|
||||
struct nlattr *act_options;
|
||||
struct tc_mirred sel = { 0, };
|
||||
|
||||
if (!(act_options = nla_nest_start (msg, TCA_ACT_OPTIONS)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (mirred->egress && mirred->redirect)
|
||||
sel.eaction = TCA_EGRESS_REDIR;
|
||||
else if (mirred->egress && mirred->mirror)
|
||||
sel.eaction = TCA_EGRESS_MIRROR;
|
||||
else if (mirred->ingress && mirred->redirect)
|
||||
sel.eaction = TCA_INGRESS_REDIR;
|
||||
else if (mirred->ingress && mirred->mirror)
|
||||
sel.eaction = TCA_INGRESS_MIRROR;
|
||||
sel.ifindex = mirred->ifindex;
|
||||
|
||||
NLA_PUT (msg, TCA_MIRRED_PARMS, sizeof (sel), &sel);
|
||||
|
||||
nla_nest_end (msg, act_options);
|
||||
|
||||
return TRUE;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_add_action (struct nl_msg *msg,
|
||||
const NMPlatformAction *action)
|
||||
{
|
||||
struct nlattr *prio;
|
||||
|
||||
nm_assert (action || action->kind);
|
||||
|
||||
if (!(prio = nla_nest_start (msg, 1 /* priority */)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_STRING (msg, TCA_ACT_KIND, action->kind);
|
||||
|
||||
if (nm_streq (action->kind, NM_PLATFORM_ACTION_KIND_SIMPLE))
|
||||
_add_action_simple (msg, &action->simple);
|
||||
else if (nm_streq (action->kind, NM_PLATFORM_ACTION_KIND_MIRRED))
|
||||
_add_action_mirred (msg, &action->mirred);
|
||||
|
||||
nla_nest_end (msg, prio);
|
||||
|
||||
return TRUE;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static struct nl_msg *
|
||||
_nl_msg_new_tfilter (int nlmsg_type,
|
||||
int nlmsg_flags,
|
||||
|
|
@ -4361,8 +4289,52 @@ _nl_msg_new_tfilter (int nlmsg_type,
|
|||
if (!(act_tab = nla_nest_start (msg, TCA_OPTIONS))) // 3 TCA_ACT_KIND TCA_ACT_KIND
|
||||
goto nla_put_failure;
|
||||
|
||||
if (tfilter->action.kind)
|
||||
_add_action (msg, &tfilter->action);
|
||||
if (tfilter->action.kind) {
|
||||
const NMPlatformAction *action = &tfilter->action;
|
||||
struct nlattr *prio;
|
||||
struct nlattr *act_options;
|
||||
|
||||
if (!(prio = nla_nest_start (msg, 1 /* priority */)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_STRING (msg, TCA_ACT_KIND, action->kind);
|
||||
|
||||
if (nm_streq (action->kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) {
|
||||
const NMPlatformActionSimple *simple = &action->simple;
|
||||
struct tc_defact sel = { 0, };
|
||||
|
||||
if (!(act_options = nla_nest_start (msg, TCA_ACT_OPTIONS)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT (msg, TCA_DEF_PARMS, sizeof (sel), &sel);
|
||||
NLA_PUT (msg, TCA_DEF_DATA, sizeof (simple->sdata), simple->sdata);
|
||||
|
||||
nla_nest_end (msg, act_options);
|
||||
|
||||
} else if (nm_streq (action->kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
||||
const NMPlatformActionMirred *mirred = &action->mirred;
|
||||
struct tc_mirred sel = { 0, };
|
||||
|
||||
if (!(act_options = nla_nest_start (msg, TCA_ACT_OPTIONS)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (mirred->egress && mirred->redirect)
|
||||
sel.eaction = TCA_EGRESS_REDIR;
|
||||
else if (mirred->egress && mirred->mirror)
|
||||
sel.eaction = TCA_EGRESS_MIRROR;
|
||||
else if (mirred->ingress && mirred->redirect)
|
||||
sel.eaction = TCA_INGRESS_REDIR;
|
||||
else if (mirred->ingress && mirred->mirror)
|
||||
sel.eaction = TCA_INGRESS_MIRROR;
|
||||
sel.ifindex = mirred->ifindex;
|
||||
|
||||
NLA_PUT (msg, TCA_MIRRED_PARMS, sizeof (sel), &sel);
|
||||
|
||||
nla_nest_end (msg, act_options);
|
||||
}
|
||||
|
||||
nla_nest_end (msg, prio);
|
||||
}
|
||||
|
||||
nla_nest_end (msg, tc_options);
|
||||
|
||||
|
|
@ -8273,6 +8245,9 @@ qdisc_add (NMPlatform *platform,
|
|||
char s_buf[256];
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
|
||||
/* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind
|
||||
* is undefined. */
|
||||
|
||||
msg = _nl_msg_new_qdisc (RTM_NEWQDISC, flags, qdisc);
|
||||
|
||||
event_handler_read_netlink (platform, FALSE);
|
||||
|
|
@ -8314,6 +8289,9 @@ tfilter_add (NMPlatform *platform,
|
|||
char s_buf[256];
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
|
||||
/* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind
|
||||
* and tfilter.action.kind is undefined. */
|
||||
|
||||
msg = _nl_msg_new_tfilter (RTM_NEWTFILTER, flags, tfilter);
|
||||
|
||||
event_handler_read_netlink (platform, FALSE);
|
||||
|
|
|
|||
|
|
@ -5077,10 +5077,27 @@ nm_platform_qdisc_add (NMPlatform *self,
|
|||
int ifindex = qdisc->ifindex;
|
||||
_CHECK_SELF (self, klass, -NME_BUG);
|
||||
|
||||
/* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind
|
||||
* is undefined. */
|
||||
|
||||
_LOG3D ("adding or updating a qdisc: %s", nm_platform_qdisc_to_string (qdisc, NULL, 0));
|
||||
return klass->qdisc_add (self, flags, qdisc);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_qdisc_sync:
|
||||
* @self: the #NMPlatform instance
|
||||
* @ifindex: the ifindex where to configure the qdiscs.
|
||||
* @known_qdiscs: the list of qdiscs (#NMPObject).
|
||||
*
|
||||
* The function promises not to take any reference to the qdisc
|
||||
* instances from @known_qdiscs, nor to keep them around after
|
||||
* the function returns. This is important, because it allows the
|
||||
* caller to pass NMPlatformQdisc instances which "kind" string
|
||||
* have a limited lifetime.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_platform_qdisc_sync (NMPlatform *self,
|
||||
int ifindex,
|
||||
|
|
@ -5143,10 +5160,27 @@ nm_platform_tfilter_add (NMPlatform *self,
|
|||
int ifindex = tfilter->ifindex;
|
||||
_CHECK_SELF (self, klass, -NME_BUG);
|
||||
|
||||
/* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind
|
||||
* and tfilter.action.kind is undefined. */
|
||||
|
||||
_LOG3D ("adding or updating a tfilter: %s", nm_platform_tfilter_to_string (tfilter, NULL, 0));
|
||||
return klass->tfilter_add (self, flags, tfilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_qdisc_sync:
|
||||
* @self: the #NMPlatform instance
|
||||
* @ifindex: the ifindex where to configure the qdiscs.
|
||||
* @known_tfilters: the list of tfilters (#NMPObject).
|
||||
*
|
||||
* The function promises not to take any reference to the tfilter
|
||||
* instances from @known_tfilters, nor to keep them around after
|
||||
* the function returns. This is important, because it allows the
|
||||
* caller to pass NMPlatformTfilter instances which "kind" string
|
||||
* have a limited lifetime.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_platform_tfilter_sync (NMPlatform *self,
|
||||
int ifindex,
|
||||
|
|
@ -6427,10 +6461,13 @@ const char *
|
|||
nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len)
|
||||
{
|
||||
char str_dev[TO_STRING_DEV_BUF_SIZE];
|
||||
const char *buf0;
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null (qdisc, &buf, &len))
|
||||
return buf;
|
||||
|
||||
buf0 = buf;
|
||||
|
||||
nm_utils_strbuf_append (&buf, &len, "%s%s family %u handle %x parent %x info %x",
|
||||
qdisc->kind,
|
||||
_to_string_dev (NULL, qdisc->ifindex, str_dev, sizeof (str_dev)),
|
||||
|
|
@ -6450,15 +6487,15 @@ nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len)
|
|||
nm_utils_strbuf_append (&buf, &len, " interval %u", qdisc->fq_codel.interval);
|
||||
if (qdisc->fq_codel.quantum)
|
||||
nm_utils_strbuf_append (&buf, &len, " quantum %u", qdisc->fq_codel.quantum);
|
||||
if (qdisc->fq_codel.ce_threshold != -1)
|
||||
if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED)
|
||||
nm_utils_strbuf_append (&buf, &len, " ce_threshold %u", qdisc->fq_codel.ce_threshold);
|
||||
if (qdisc->fq_codel.memory != -1)
|
||||
nm_utils_strbuf_append (&buf, &len, " memory %u", qdisc->fq_codel.memory);
|
||||
if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET)
|
||||
nm_utils_strbuf_append (&buf, &len, " memory_limit %u", qdisc->fq_codel.memory_limit);
|
||||
if (qdisc->fq_codel.ecn)
|
||||
nm_utils_strbuf_append (&buf, &len, " ecn");
|
||||
}
|
||||
|
||||
return buf;
|
||||
return buf0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -6479,8 +6516,9 @@ nm_platform_qdisc_hash_update (const NMPlatformQdisc *obj, NMHashState *h)
|
|||
obj->fq_codel.interval,
|
||||
obj->fq_codel.quantum,
|
||||
obj->fq_codel.ce_threshold,
|
||||
obj->fq_codel.memory,
|
||||
obj->fq_codel.ecn == TRUE);
|
||||
obj->fq_codel.memory_limit,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->fq_codel.ecn));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6502,8 +6540,8 @@ nm_platform_qdisc_cmp (const NMPlatformQdisc *a, const NMPlatformQdisc *b)
|
|||
NM_CMP_FIELD (a, b, fq_codel.interval);
|
||||
NM_CMP_FIELD (a, b, fq_codel.quantum);
|
||||
NM_CMP_FIELD (a, b, fq_codel.ce_threshold);
|
||||
NM_CMP_FIELD (a, b, fq_codel.memory);
|
||||
NM_CMP_FIELD (a, b, fq_codel.ecn == TRUE);
|
||||
NM_CMP_FIELD (a, b, fq_codel.memory_limit);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, fq_codel.ecn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -6573,11 +6611,12 @@ nm_platform_tfilter_hash_update (const NMPlatformTfilter *obj, NMHashState *h)
|
|||
nm_hash_update_strarr (h, obj->action.simple.sdata);
|
||||
} else if (nm_streq (obj->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
||||
nm_hash_update_vals (h,
|
||||
obj->action.mirred.ingress,
|
||||
obj->action.mirred.egress,
|
||||
obj->action.mirred.mirror,
|
||||
obj->action.mirred.redirect,
|
||||
obj->action.mirred.ifindex);
|
||||
obj->action.mirred.ifindex,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->action.mirred.ingress,
|
||||
obj->action.mirred.egress,
|
||||
obj->action.mirred.mirror,
|
||||
obj->action.mirred.redirect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6598,11 +6637,11 @@ nm_platform_tfilter_cmp (const NMPlatformTfilter *a, const NMPlatformTfilter *b)
|
|||
if (nm_streq (a->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) {
|
||||
NM_CMP_FIELD_STR (a, b, action.simple.sdata);
|
||||
} else if (nm_streq (a->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
||||
NM_CMP_FIELD (a, b, action.mirred.ingress);
|
||||
NM_CMP_FIELD (a, b, action.mirred.egress);
|
||||
NM_CMP_FIELD (a, b, action.mirred.mirror);
|
||||
NM_CMP_FIELD (a, b, action.mirred.redirect);
|
||||
NM_CMP_FIELD (a, b, action.mirred.ifindex);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, action.mirred.ingress);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, action.mirred.egress);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, action.mirred.mirror);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, action.mirred.redirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -596,20 +596,41 @@ typedef struct {
|
|||
bool uid_range_has:1; /* has(FRA_UID_RANGE) */
|
||||
} NMPlatformRoutingRule;
|
||||
|
||||
#define NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET (~((guint32) 0))
|
||||
|
||||
#define NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED ((guint32) 0x83126E97u)
|
||||
|
||||
G_STATIC_ASSERT (((((guint64) NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) * 1000u) >> 10) == (guint64) INT_MAX);
|
||||
|
||||
typedef struct {
|
||||
guint32 limit;
|
||||
guint32 flows;
|
||||
guint32 target;
|
||||
guint32 interval;
|
||||
guint32 quantum;
|
||||
guint32 ce_threshold;
|
||||
guint32 memory;
|
||||
guint32 ce_threshold; /* TCA_FQ_CODEL_CE_THRESHOLD: kernel internally stores this value as
|
||||
* ((val64 * NSEC_PER_USEC) >> CODEL_SHIFT). The default value (in
|
||||
* the domain with this coersion) is CODEL_DISABLED_THRESHOLD (INT_MAX).
|
||||
* That means, "disabled" is expressed on RTM_NEWQDISC netlink API by absence of the
|
||||
* netlink attribute but also as the special value 0x83126E97u
|
||||
* (NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED).
|
||||
* Beware: zero is not the default you must always explicitly set this value. */
|
||||
guint32 memory_limit; /* TCA_FQ_CODEL_MEMORY_LIMIT: note that only values <= 2^31 are accepted by kernel
|
||||
* and kernel defaults to 32MB.
|
||||
* Note that we use the special value NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET
|
||||
* to indicate that no explicit limit is set (when we send a RTM_NEWQDISC request).
|
||||
* This will cause kernel to choose the default (32MB).
|
||||
* Beware: zero is not the default you must always explicitly set this value. */
|
||||
bool ecn:1;
|
||||
} NMPlatformQdiscFqCodel;
|
||||
|
||||
typedef struct {
|
||||
__NMPlatformObjWithIfindex_COMMON;
|
||||
|
||||
/* beware, kind is embedded in an NMPObject, hence you must
|
||||
* take care of the lifetime of the string. */
|
||||
const char *kind;
|
||||
|
||||
int addr_family;
|
||||
guint32 handle;
|
||||
guint32 parent;
|
||||
|
|
@ -624,15 +645,19 @@ typedef struct {
|
|||
} NMPlatformActionSimple;
|
||||
|
||||
typedef struct {
|
||||
gboolean egress;
|
||||
gboolean ingress;
|
||||
gboolean mirror;
|
||||
gboolean redirect;
|
||||
int ifindex;
|
||||
bool egress:1;
|
||||
bool ingress:1;
|
||||
bool mirror:1;
|
||||
bool redirect:1;
|
||||
} NMPlatformActionMirred;
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* beware, kind is embedded in an NMPObject, hence you must
|
||||
* take care of the lifetime of the string. */
|
||||
const char *kind;
|
||||
|
||||
union {
|
||||
NMPlatformActionSimple simple;
|
||||
NMPlatformActionMirred mirred;
|
||||
|
|
@ -644,7 +669,11 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
__NMPlatformObjWithIfindex_COMMON;
|
||||
|
||||
/* beware, kind is embedded in an NMPObject, hence you must
|
||||
* take care of the lifetime of the string. */
|
||||
const char *kind;
|
||||
|
||||
int addr_family;
|
||||
guint32 handle;
|
||||
guint32 parent;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ _nl80211_alloc_msg (int id, int ifindex, int phy, guint32 cmd, guint32 flags)
|
|||
return g_steal_pointer (&msg);
|
||||
|
||||
nla_put_failure:
|
||||
return NULL;
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static struct nl_msg *
|
||||
|
|
@ -250,7 +250,7 @@ wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -267,7 +267,7 @@ wifi_nl80211_set_powersave (NMWifiUtils *data, guint32 powersave)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -365,7 +365,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
/* @divisor: pass what value @xbm should be divided by to get dBm */
|
||||
|
|
@ -642,7 +642,7 @@ nl80211_get_ap_info (NMWifiUtilsNl80211 *self,
|
|||
return;
|
||||
|
||||
nla_put_failure:
|
||||
return;
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
static guint32
|
||||
|
|
@ -695,7 +695,7 @@ wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
struct nl80211_device_info {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ _nl802154_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags)
|
|||
return g_steal_pointer (&msg);
|
||||
|
||||
nla_put_failure:
|
||||
return NULL;
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static struct nl_msg *
|
||||
|
|
@ -217,7 +217,7 @@ nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
guint16
|
||||
|
|
@ -244,7 +244,7 @@ nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -262,7 +262,7 @@ nm_wpan_utils_set_channel (NMWpanUtils *self, guint8 page, guint8 channel)
|
|||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
return FALSE;
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue