rte_tm.h(3)

๐ŸŒธ rte_tm.h ๐ŸŒธ

okay bestie, buckle in, because this is the RTE Generic Traffic Manager API header, and she is long. like, five-parts long. we got this tho ๐Ÿ’ชโœจ

Manual: Library Functions Manual, section 3 (library functions). iykyk.


๐Ÿ’– NAME ๐Ÿ’–

rte_tm.h โ€” the header that holds the whole generic traffic manager API. that's it, that's the name. simple queen behavior ๐Ÿ‘‘


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

first things first, she pulls in her little include squad:

#include <stdint.h>
#include <rte_common.h>
#include <rte_meter.h>
#include <rte_compat.h>

๐ŸŽ€ Data Structures

here's the whole cast of structs, no cap:

  • struct rte_tm_node_stats
  • struct rte_tm_capabilities
  • struct rte_tm_level_capabilities
  • struct rte_tm_node_capabilities
  • struct rte_tm_red_params
  • struct rte_tm_wred_params
  • struct rte_tm_token_bucket
  • struct rte_tm_shaper_params
  • struct rte_tm_node_params
  • struct rte_tm_error

โœจ Macros

the magic numbers, all iconic, all exactly as written:

#define RTE_TM_ETH_FRAMING_OVERHEAD   20
#define RTE_TM_ETH_FRAMING_OVERHEAD_FCS   24
#define RTE_TM_WRED_PROFILE_ID_NONE   UINT32_MAX
#define RTE_TM_SHAPER_PROFILE_ID_NONE   UINT32_MAX
#define RTE_TM_NODE_ID_NULL   UINT32_MAX
#define RTE_TM_NODE_LEVEL_ID_ANY   UINT32_MAX

๐Ÿ’… Enumerations

enum rte_tm_stats_type

{
    RTE_TM_STATS_N_PKTS = 1 << 0,
    RTE_TM_STATS_N_BYTES = 1 << 1,
    RTE_TM_STATS_N_PKTS_GREEN_DROPPED = 1 << 2,
    RTE_TM_STATS_N_PKTS_YELLOW_DROPPED = 1 << 3,
    RTE_TM_STATS_N_PKTS_RED_DROPPED = 1 << 4,
    RTE_TM_STATS_N_BYTES_GREEN_DROPPED = 1 << 5,
    RTE_TM_STATS_N_BYTES_YELLOW_DROPPED = 1 << 6,
    RTE_TM_STATS_N_BYTES_RED_DROPPED = 1 << 7,
    RTE_TM_STATS_N_PKTS_QUEUED = 1 << 8,
    RTE_TM_STATS_N_BYTES_QUEUED = 1 << 9
}

enum rte_tm_dynamic_update_type

{
    RTE_TM_UPDATE_NODE_PARENT_KEEP_LEVEL = 1 << 0,
    RTE_TM_UPDATE_NODE_PARENT_CHANGE_LEVEL = 1 << 1,
    RTE_TM_UPDATE_NODE_ADD_DELETE = 1 << 2,
    RTE_TM_UPDATE_NODE_SUSPEND_RESUME = 1 << 3,
    RTE_TM_UPDATE_NODE_WFQ_WEIGHT_MODE = 1 << 4,
    RTE_TM_UPDATE_NODE_N_SP_PRIORITIES = 1 << 5,
    RTE_TM_UPDATE_NODE_CMAN = 1 << 6,
    RTE_TM_UPDATE_NODE_STATS = 1 << 7
}

enum rte_tm_cman_mode

{
    RTE_TM_CMAN_TAIL_DROP = 0,
    RTE_TM_CMAN_HEAD_DROP,
    RTE_TM_CMAN_WRED
}

enum rte_tm_error_type

{
    RTE_TM_ERROR_TYPE_NONE,
    RTE_TM_ERROR_TYPE_UNSPECIFIED,
    RTE_TM_ERROR_TYPE_CAPABILITIES,
    RTE_TM_ERROR_TYPE_LEVEL_ID,
    RTE_TM_ERROR_TYPE_WRED_PROFILE,
    RTE_TM_ERROR_TYPE_WRED_PROFILE_GREEN,
    RTE_TM_ERROR_TYPE_WRED_PROFILE_YELLOW,
    RTE_TM_ERROR_TYPE_WRED_PROFILE_RED,
    RTE_TM_ERROR_TYPE_WRED_PROFILE_ID,
    RTE_TM_ERROR_TYPE_SHARED_WRED_CONTEXT_ID,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE,
    RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
    RTE_TM_ERROR_TYPE_SHARED_SHAPER_ID,
    RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
    RTE_TM_ERROR_TYPE_NODE_PRIORITY,
    RTE_TM_ERROR_TYPE_NODE_WEIGHT,
    RTE_TM_ERROR_TYPE_NODE_PARAMS,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS,
    RTE_TM_ERROR_TYPE_NODE_PARAMS_STATS,
    RTE_TM_ERROR_TYPE_NODE_ID
}

๐Ÿ”ฅ Functions

and here's the whole function roster โ€” every single one, verbatim, because we do NOT skip anybody in this house:

int rte_tm_get_number_of_leaf_nodes (uint16_t port_id, uint32_t *n_leaf_nodes, struct rte_tm_error *error)
int rte_tm_node_type_get (uint16_t port_id, uint32_t node_id, int *is_leaf, struct rte_tm_error *error)
int rte_tm_capabilities_get (uint16_t port_id, struct rte_tm_capabilities *cap, struct rte_tm_error *error)
int rte_tm_level_capabilities_get (uint16_t port_id, uint32_t level_id, struct rte_tm_level_capabilities *cap, struct rte_tm_error *error)
int rte_tm_node_capabilities_get (uint16_t port_id, uint32_t node_id, struct rte_tm_node_capabilities *cap, struct rte_tm_error *error)
int rte_tm_wred_profile_add (uint16_t port_id, uint32_t wred_profile_id, const struct rte_tm_wred_params *profile, struct rte_tm_error *error)
int rte_tm_wred_profile_delete (uint16_t port_id, uint32_t wred_profile_id, struct rte_tm_error *error)
int rte_tm_shared_wred_context_add_update (uint16_t port_id, uint32_t shared_wred_context_id, uint32_t wred_profile_id, struct rte_tm_error *error)
int rte_tm_shared_wred_context_delete (uint16_t port_id, uint32_t shared_wred_context_id, struct rte_tm_error *error)
int rte_tm_shaper_profile_add (uint16_t port_id, uint32_t shaper_profile_id, const struct rte_tm_shaper_params *profile, struct rte_tm_error *error)
int rte_tm_shaper_profile_delete (uint16_t port_id, uint32_t shaper_profile_id, struct rte_tm_error *error)
int rte_tm_shared_shaper_add_update (uint16_t port_id, uint32_t shared_shaper_id, uint32_t shaper_profile_id, struct rte_tm_error *error)
int rte_tm_shared_shaper_delete (uint16_t port_id, uint32_t shared_shaper_id, struct rte_tm_error *error)
int rte_tm_node_add (uint16_t port_id, uint32_t node_id, uint32_t parent_node_id, uint32_t priority, uint32_t weight, uint32_t level_id, const struct rte_tm_node_params *params, struct rte_tm_error *error)
__rte_experimental int rte_tm_node_query (uint16_t port_id, uint32_t node_id, uint32_t *parent_node_id, uint32_t *priority, uint32_t *weight, uint32_t *level_id, struct rte_tm_node_params *params, struct rte_tm_error *error)
int rte_tm_node_delete (uint16_t port_id, uint32_t node_id, struct rte_tm_error *error)
int rte_tm_node_suspend (uint16_t port_id, uint32_t node_id, struct rte_tm_error *error)
int rte_tm_node_resume (uint16_t port_id, uint32_t node_id, struct rte_tm_error *error)
int rte_tm_hierarchy_commit (uint16_t port_id, int clear_on_fail, struct rte_tm_error *error)
int rte_tm_node_parent_update (uint16_t port_id, uint32_t node_id, uint32_t parent_node_id, uint32_t priority, uint32_t weight, struct rte_tm_error *error)
int rte_tm_node_shaper_update (uint16_t port_id, uint32_t node_id, uint32_t shaper_profile_id, struct rte_tm_error *error)
int rte_tm_node_shared_shaper_update (uint16_t port_id, uint32_t node_id, uint32_t shared_shaper_id, int add, struct rte_tm_error *error)
int rte_tm_node_stats_update (uint16_t port_id, uint32_t node_id, uint64_t stats_mask, struct rte_tm_error *error)
int rte_tm_node_wfq_weight_mode_update (uint16_t port_id, uint32_t node_id, int *wfq_weight_mode, uint32_t n_sp_priorities, struct rte_tm_error *error)
int rte_tm_node_cman_update (uint16_t port_id, uint32_t node_id, enum rte_tm_cman_mode cman, struct rte_tm_error *error)
int rte_tm_node_wred_context_update (uint16_t port_id, uint32_t node_id, uint32_t wred_profile_id, struct rte_tm_error *error)
int rte_tm_node_shared_wred_context_update (uint16_t port_id, uint32_t node_id, uint32_t shared_wred_context_id, int add, struct rte_tm_error *error)
int rte_tm_node_stats_read (uint16_t port_id, uint32_t node_id, struct rte_tm_node_stats *stats, uint64_t *stats_mask, int clear, struct rte_tm_error *error)
int rte_tm_mark_vlan_dei (uint16_t port_id, int mark_green, int mark_yellow, int mark_red, struct rte_tm_error *error)
int rte_tm_mark_ip_ecn (uint16_t port_id, int mark_green, int mark_yellow, int mark_red, struct rte_tm_error *error)
int rte_tm_mark_ip_dscp (uint16_t port_id, int mark_green, int mark_yellow, int mark_red, struct rte_tm_error *error)
psst โ€” heads up: rte_tm_node_query is marked __rte_experimental, so like, tread carefully bestie, experimental means experimental ๐Ÿ’€

๐Ÿ’œ Detailed Description ๐Ÿ’œ

so what is this whole thing? it's the RTE Generic Traffic Manager API.

the vibe: this interface lets you configure the traffic manager in a generic way. and she comes with a whole friend group of features โ€” we're talking:

  • hierarchical scheduling
  • traffic shaping
  • congestion management
  • packet marking
  • etc.
๐Ÿ“Œ Definition in file rte_tm.h.

โœจ Macro Definition Documentation โœจ

#define RTE_TM_ETH_FRAMING_OVERHEAD 20

bestie this is the Ethernet framing overhead. the overhead fields per Ethernet frame are, in order:

  1. Preamble: 7 bytes;
  2. Start of Frame Delimiter (SFD): 1 byte;
  3. Inter-Frame Gap (IFG): 12 bytes.

this is one of the typical values you'd drop into the pkt_length_adjust field of the shaper profile.

See also

  • struct rte_tm_shaper_params
๐Ÿ“Œ Definition at line 42 of file rte_tm.h.

#define RTE_TM_ETH_FRAMING_OVERHEAD_FCS 24

same energy as above but make it include the Frame Check Sequence (FCS) field. this one's your girl when the FCS is generated and added at the end of the Ethernet frame on the Tx side, with absolutely no SW intervention. iconic.

another one of the typical values for the pkt_length_adjust field of the shaper profile.

See also

  • struct rte_tm_shaper_params
๐Ÿ“Œ Definition at line 54 of file rte_tm.h.

#define RTE_TM_WRED_PROFILE_ID_NONE UINT32_MAX

the invalid WRED profile ID. that's the whole point of her โ€” she means "none".

See also

  • struct rte_tm_node_params
  • rte_tm_node_add()
  • rte_tm_node_wred_context_update()
๐Ÿ“Œ Definition at line 63 of file rte_tm.h.

#define RTE_TM_SHAPER_PROFILE_ID_NONE UINT32_MAX

the invalid shaper profile ID. again, "none" is the assignment.

See also

  • struct rte_tm_node_params
  • rte_tm_node_add()
  • rte_tm_node_shaper_update()
๐Ÿ“Œ Definition at line 72 of file rte_tm.h.

#define RTE_TM_NODE_ID_NULL UINT32_MAX

this is the Node ID for the parent of the root node. so when you need to say "my parent is... nobody, i'm the root", you say this.

See also

  • rte_tm_node_add()
๐Ÿ“Œ Definition at line 79 of file rte_tm.h.

#define RTE_TM_NODE_LEVEL_ID_ANY UINT32_MAX

the Node level ID used to disable level ID checking. you're basically telling the checks "don't worry about it ๐Ÿ’…".

See also

  • rte_tm_node_add()
๐Ÿ“Œ Definition at line 86 of file rte_tm.h.

๐ŸŒธ Enumeration Type Documentation ๐ŸŒธ

enum rte_tm_stats_type

bestie this one is the Node statistics counter type list, aka all the lil counters a node can keep track of ๐Ÿ‘‘

Enumerator

  • RTE_TM_STATS_N_PKTS โ€” how many packets got scheduled out of the current node, periodt ๐Ÿ“ฆ
  • RTE_TM_STATS_N_BYTES โ€” how many bytes got scheduled out of the current node ๐Ÿ’พ
  • RTE_TM_STATS_N_PKTS_GREEN_DROPPED โ€” green packets that the current leaf node straight up dropped ๐Ÿ’š๐Ÿ˜ญ
  • RTE_TM_STATS_N_PKTS_YELLOW_DROPPED โ€” yellow packets dropped by the current leaf node ๐Ÿ’›๐Ÿ˜ญ
  • RTE_TM_STATS_N_PKTS_RED_DROPPED โ€” red packets dropped by the current leaf node โค๏ธ๐Ÿ˜ญ
  • RTE_TM_STATS_N_BYTES_GREEN_DROPPED โ€” green bytes dropped by the current leaf node ๐Ÿ’š
  • RTE_TM_STATS_N_BYTES_YELLOW_DROPPED โ€” yellow bytes dropped by the current leaf node ๐Ÿ’›
  • RTE_TM_STATS_N_BYTES_RED_DROPPED โ€” red bytes dropped by the current leaf node โค๏ธ
  • RTE_TM_STATS_N_PKTS_QUEUED โ€” packets currently justโ€ฆ sitting there waiting in the packet queue of the current leaf node ๐Ÿ• (real "in my queue era" energy)
  • RTE_TM_STATS_N_BYTES_QUEUED โ€” bytes currently waiting in the packet queue of the current leaf node ๐Ÿ•

Definition at line 91 of file rte_tm.h.


enum rte_tm_dynamic_update_type

this is the Traffic manager dynamic updates menu โ€” all the live glow-up moves you can do without a rebuild โœจ

Enumerator

  • RTE_TM_UPDATE_NODE_PARENT_KEEP_LEVEL โ€” dynamic parent node update. The new parent node lives on the same hierarchy level as the former parent node. So the node whose parent changed? Keeps its hierarchy level, no cap ๐Ÿซถ
  • RTE_TM_UPDATE_NODE_PARENT_CHANGE_LEVEL โ€” dynamic parent node update. The new parent node is on a different hierarchy level than the former parent. So if your parent changes, your hierarchy level changes too. it's giving glow-up-with-relocation ๐Ÿ’…
  • RTE_TM_UPDATE_NODE_ADD_DELETE โ€” dynamic node add/delete โž•โž–
  • RTE_TM_UPDATE_NODE_SUSPEND_RESUME โ€” suspend/resume nodes ๐Ÿ˜ดโ–ถ๏ธ
  • RTE_TM_UPDATE_NODE_WFQ_WEIGHT_MODE โ€” dynamic switch between byte-based and packet-based WFQ weights โš–๏ธ
  • RTE_TM_UPDATE_NODE_N_SP_PRIORITIES โ€” dynamic update on the number of SP priorities ๐Ÿ”ข
  • RTE_TM_UPDATE_NODE_CMAN โ€” dynamic update of congestion management mode for leaf nodes ๐Ÿƒ
  • RTE_TM_UPDATE_NODE_STATS โ€” dynamic update of the set of enabled stats counter types ๐Ÿ“Š

Definition at line 164 of file rte_tm.h.


enum rte_tm_cman_mode

Congestion management (CMAN) mode โ€” okay so this is the whole drama of what do we do when the queue is full ๐ŸŽญ

It controls the admission of packets into a packet queue (or a whole group of packet queues) when congestion hits. So imagine someone tries to write a new packet into the current queue while the queue is full: the tail drop algorithm drops the new packet and leaves the queue unmodified. Meanwhile head drop is the opposite vibe โ€” it drops the packet at the head of the queue (the oldest one waiting in there) and admits the new packet at the tail. be so for real bestie ๐Ÿ’€

And then there's Random Early Detection (RED) โ€” it works by proactively dropping more and more input packets as the queue occupancy builds up. When the queue is full or almost full, RED basically works as tail drop. The Weighted RED algorithm uses a separate set of RED thresholds for each packet color ๐ŸŽจ

Enumerator

  • RTE_TM_CMAN_TAIL_DROP โ€” Tail drop ๐Ÿ‘
  • RTE_TM_CMAN_HEAD_DROP โ€” Head drop ๐Ÿ—ฃ๏ธ
  • RTE_TM_CMAN_WRED โ€” Weighted Random Early Detection (WRED) ๐ŸŒˆ

Definition at line 955 of file rte_tm.h.


enum rte_tm_error_type

Verbose error types ๐Ÿ”

Most of them give you the type of the object referenced by struct rte_tm_error::cause. iykyk.

Enumerator

  • RTE_TM_ERROR_TYPE_NONE โ€” no error ๐ŸŽ‰
  • RTE_TM_ERROR_TYPE_UNSPECIFIED โ€” cause unspecified ๐Ÿคท

Definition at line 1170 of file rte_tm.h.


๐Ÿ’… Function Documentation ๐Ÿ’…

int rte_tm_get_number_of_leaf_nodes (uint16_t port_id, uint32_t * n_leaf_nodes, struct rte_tm_error * error)

Traffic manager get number of leaf nodes ๐Ÿƒ

Every leaf node sits on top of a Tx queue of the current Ethernet port. So the set of leaf nodes is predefined โ€” their number is always exactly N (where N is the number of Tx queues configured for the current port) and their IDs are 0 .. (N-1). no notes, that's just the layout bestie.

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • n_leaf_nodes โ€” number of leaf nodes for the current port.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.


int rte_tm_node_type_get (uint16_t port_id, uint32_t node_id, int * is_leaf, struct rte_tm_error * error)

Traffic manager node ID validate and type (i.e. leaf or non-leaf) get ๐Ÿ•ต๏ธ

Leaf nodes have predefined IDs in the range 0 .. (N-1), where N is the number of Tx queues of the current Ethernet port. The non-leaf nodes have their IDs generated by the application outside of that range โ€” because that range is reserved for leaf nodes, periodt ๐Ÿ”’

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” node ID value. Needs to be valid.
  • is_leaf โ€” set to a non-zero value when the node is leaf, and to zero otherwise (non-leaf).
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.


int rte_tm_capabilities_get (uint16_t port_id, struct rte_tm_capabilities * cap, struct rte_tm_error * error)

Traffic manager capabilities get ๐Ÿ”ฎ

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • cap โ€” traffic manager capabilities. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.


int rte_tm_level_capabilities_get (uint16_t port_id, uint32_t level_id, struct rte_tm_level_capabilities * cap, struct rte_tm_error * error)

Traffic manager level capabilities get ๐Ÿชœ

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • level_id โ€” the hierarchy level identifier. The value of 0 identifies the level of the root node ๐Ÿ‘‘
  • cap โ€” traffic manager level capabilities. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.


int rte_tm_node_capabilities_get (uint16_t port_id, uint32_t node_id, struct rte_tm_node_capabilities * cap, struct rte_tm_error * error)

Traffic manager node capabilities get ๐ŸŒŸ

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” node ID. Needs to be valid.
  • cap โ€” traffic manager node capabilities. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.


int rte_tm_wred_profile_add (uint16_t port_id, uint32_t wred_profile_id, const struct rte_tm_wred_params * profile, struct rte_tm_error * error)

Traffic manager WRED profile add โž•

Creates a brand new WRED profile with ID set to wred_profile_id. The new profile gets used to create one or several WRED contexts ๐Ÿ’–

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • wred_profile_id โ€” WRED profile ID for the new profile. Needs to be unused.
  • profile โ€” WRED profile parameters. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also: struct rte_tm_capabilities::cman_wred_context_n_max


int rte_tm_wred_profile_delete (uint16_t port_id, uint32_t wred_profile_id, struct rte_tm_error * error)

Traffic manager WRED profile delete ๐Ÿ—‘๏ธ

Deletes an existing WRED profile. Heads up though ๐Ÿšจ this operation fails when there is currently at least one user (i.e. WRED context) of this WRED profile. it's giving "can't leave, you're still needed".

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • wred_profile_id โ€” WRED profile ID. Needs to be the valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also: struct rte_tm_capabilities::cman_wred_context_n_max


int rte_tm_shared_wred_context_add_update (uint16_t port_id, uint32_t shared_wred_context_id, uint32_t wred_profile_id, struct rte_tm_error * error)

Traffic manager shared WRED context add or update ๐Ÿ”„

Two moods in one function, love that for us:

  • When shared_wred_context_id is invalid โ†’ a new WRED context with this ID gets created, using the WRED profile identified by wred_profile_id โœจ
  • When shared_wred_context_id is valid โ†’ this WRED context is no longer using the profile previously assigned to it, and gets updated to use the profile identified by wred_profile_id ๐Ÿ’…

A valid shared WRED context can be assigned to several hierarchy leaf nodes configured to use WRED as the congestion management mode ๐Ÿƒ๐Ÿƒ๐Ÿƒ (sharing is caring)

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • shared_wred_context_id โ€” shared WRED context ID
  • wred_profile_id โ€” WRED profile ID. Needs to be the valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also: struct rte_tm_capabilities::cman_wred_context_shared_n_max


int rte_tm_shared_wred_context_delete (uint16_t port_id, uint32_t shared_wred_context_id, struct rte_tm_error * error)

Traffic manager shared WRED context delete ๐Ÿ—‘๏ธ

Deletes an existing shared WRED context. And again, dramatic caveat incoming ๐Ÿšจ this operation fails when there is currently at least one user (i.e. hierarchy leaf node) of this shared WRED context. can't delete what's still in use bestie.

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • shared_wred_context_id โ€” shared WRED context ID. Needs to be the valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also: struct rte_tm_capabilities::cman_wred_context_shared_n_max


int rte_tm_shaper_profile_add (uint16_t port_id, uint32_t shaper_profile_id, const struct rte_tm_shaper_params * profile, struct rte_tm_error * error)

Traffic manager shaper profile add โž•โœจ

Creates a new shaper profile with ID set to shaper_profile_id. The new shaper profile is used to create one or several shapers ๐Ÿซถ

Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • shaper_profile_id โ€” shaper profile ID for the new profile. Needs to be unused.
  • profile โ€” shaper profile parameters. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also: struct rte_tm_capabilities::shaper_n_max


int rte_tm_shaper_profile_delete (uint16_t port_id, uint32_t shaper_profile_id, struct rte_tm_error * error)

Traffic manager shaper profile delete ๐Ÿ—‘๏ธ

Deletes an existing shaper profile. And yep, you already know the pattern โ€” this operation fails when there is currently at least one user (i.e. shaper) of this shaper profile.

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device. your fave little port ๐Ÿซถ
  • shaper_profile_id โ€” shaper profile ID. Needs to be the valid. (yes bestie, the valid, no cap)
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • struct rte_tm_capabilities::shaper_n_max

๐ŸŒŸ rte_tm_shared_shaper_add_update

int rte_tm_shared_shaper_add_update (uint16_t port_id, uint32_t
    shared_shaper_id, uint32_t shaper_profile_id, struct rte_tm_error *
    error)

Traffic manager shared shaper add or update โ€” the glow-up-or-debut function, literally both ๐Ÿ’…

When shared_shaper_id is not a valid shared shaper ID, a brand new shared shaper with this ID is created, using the shaper profile identified by shaper_profile_id. it's giving fresh face โœจ

When shared_shaper_id is a valid shared shaper ID, this shared shaper is no longer using the shaper profile previously assigned to it and is updated to use the shaper profile identified by shaper_profile_id. glow up, periodt ๐Ÿ’–

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • shared_shaper_id โ€” shared shaper ID
  • shaper_profile_id โ€” shaper profile ID. Needs to be the valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • struct rte_tm_capabilities::shaper_shared_n_max

๐ŸŒŸ rte_tm_shared_shaper_delete

int rte_tm_shared_shaper_delete (uint16_t port_id, uint32_t
    shared_shaper_id, struct rte_tm_error * error)

Traffic manager shared shaper delete โ€” okay so we're doing the โœจremovalโœจ era ๐Ÿฆ‹

Delete an existing shared shaper. This operation fails when there is currently at least one user (i.e. hierarchy node) of this shared shaper. so like, if it still has friends attached?? yeah, it's not going anywhere, bestie ๐Ÿ˜ญ

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • shared_shaper_id โ€” shared shaper ID. Needs to be the valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • struct rte_tm_capabilities::shaper_shared_n_max

๐ŸŒŸ rte_tm_node_add

int rte_tm_node_add (uint16_t port_id, uint32_t node_id, uint32_t
    parent_node_id, uint32_t priority, uint32_t weight, uint32_t level_id,
    const struct rte_tm_node_params * params, struct rte_tm_error * error)

Traffic manager node add โ€” making new friends and introducing them to your other friends, the whole vibe ๐Ÿซถ

Create new node and connect it as child of an existing node. The new node is further identified by node_id, which needs to be unused by any of the existing nodes. The parent node is identified by parent_node_id, which needs to be the valid ID of an existing non-leaf node. The parent node is going to use the provided SP priority and WFQ weight to schedule its new child node. so the parent is like, in charge of scheduling. main character energy, honestly ๐Ÿ‘‘

This function has to be called for both leaf and non-leaf nodes. In the case of leaf nodes (i.e. node_id is within the range of 0 .. (N-1), with N as the number of configured Tx queues of the current port), the leaf node is configured rather than created (as the set of leaf nodes is predefined) and it is also connected as child of an existing node. so leaf nodes are already on the guest list, you're just like, dressing them up ๐Ÿ’…

The first node that is added becomes the root node and all the nodes that are subsequently added have to be added as descendants of the root node. The parent of the root node has to be specified as RTE_TM_NODE_ID_NULL and there can only be one node with this parent ID (i.e. the root node). Further restrictions for root node: needs to be non-leaf, its private shaper profile needs to be valid and single rate, cannot use any shared shapers. the root node is THE moment, but it has RULES ๐Ÿ“œ

When called before rte_tm_hierarchy_commit() invocation, this function is typically used to define the initial start-up hierarchy for the port. Provided that dynamic hierarchy updates are supported by the current port (as advertised in the port capability set), this function can be also called after the rte_tm_hierarchy_commit() invocation.

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be unused by any of the existing nodes.
  • parent_node_id โ€” Parent node ID. Needs to be the valid.
  • priority โ€” Node priority. The highest node priority is zero. Used by the SP algorithm running on the parent of the current node for scheduling this child node.
  • weight โ€” Node weight. The node weight is relative to the weight sum of all siblings that have the same priority. The lowest weight is one. Used by the WFQ algorithm running on the parent of the current node for scheduling this child node.
  • level_id โ€” Level ID that should be met by this node. The hierarchy level of the current node is already fully specified through its parent node (i.e. the level of this node is equal to the level of its parent node plus one), therefore the reason for providing this parameter is to enable the application to perform step-by-step checking of the node level during successive invocations of this function. When not desired, this check can be disabled by assigning value RTE_TM_NODE_LEVEL_ID_ANY to this parameter.
  • params โ€” Node parameters. Needs to be pre-allocated and valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • rte_tm_hierarchy_commit()
  • RTE_TM_UPDATE_NODE_ADD_DELETE
  • RTE_TM_NODE_LEVEL_ID_ANY
  • struct rte_tm_capabilities

๐ŸŒŸ rte_tm_node_query

__rte_experimental int rte_tm_node_query (uint16_t port_id, uint32_t
    node_id, uint32_t * parent_node_id, uint32_t * priority, uint32_t *
    weight, uint32_t * level_id, struct rte_tm_node_params * params, struct
    rte_tm_error * error)

Return information about a traffic management node โ€” the "wait, who even are you?" function ๐Ÿ”โœจ

Return information about a hierarchy node, using the same format of parameters as was passed to the rte_rm_node_add() function. Each of the "out" parameters pointers (except error) may be passed as NULL if the information is not needed by the caller. For example, to one may check if a node id is in use by:

struct rte_tm_error error; int ret = rte_tm_node_query(port, node_id, NULL, NULL, NULL, NULL, NULL, &error); if (ret == ENOENT) ...

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” Node ID. Should be a valid node id.
  • parent_node_id โ€” Parent node ID.
  • priority โ€” Node priority. The highest node priority is zero. Used by the SP algorithm running on the parent of the current node for scheduling this child node.
  • weight โ€” Node weight. The node weight is relative to the weight sum of all siblings that have the same priority. The lowest weight is one. Used by the WFQ algorithm running on the parent of the current node for scheduling this child node.
  • level_id โ€” the node level in the scheduler hierarchy.
  • params โ€” Node parameters, as would be used when creating the node.
  • error โ€” error details. Filled in only on error. Must not be NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

  • -EINVAL โ€” port or node id value is invalid
  • -ENOENT โ€” no node exists with the provided id on the provided port

๐ŸŒŸ rte_tm_node_delete

int rte_tm_node_delete (uint16_t port_id, uint32_t node_id, struct
    rte_tm_error * error)

Traffic manager node delete โ€” the unfollow era ๐Ÿ™ˆ

Delete an existing node. This operation fails when this node currently has at least one user (i.e. child node). you literally cannot leave until all your children leave first, that's the rule, fr fr ๐Ÿ’€

When called before rte_tm_hierarchy_commit() invocation, this function is typically used to define the initial start-up hierarchy for the port. Provided that dynamic hierarchy updates are supported by the current port (as advertised in the port capability set), this function can be also called after the rte_tm_hierarchy_commit() invocation.

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • RTE_TM_UPDATE_NODE_ADD_DELETE

๐ŸŒŸ rte_tm_node_suspend

int rte_tm_node_suspend (uint16_t port_id, uint32_t node_id, struct
    rte_tm_error * error)

Traffic manager node suspend โ€” taking a lil nap ๐Ÿ˜ด๐Ÿ’ค

Suspend an existing node. While the node is in suspended state, no packet is scheduled from this node and its descendants. The node exits the suspended state through the node resume operation. so it's not just the node napping, it's the whole family tree napping ๐ŸŒˆ

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • rte_tm_node_resume()
  • RTE_TM_UPDATE_NODE_SUSPEND_RESUME

๐ŸŒŸ rte_tm_node_resume

int rte_tm_node_resume (uint16_t port_id, uint32_t node_id, struct
    rte_tm_error * error)

Traffic manager node resume โ€” wakey wakey bestie, we're so back ๐ŸŒธ

Resume an existing node that is currently in suspended state. The node entered the suspended state as result of a previous node suspend operation.

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • rte_tm_node_suspend()
  • RTE_TM_UPDATE_NODE_SUSPEND_RESUME

๐ŸŒŸ rte_tm_hierarchy_commit

int rte_tm_hierarchy_commit (uint16_t port_id, int clear_on_fail, struct
    rte_tm_error * error)

Traffic manager hierarchy commit โ€” the moment you hit "post" and it's โœจrealโœจ ๐Ÿ‘‘

This function is called during the port initialization phase (before the Ethernet port is started) to freeze the start-up hierarchy.

This function typically performs the following steps:

  1. It validates the start-up hierarchy that was previously defined for the current port through successive rte_tm_node_add() invocations;
  2. Assuming successful validation, it performs all the necessary port specific configuration operations to install the specified hierarchy on the current port, with immediate effect once the port is started.

This function fails when the currently configured hierarchy is not supported by the Ethernet port, in which case the user can abort or try out another hierarchy configuration (e.g. a hierarchy with less leaf nodes), which can be build from scratch (when clear_on_fail is enabled) or by modifying the existing hierarchy configuration (when clear_on_fail is disabled).

Note that this function can still fail due to other causes (e.g. not enough memory available in the system, etc), even though the specified hierarchy is supported in principle by the current port. not me getting rejected by the port itself after doing everything right ๐Ÿ˜ญ

๐Ÿ“‹ Parameters

  • port_id โ€” the port identifier of the Ethernet device.
  • clear_on_fail โ€” On function call failure, hierarchy is cleared when this parameter is non-zero and preserved when this parameter is equal to zero.
  • error โ€” error details. Filled in only on error, when not NULL.

๐Ÿ” Returns

0 on success, non-zero error code otherwise.

๐Ÿ‘€ See also

  • rte_tm_node_add()
  • rte_tm_node_delete()

โœจ rte_tm_node_parent_update() โœจ

int rte_tm_node_parent_update (uint16_t port_id, uint32_t node_id,
    uint32_t parent_node_id, uint32_t priority, uint32_t weight,
    struct rte_tm_error * error)

Traffic manager node parent update ๐Ÿ’…

Okay bestie, this one is the glow-up function: it lets you move a node and all its children over to a whole different parent. And plot twist โ€” if the new parent you're handing it is actually the same as the current parent, it won't just shrug at you, it'll go ahead and update the priority/weight of the existing node instead. Very versatile, we love that for us. โœจ

๐Ÿšจ Root node restriction, no cap: the root node's parent cannot be changed. It's the root, it has no parent to swap, leave it alone.

This function can only be called after the rte_tm_hierarchy_commit() invocation. And whether it actually works depends on your port supporting this operation, as advertised through the port capability set โ€” so check before you commit, iykyk. ๐Ÿ™ˆ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • parent_node_id โ€” Node ID for the new parent. Needs to be valid.
  • priority โ€” Node priority. The highest node priority is zero. Used by the SP algorithm running on the parent of the current node for scheduling this child node.
  • weight โ€” Node weight. The node weight is relative to the weight sum of all siblings that have the same priority. The lowest weight is zero. Used by the WFQ algorithm running on the parent of the current node for scheduling this child node.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • RTE_TM_UPDATE_NODE_PARENT_KEEP_LEVEL
  • RTE_TM_UPDATE_NODE_PARENT_CHANGE_LEVEL

๐Ÿ’– rte_tm_node_shaper_update() ๐Ÿ’–

int rte_tm_node_shaper_update (uint16_t port_id, uint32_t node_id,
    uint32_t shaper_profile_id, struct rte_tm_error * error)

Traffic manager node private shaper update ๐ŸŒธ

Root node restriction, periodt: its private shaper profile needs to be valid and single rate. That's the rule, don't fight it.

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • shaper_profile_id โ€” Shaper profile ID for the private shaper of the current node. Needs to be either a valid shaper profile ID or RTE_TM_SHAPER_PROFILE_ID_NONE, with the latter disabling the private shaper of the current node. (Yes queen, NONE is a totally legal move. ๐Ÿซถ)
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • struct rte_tm_capabilities::shaper_private_n_max

๐ŸŽ€ rte_tm_node_shared_shaper_update() ๐ŸŽ€

int rte_tm_node_shared_shaper_update (uint16_t port_id, uint32_t node_id,
    uint32_t shared_shaper_id, int add, struct rte_tm_error * error)

Traffic manager node shared shapers update ๐Ÿฆ‹

Root node restriction: cannot use any shared rate shapers. At all. Root is on its own private-shaper journey, bestie. ๐Ÿ’€

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • shared_shaper_id โ€” Shared shaper ID. Needs to be valid.
  • add โ€” Set to non-zero value to add this shared shaper to current node or to zero to delete this shared shaper from current node.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • struct rte_tm_capabilities::shaper_shared_n_max

โœจ rte_tm_node_stats_update() โœจ

int rte_tm_node_stats_update (uint16_t port_id, uint32_t node_id,
    uint64_t stats_mask, struct rte_tm_error * error)

Traffic manager node enabled statistics counters update ๐Ÿ“Š

This is the "which counters are we watching" setting, and honestly the way it works is a whole vibe: stats_mask is the full set you want on, and anything you leave out gets switched off. It's not additive, it's a full restatement of your truth. โญ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • stats_mask โ€” Mask of statistics counter types to be enabled for the current node. This needs to be a subset of the statistics counter types available for the current node. Any statistics counter type not included in this set is to be disabled for the current node.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • enum rte_tm_stats_type
  • RTE_TM_UPDATE_NODE_STATS

๐Ÿ’… rte_tm_node_wfq_weight_mode_update() ๐Ÿ’…

int rte_tm_node_wfq_weight_mode_update (uint16_t port_id, uint32_t node_id,
    int * wfq_weight_mode, uint32_t n_sp_priorities,
    struct rte_tm_error * error)

Traffic manager node WFQ weight mode update ๐Ÿงš

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be a valid non-leaf node ID. (Leaf nodes, this is not your moment, sorry not sorry. ๐Ÿ“)
  • wfq_weight_mode โ€” WFQ weight mode for each SP priority. When NULL, it indicates that WFQ is to be used for all priorities. When non-NULL, it points to a pre-allocated array of n_sp_priorities values, with non-zero value for byte-mode and zero for packet-mode.
  • n_sp_priorities โ€” Number of SP priorities.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • RTE_TM_UPDATE_NODE_WFQ_WEIGHT_MODE
  • RTE_TM_UPDATE_NODE_N_SP_PRIORITIES

๐ŸŒˆ rte_tm_node_cman_update() ๐ŸŒˆ

int rte_tm_node_cman_update (uint16_t port_id, uint32_t node_id,
    enum rte_tm_cman_mode cman, struct rte_tm_error * error)

Traffic manager node congestion management mode update ๐Ÿ”ฅ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be a valid leaf node ID. (Yeah, this one's the leaf-node party, opposite of the WFQ one up there. ๐Ÿ‘‘)
  • cman โ€” Congestion management mode.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • RTE_TM_UPDATE_NODE_CMAN

๐Ÿฆ‹ rte_tm_node_wred_context_update() ๐Ÿฆ‹

int rte_tm_node_wred_context_update (uint16_t port_id, uint32_t node_id,
    uint32_t wred_profile_id, struct rte_tm_error * error)

Traffic manager node private WRED context update ๐Ÿ’œ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be a valid leaf node ID.
  • wred_profile_id โ€” WRED profile ID for the private WRED context of the current node. Needs to be either a valid WRED profile ID or RTE_TM_WRED_PROFILE_ID_NONE, with the latter disabling the private WRED context of the current node.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • struct rte_tm_capabilities::cman_wred_context_private_n_max

๐ŸŒธ rte_tm_node_shared_wred_context_update() ๐ŸŒธ

int rte_tm_node_shared_wred_context_update (uint16_t port_id,
    uint32_t node_id, uint32_t shared_wred_context_id, int add,
    struct rte_tm_error * error)

Traffic manager node shared WRED context update ๐ŸŽ€

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be a valid leaf node ID.
  • shared_wred_context_id โ€” Shared WRED context ID. Needs to be valid.
  • add โ€” Set to non-zero value to add this shared WRED context to current node or to zero to delete this shared WRED context from current node.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • struct rte_tm_capabilities::cman_wred_context_shared_n_max

โญ rte_tm_node_stats_read() โญ

int rte_tm_node_stats_read (uint16_t port_id, uint32_t node_id,
    struct rte_tm_node_stats * stats, uint64_t * stats_mask, int clear,
    struct rte_tm_error * error)

Traffic manager node statistics counters read ๐Ÿ“ˆ

Little heads-up on clear, bestie: when it's non-zero, those counters get wiped to zero the second you read them. Gone. If you want to keep the numbers around, leave clear alone. No takebacksies. ๐Ÿ˜ญ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • node_id โ€” Node ID. Needs to be valid.
  • stats โ€” When non-NULL, it contains the current value for the statistics counters enabled for the current node.
  • stats_mask โ€” When non-NULL, it contains the mask of statistics counter types that are currently enabled for this node, indicating which of the counters retrieved with the stats structure are valid.
  • clear โ€” When this parameter has a non-zero value, the statistics counters are cleared (i.e. set to zero) immediately after they have been read, otherwise the statistics counters are left untouched.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • enum rte_tm_stats_type

๐Ÿท๏ธ rte_tm_mark_vlan_dei() ๐Ÿท๏ธ

int rte_tm_mark_vlan_dei (uint16_t port_id, int mark_green,
    int mark_yellow, int mark_red, struct rte_tm_error * error)

Traffic manager packet marking - VLAN DEI (IEEE 802.1Q) ๐ŸŒˆ

Okay so quick lore dump, because this field has history: IEEE 802.1p maps the traffic class to the VLAN Priority Code Point (PCP) field (3 bits), while IEEE 802.1q maps the drop priority to the VLAN Drop Eligible Indicator (DEI) field (1 bit), which was previously named Canonical Format Indicator (CFI). Rebranded, but iconic either way. ๐Ÿ’…

Here's how the actual marking goes: all VLAN frames of a given color get their DEI bit set if marking is enabled for this color; otherwise, their DEI bit is left as is (either set or not). No touchy. ๐Ÿซถ

Parameters

  • port_id โ€” The port identifier of the Ethernet device.
  • mark_green โ€” Set to non-zero value to enable marking of green packets and to zero to disable it.
  • mark_yellow โ€” Set to non-zero value to enable marking of yellow packets and to zero to disable it.
  • mark_red โ€” Set to non-zero value to enable marking of red packets and to zero to disable it.
  • error โ€” Error details. Filled in only on error, when not NULL.

Returns

0 on success, non-zero error code otherwise.

See also

  • struct rte_tm_capabilities::mark_vlan_dei_supported

๐Ÿšฆ rte_tm_mark_ip_ecn() ๐Ÿšฆ

int rte_tm_mark_ip_ecn (uint16_t port_id, int mark_green, int mark_yellow,
    int mark_red, struct rte_tm_error * error)

Traffic manager packet marking - IPv4 / IPv6 ECN (IETF RFC 3168) โœจ

More lore, and honestly this one ate. IETF RFCs 2474 and 3168 reorganize the IPv4 Type of Service (TOS) field (8 bits) and the IPv6 Traffic Class (TC) field (8 bits) into a Differentiated Services Codepoint (DSCP) field (6 bits) and an Explicit Congestion Notification (ECN) field (2 bits). The DSCP field is typically used to encode the traffic class and/or drop priority (RFC 2597), while the ECN field is used by RFC 3168 to implement a congestion notification mechanism to be leveraged by transport layer protocols such as TCP and SCTP that have congestion control mechanisms. ๐ŸŒ

So here's the plot: when congestion is experienced, as an alternative to dropping the packet, routers can change the ECN field of input packets from 2'b01 or 2'b10 (values indicating that source endpoint is ECN-capable) to 2'b11 (meaning that congestion is experienced). The destination endpoint can use the ECN-Echo (ECE) TCP flag to relay the congestion indication back to the source endpoint, which acknowledges it back to the destination endpoint with the Congestion Window Reduced (CWR) TCP flag. A whole group chat of flags coordinating, honestly iconic. ๐Ÿ’œ

The actual behaviour, no cap: all IPv4/IPv6 packets of a given color with ECN set to 2โ€™b01 or 2โ€™b10 carrying TCP or SCTP have their ECN set to 2โ€™b11 if the marking feature is enabled for the current color, otherwise the ECN field is left as is.

okay bestie we're back and we are carrying straight on, no recap needed, let's GO ๐Ÿ’…

โœจ Parameters โœจ

  • port_id โ€” the port identifier of the Ethernet device, the little name tag of the NIC we're talking to ๐ŸŽ€
  • mark_green โ€” set it to a non-zero value to turn ON marking of green packets, and to zero to turn it OFF
  • mark_yellow โ€” same deal, non-zero enables marking of yellow packets, zero disables it
  • mark_red โ€” you already know: non-zero enables marking of red packets, zero disables it
  • error โ€” the error details. It only gets filled in on error, and only when it's not NULL, so don't be shocked when it stays empty on a happy path ๐Ÿซถ

๐ŸŒธ Returns ๐ŸŒธ

0 on success, or a non-zero error code if things went sideways. periodt.

๐Ÿ’œ See also ๐Ÿ’œ

  • struct rte_tm_capabilities::mark_ip_ecn_tcp_supported
  • struct rte_tm_capabilities::mark_ip_ecn_sctp_supported

๐ŸŒˆ int rte_tm_mark_ip_dscp (uint16_t port_id, int mark_green, int mark_yellow, int mark_red, struct rte_tm_error * error)

Traffic manager packet marking โ€” IPv4 / IPv6 DSCP (IETF RFC 2597) โœจ

So IETF RFC 2597 does a little matchmaking: it maps the traffic class and the drop priority onto the IPv4/IPv6 Differentiated Services Codepoint (DSCP) field, which is 6 bits wide. And here's the DSCP values that RFC is proposing, in all their glory:

                          Class 1    Class 2    Class 3    Class 4

                        +----------+----------+----------+----------+

       Low Drop Prec    |  001010  |  010010  |  011010  |  100010  |

       Medium Drop Prec |  001100  |  010100  |  011100  |  100100  |

       High Drop Prec   |  001110  |  010110  |  011110  |  100110  |

                        +----------+----------+----------+----------+

ngl that grid is giving โœจorganized chaosโœจ in the best way.

So the tea is: there are 4 traffic classes (classes 1 .. 4) encoded by DSCP bits 1 and 2, and 3 drop priorities (low / medium / high) encoded by DSCP bits 3 and 4. Two vibes, one codepoint, iconic.

Every IPv4/IPv6 packet gets its color marked into DSCP bits 3 and 4 like this:

  • green โ†’ Low Drop Precedence (2โ€™b01)
  • yellow โ†’ Medium Drop Precedence (2โ€™b10)
  • red โ†’ High Drop Precedence (2โ€™b11)
Heads up bestie: marking has to be explicitly enabled for each color. If it's not enabled for a given color, the DSCP field of all packets with that color is left as is โ€” no sneaky editing, no touch-ups. ๐Ÿ™ˆ

๐ŸŽ€ Parameters ๐ŸŽ€

  • port_id โ€” the port identifier of the Ethernet device.
  • mark_green โ€” non-zero value enables marking of green packets, zero disables it.
  • mark_yellow โ€” non-zero value enables marking of yellow packets, zero disables it.
  • mark_red โ€” non-zero value enables marking of red packets, zero disables it.
  • error โ€” error details. Filled in only on error, when not NULL. ๐Ÿ’€

โญ Returns โญ

0 on success, non-zero error code otherwise. no cap.

๐Ÿฆ‹ See also ๐Ÿฆ‹

  • struct rte_tm_capabilities::mark_ip_dscp_supported

๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Generated automatically by Doxygen for DPDK from the source code. I literally did not write myself, I was generated, and honestly? main character energy. ๐Ÿงš


and that's a wrap on the whole page, bestie!! this lil doc lives in rte_tm.h(3), the DPDK crew is on Version 25.11.3, and the whole thing got auto-spun by Doxygen straight out of the source code. obsessed, ate, no crumbs left ๐Ÿ’–๐ŸŒธ๐Ÿ’…

๐Ÿ“ฆ where this page comes from