libnm-core: add functionality for dealing with tc-style traffic filter specifiers
Tailored to fit both nmcli and keyfile needs.
This commit is contained in:
@@ -2465,6 +2465,145 @@ nm_utils_tc_action_from_str (const char *str, GError **error)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _nm_utils_string_append_tc_tfilter_rest:
|
||||||
|
* @string: the string to write the formatted tfilter to
|
||||||
|
* @tfilter: the %NMTCTfilter
|
||||||
|
*
|
||||||
|
* This formats the rest of the tfilter string but the parent. Useful to format
|
||||||
|
* the keyfile value and nowhere else.
|
||||||
|
* Use nm_utils_tc_tfilter_to_str() that also includes the parent instead.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_nm_utils_string_append_tc_tfilter_rest (GString *string, NMTCTfilter *tfilter, GError **error)
|
||||||
|
{
|
||||||
|
guint32 handle = nm_tc_tfilter_get_handle (tfilter);
|
||||||
|
const char *kind = nm_tc_tfilter_get_kind (tfilter);
|
||||||
|
NMTCAction *action;
|
||||||
|
|
||||||
|
if (handle != TC_H_UNSPEC) {
|
||||||
|
g_string_append (string, "handle ");
|
||||||
|
_string_append_tc_handle (string, handle);
|
||||||
|
g_string_append_c (string, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_append (string, kind);
|
||||||
|
|
||||||
|
action = nm_tc_tfilter_get_action (tfilter);
|
||||||
|
if (action) {
|
||||||
|
g_string_append (string, " action ");
|
||||||
|
if (!_string_append_tc_action (string, action, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_tc_tfilter_to_str:
|
||||||
|
* @tfilter: the %NMTCTfilter
|
||||||
|
* @error: location of the error
|
||||||
|
*
|
||||||
|
* Turns the %NMTCTfilter into a tc style string representation of the queueing
|
||||||
|
* discipline.
|
||||||
|
*
|
||||||
|
* Returns: formatted string or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
nm_utils_tc_tfilter_to_str (NMTCTfilter *tfilter, GError **error)
|
||||||
|
{
|
||||||
|
GString *string;
|
||||||
|
|
||||||
|
string = g_string_sized_new (60);
|
||||||
|
|
||||||
|
_nm_utils_string_append_tc_parent (string, "parent",
|
||||||
|
nm_tc_tfilter_get_parent (tfilter));
|
||||||
|
if (!_nm_utils_string_append_tc_tfilter_rest (string, tfilter, error)) {
|
||||||
|
g_string_free (string, TRUE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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' ),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_tc_tfilter_from_str:
|
||||||
|
* @str: the string representation of a tfilter
|
||||||
|
* @error: location of the error
|
||||||
|
*
|
||||||
|
* Parces the tc style string tfilter representation of the queueing
|
||||||
|
* discipline to a %NMTCTfilter instance. Supports a subset of the tc language.
|
||||||
|
*
|
||||||
|
* Returns: the %NMTCTfilter or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
NMTCTfilter *
|
||||||
|
nm_utils_tc_tfilter_from_str (const char *str, GError **error)
|
||||||
|
{
|
||||||
|
guint32 handle = TC_H_UNSPEC;
|
||||||
|
guint32 parent = TC_H_UNSPEC;
|
||||||
|
gs_free char *kind = NULL;
|
||||||
|
gs_free char *rest = NULL;
|
||||||
|
NMTCAction *action = NULL;
|
||||||
|
const char *extra_opts = NULL;
|
||||||
|
NMTCTfilter *tfilter = NULL;
|
||||||
|
gs_unref_hashtable GHashTable *ht = NULL;
|
||||||
|
GVariant *variant;
|
||||||
|
|
||||||
|
nm_assert (str);
|
||||||
|
nm_assert (!error || !*error);
|
||||||
|
|
||||||
|
if (!_tc_read_common_opts (str, &handle, &parent, &kind, &rest, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (rest) {
|
||||||
|
ht = nm_utils_parse_variant_attributes (rest,
|
||||||
|
' ', ' ', FALSE,
|
||||||
|
tc_tfilter_attribute_spec,
|
||||||
|
error);
|
||||||
|
if (!ht)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
variant = g_hash_table_lookup (ht, "");
|
||||||
|
if (variant)
|
||||||
|
extra_opts = g_variant_get_string (variant, NULL);
|
||||||
|
|
||||||
|
if (g_hash_table_contains (ht, "action")) {
|
||||||
|
action = nm_utils_tc_action_from_str (extra_opts, error);
|
||||||
|
if (!action) {
|
||||||
|
g_prefix_error (error, _("invalid action: "));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_set_error (error, 1, 0, _("unsupported tfilter option: '%s'."), rest);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tfilter = nm_tc_tfilter_new (kind, parent, error);
|
||||||
|
if (!tfilter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
nm_tc_tfilter_set_handle (tfilter, handle);
|
||||||
|
if (action) {
|
||||||
|
nm_tc_tfilter_set_action (tfilter, action);
|
||||||
|
nm_tc_action_unref (action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_utils_uuid_generate_buf_:
|
* nm_utils_uuid_generate_buf_:
|
||||||
* @buf: input buffer, must contain at least 37 bytes
|
* @buf: input buffer, must contain at least 37 bytes
|
||||||
|
@@ -243,6 +243,11 @@ NMTCAction *nm_utils_tc_action_from_str (const char *str, GError **error);
|
|||||||
NM_AVAILABLE_IN_1_12
|
NM_AVAILABLE_IN_1_12
|
||||||
char *nm_utils_tc_action_to_str (NMTCAction *action, GError **error);
|
char *nm_utils_tc_action_to_str (NMTCAction *action, GError **error);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_12
|
||||||
|
NMTCTfilter *nm_utils_tc_tfilter_from_str (const char *str, GError **error);
|
||||||
|
NM_AVAILABLE_IN_1_12
|
||||||
|
char *nm_utils_tc_tfilter_to_str (NMTCTfilter *tfilter, GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __NM_UTILS_H__ */
|
#endif /* __NM_UTILS_H__ */
|
||||||
|
@@ -1284,6 +1284,8 @@ global:
|
|||||||
nm_utils_tc_action_to_str;
|
nm_utils_tc_action_to_str;
|
||||||
nm_utils_tc_qdisc_from_str;
|
nm_utils_tc_qdisc_from_str;
|
||||||
nm_utils_tc_qdisc_to_str;
|
nm_utils_tc_qdisc_to_str;
|
||||||
|
nm_utils_tc_tfilter_from_str;
|
||||||
|
nm_utils_tc_tfilter_to_str;
|
||||||
} libnm_1_10_0;
|
} libnm_1_10_0;
|
||||||
|
|
||||||
libnm_1_12_0 {
|
libnm_1_12_0 {
|
||||||
|
Reference in New Issue
Block a user