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_statsstruct rte_tm_capabilitiesstruct rte_tm_level_capabilitiesstruct rte_tm_node_capabilitiesstruct rte_tm_red_paramsstruct rte_tm_wred_paramsstruct rte_tm_token_bucketstruct rte_tm_shaper_paramsstruct rte_tm_node_paramsstruct 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_queryis 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:
- Preamble:
7bytes; - Start of Frame Delimiter (SFD):
1byte; - Inter-Frame Gap (IFG):
12bytes.
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 line42of filerte_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 line54of filerte_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_paramsrte_tm_node_add()rte_tm_node_wred_context_update()
๐ Definition at line63of filerte_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_paramsrte_tm_node_add()rte_tm_node_shaper_update()
๐ Definition at line72of filerte_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 line79of filerte_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 line86of filerte_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 notNULL.
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 notNULL.
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 notNULL.
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 of0identifies 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 notNULL.
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 notNULL.
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 notNULL.
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 notNULL.
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_idis invalid โ a new WRED context with this ID gets created, using the WRED profile identified bywred_profile_idโจ - When
shared_wred_context_idis valid โ this WRED context is no longer using the profile previously assigned to it, and gets updated to use the profile identified bywred_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 IDwred_profile_idโ WRED profile ID. Needs to be the valid.errorโ error details. Filled in only on error, when notNULL.
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 notNULL.
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 notNULL.
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 notNULL.
๐ 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 IDshaper_profile_idโ shaper profile ID. Needs to be the valid.errorโ error details. Filled in only on error, when notNULL.
๐ 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 notNULL.
๐ 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 valueRTE_TM_NODE_LEVEL_ID_ANYto this parameter.paramsโ Node parameters. Needs to be pre-allocated and valid.errorโ error details. Filled in only on error, when notNULL.
๐ Returns
0 on success, non-zero error code otherwise.
๐ See also
rte_tm_hierarchy_commit()RTE_TM_UPDATE_NODE_ADD_DELETERTE_TM_NODE_LEVEL_ID_ANYstruct 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 beNULL.
๐ 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 notNULL.
๐ 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 notNULL.
๐ 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 notNULL.
๐ 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:
- It validates the start-up hierarchy that was previously defined for the current port through successive
rte_tm_node_add()invocations; - 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 notNULL.
๐ 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 notNULL.
Returns
0 on success, non-zero error code otherwise.
See also
RTE_TM_UPDATE_NODE_PARENT_KEEP_LEVELRTE_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 orRTE_TM_SHAPER_PROFILE_ID_NONE, with the latter disabling the private shaper of the current node. (Yes queen,NONEis a totally legal move. ๐ซถ)errorโ Error details. Filled in only on error, when notNULL.
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 notNULL.
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 notNULL.
Returns
0 on success, non-zero error code otherwise.
See also
enum rte_tm_stats_typeRTE_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. WhenNULL, it indicates that WFQ is to be used for all priorities. When non-NULL, it points to a pre-allocated array ofn_sp_prioritiesvalues, 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 notNULL.
Returns
0 on success, non-zero error code otherwise.
See also
RTE_TM_UPDATE_NODE_WFQ_WEIGHT_MODERTE_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 notNULL.
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 orRTE_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 notNULL.
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 notNULL.
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 thestatsstructure 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 notNULL.
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 notNULL.
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 OFFmark_yellowโ same deal, non-zero enables marking of yellow packets, zero disables itmark_redโ you already know: non-zero enables marking of red packets, zero disables iterrorโ the error details. It only gets filled in on error, and only when it's notNULL, 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_supportedstruct 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 notNULL. ๐
โญ 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
- ubuntu resolute: dpdk-doc 25.11.3-0ubuntu0.26.04.1 ยท BSD-3-Clause
- ubuntu stonking: dpdk-doc 25.11.3-1 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms