DPDK 25.07.0
Data Structures | Macros | Typedefs | Functions
rte_graph_feature_arc.h File Reference
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rte_common.h>
#include <rte_compat.h>
#include <rte_debug.h>
#include <rte_graph.h>
#include <rte_rcu_qsbr.h>

Go to the source code of this file.

Data Structures

struct  rte_graph_feature_register
 
struct  rte_graph_feature_arc_register
 

Macros

#define RTE_GRAPH_FEATURE_ARC_NAMELEN   RTE_NODE_NAMESIZE
 
#define RTE_GRAPH_FEATURE_ARC_INITIALIZER   ((rte_graph_feature_arc_t)UINT16_MAX)
 
#define RTE_GRAPH_FEATURE_REGISTER(reg)
 
#define RTE_GRAPH_FEATURE_ARC_REGISTER(reg)
 

Typedefs

typedef uint16_t rte_graph_feature_arc_t
 
typedef uint8_t rte_graph_feature_t
 
typedef uint32_t rte_graph_feature_data_t
 
typedef void(* rte_graph_feature_change_notifier_cb_t) (const char *arc_name, const char *feature_name, rte_node_t feature_node_id, uint32_t index, bool enable_disable, uint16_t app_cookie)
 
typedef uint16_t(* rte_graph_feature_override_index_cb_t) (void)
 

Functions

__rte_experimental int rte_graph_feature_arc_init (uint16_t num_feature_arcs)
 
__rte_experimental int rte_graph_feature_arc_create (struct rte_graph_feature_arc_register *reg, rte_graph_feature_arc_t *_arc)
 
__rte_experimental int rte_graph_feature_arc_lookup_by_name (const char *arc_name, rte_graph_feature_arc_t *_arc)
 
__rte_experimental int rte_graph_feature_add (struct rte_graph_feature_register *feat_reg)
 
__rte_experimental int rte_graph_feature_enable (rte_graph_feature_arc_t _arc, uint32_t index, const char *feature_name, uint16_t app_cookie, struct rte_rcu_qsbr *qsbr)
 
__rte_experimental int rte_graph_feature_disable (rte_graph_feature_arc_t _arc, uint32_t index, const char *feature_name, struct rte_rcu_qsbr *qsbr)
 
__rte_experimental int rte_graph_feature_lookup (rte_graph_feature_arc_t arc, const char *feature_name, rte_graph_feature_t *feature)
 
__rte_experimental int rte_graph_feature_arc_destroy (rte_graph_feature_arc_t _arc)
 
__rte_experimental int rte_graph_feature_arc_cleanup (void)
 
__rte_experimental uint32_t rte_graph_feature_arc_num_features (rte_graph_feature_arc_t _arc)
 
__rte_experimental uint32_t rte_graph_feature_arc_num_enabled_features (rte_graph_feature_arc_t _arc)
 
__rte_experimental char * rte_graph_feature_arc_feature_to_name (rte_graph_feature_arc_t _arc, rte_graph_feature_t feature)
 
__rte_experimental int rte_graph_feature_arc_feature_to_node (rte_graph_feature_arc_t _arc, rte_graph_feature_t feature, rte_node_t *node)
 
__rte_experimental uint32_t rte_graph_feature_arc_names_get (char *arc_names[])
 

Detailed Description

Warning
EXPERIMENTAL: All functions in this file may be changed or removed without prior notice.

Graph Feature Arc API

Define APIs and structures/variables with respect to feature arc

In a typical network stack, often a protocol must be first enabled in control plane before any packet is steered for its processing in the dataplane. For eg: incoming IPv4 packets are routed only after a valid IPv4 address is assigned to the received interface. In other words, often packets received on an interface need to be steered to protocol not based on the packet content but based on whether the protocol is configured on the interface or not.

Protocols can be enabled/disabled multiple times at runtime in the control plane. Protocols enabled on one interface may not be enabled on another interface.

When more than one protocols are present in a networking layer (say IPv4, IP tables, IPsec etc), it becomes imperative to steer packets (in dataplane) across each protocol processing in a defined sequential order. In ingress direction, stack decides to perform IPsec decryption first before IP validation while in egress direction IPsec encryption is performed after IP forwarding. In the case of IP tables, users can enable rules in any protocol order i.e. pre-routing or post-routing etc. This implies that protocols are configured differently at each networking layer and in each traffic direction.

A feature arc represents an ordered list of features/protocols nodes at the given networking layer and in a given direction. It provides a high level abstraction to enable/disable features on an index at runtime and provide a mechanism to steer packets across these feature nodes in a generic manner. Here index corresponds to either interface index, route index, flow index or classification index etc. as it is deemed suitable to configure protocols at the networking layer. Some typical examples of protocols which are configured based on

Feature arc also provides a way to steer packets from in-built DPDK feature nodes to out-of-tree feature nodes and vice-versa without any code changes required in DPDK in-built node's fast path functions. This way it allows application to override default packet path defined by in-built DPDK nodes.

Features enabled on one index may not be enabled on another index hence packets received on an interface "X" should be treated independently from packets received on interface "Y".

A given feature might consume packet (if it's configured to consume) or may forward it to next enabled feature. For instance, "IPsec input" feature may consume/drop all packets with "Protect" policy action while all packets with policy action as "Bypass" may be forwarded to next enabled feature (with in same feature arc)

A feature arc in a graph is represented via start_node and end_feature_node. Feature nodes are added between start_node and end_feature_node. Packets enter feature arc path via start_node while they exit from end_feature_node. Packets steering from start_node to feature nodes are controlled in control plane via rte_graph_feature_enable(), rte_graph_feature_disable().

This library facilitates rte graph based applications to implement stack functionalities described above by providing "edge" to the next enabled feature node in fast path

In order to use feature-arc APIs, applications needs to do following in control plane:

If a given feature likes to control number of indexes (which is higher than rte_graph_feature_arc_register::max_indexes) it can do so by setting rte_graph_feature_register::override_index_cb(). As part of rte_graph_feature_arc_init(), all rte_graph_feature_register::override_index_cb(), if set, are called and with maximum value returned by any of the feature is used for rte_graph_feature_arc_create()

Before enabling a feature, control plane might allocate certain resources (like VRF table for IP lookup or IPsec SA for inbound policy etc). A reference of allocated resource can be passed from control plane to dataplane via app_cookie argument in rte_graph_feature_enable(). A corresponding dataplane API rte_graph_feature_data_app_cookie_get() can be used to retrieve same cookie in fast path.

When a feature is disabled, resources allocated during feature enable can be safely released via registering a callback in rte_graph_feature_register::notifier_cb(). See fast path synchronization section below for more details.

If current feature node is not consuming packet, it might want to send it to next enabled feature. Depending upon current node is a:

Above APIs deals with fast path object: feature_data (struct rte_graph_feature_data), which is unique for every index per feature with in a feature arc. It holds three data fields: next node edge, next enabled feature data and app_cookie.

rte_mbuf carries [feature_data] into feature arc specific mbuf dynamic field. See rte_graph_feature_arc_mbuf_dynfields and rte_graph_feature_arc_mbuf_dynfields_get() for more details.

Fast path synchronization

Any feature enable/disable in control plane does not require stopping of worker cores. rte_graph_feature_enable()/rte_graph_feature_disable() APIs are almost thread-safe avoiding any RCU usage. Only condition when race condition could occur is when application is trying to enable/disable feature very fast for [feature, index] combination. In that case, application should use rte_graph_feature_enable(), rte_graph_feature_disable() APIs with RCU argument

RCU synchronization may also be required when application needs to free resources (using rte_graph_feature_register::notifier_cb()) which it may have allocated during feature enable. Resources can be freed only when no worker core is not acting on it.

If RCU argument to rte_graph_feature_enable(), rte_graph_feature_disable() is non-NULL, as part of APIs:

It is application responsibility to pass valid RCU argument to APIs. It is recommended that application calls rte_rcu_qsbr_quiescent() after every iteration of rte_graph_walk()

Constraints

Optional Usage

Feature arc is added as an optional functionality to the graph library hence an application may choose not to use it by skipping explicit call to rte_graph_feature_arc_init(). In that case feature arc would be a no-op for application.

Definition in file rte_graph_feature_arc.h.

Macro Definition Documentation

◆ RTE_GRAPH_FEATURE_ARC_NAMELEN

#define RTE_GRAPH_FEATURE_ARC_NAMELEN   RTE_NODE_NAMESIZE

Length of feature arc name

Definition at line 206 of file rte_graph_feature_arc.h.

◆ RTE_GRAPH_FEATURE_ARC_INITIALIZER

#define RTE_GRAPH_FEATURE_ARC_INITIALIZER   ((rte_graph_feature_arc_t)UINT16_MAX)

Initializer values for ARC, Feature, Feature data

Definition at line 209 of file rte_graph_feature_arc.h.

◆ RTE_GRAPH_FEATURE_REGISTER

#define RTE_GRAPH_FEATURE_REGISTER (   reg)
Value:
RTE_INIT(__rte_graph_feature_register_##reg) \
{ \
__rte_graph_feature_register(&reg, __func__, __LINE__); \
}
#define RTE_INIT(func)
Definition: rte_common.h:393

constructor to register feature to an arc

Definition at line 346 of file rte_graph_feature_arc.h.

◆ RTE_GRAPH_FEATURE_ARC_REGISTER

#define RTE_GRAPH_FEATURE_ARC_REGISTER (   reg)
Value:
RTE_INIT(__rte_graph_feature_arc_register_##reg) \
{ \
__rte_graph_feature_arc_register(&reg, __func__, __LINE__); \
}

constructor to register a feature arc

Definition at line 353 of file rte_graph_feature_arc.h.

Typedef Documentation

◆ rte_graph_feature_arc_t

rte_graph feature arc object

Definition at line 214 of file rte_graph_feature_arc.h.

◆ rte_graph_feature_t

rte_graph feature object

Definition at line 217 of file rte_graph_feature_arc.h.

◆ rte_graph_feature_data_t

rte_graph feature data object

Definition at line 220 of file rte_graph_feature_arc.h.

◆ rte_graph_feature_change_notifier_cb_t

typedef void(* rte_graph_feature_change_notifier_cb_t) (const char *arc_name, const char *feature_name, rte_node_t feature_node_id, uint32_t index, bool enable_disable, uint16_t app_cookie)

feature notifier callback called when feature is enabled/disabled

Definition at line 223 of file rte_graph_feature_arc.h.

◆ rte_graph_feature_override_index_cb_t

typedef uint16_t(* rte_graph_feature_override_index_cb_t) (void)

cb for overriding arc->max_indexes via RTE_GRAPH_FEATURE_REGISTER()

Definition at line 231 of file rte_graph_feature_arc.h.

Function Documentation

◆ rte_graph_feature_arc_init()

__rte_experimental int rte_graph_feature_arc_init ( uint16_t  num_feature_arcs)

Initialize feature arc subsystem

This API

Parameters
num_feature_arcsNumber of feature arcs that application wants to create by explicitly using "rte_graph_feature_arc_create()" API.

Number of RTE_GRAPH_FEATURE_ARC_REGISTER() should be excluded from this count as API internally calculates number of RTE_GRAPH_FEATURE_ARC_REGISTER().

So, total number of supported arcs = num_feature_arcs + NUMBER_OF(RTE_GRAPH_FEATURE_ARC_REGISTER())

Returns
0: Success <0: Failure

rte_graph_feature_arc_init(0) is valid call which will accommodates constructor based arc registration

◆ rte_graph_feature_arc_create()

__rte_experimental int rte_graph_feature_arc_create ( struct rte_graph_feature_arc_register reg,
rte_graph_feature_arc_t _arc 
)

Create a feature arc.

This API can be skipped if RTE_GRAPH_FEATURE_ARC_REGISTER() is used

Parameters
regPointer to struct rte_graph_feature_arc_register
[out]_arcFeature arc object
Returns
0: Success <0: Failure

◆ rte_graph_feature_arc_lookup_by_name()

__rte_experimental int rte_graph_feature_arc_lookup_by_name ( const char *  arc_name,
rte_graph_feature_arc_t _arc 
)

Get feature arc object with name

Parameters
arc_nameFeature arc name provided to successful rte_graph_feature_arc_create()
[out]_arcFeature arc object returned. Valid only when API returns SUCCESS
Returns
0: Success <0: Failure.

◆ rte_graph_feature_add()

__rte_experimental int rte_graph_feature_add ( struct rte_graph_feature_register feat_reg)

Add a feature to already created feature arc.

This API is not required in case RTE_GRAPH_FEATURE_REGISTER() is used

Parameters
feat_regPointer to struct rte_graph_feature_register

Must be called before rte_graph_create() rte_graph_feature_add() is not allowed after call to rte_graph_feature_enable() so all features must be added before they can be enabled When called by application, then feature_node_id should be appropriately set as freg->feature_node_id = freg->feature_node->id;

Returns
0: Success <0: Failure

◆ rte_graph_feature_enable()

__rte_experimental int rte_graph_feature_enable ( rte_graph_feature_arc_t  _arc,
uint32_t  index,
const char *  feature_name,
uint16_t  app_cookie,
struct rte_rcu_qsbr *  qsbr 
)

Enable feature within a feature arc

Must be called after rte_graph_create().

Parameters
_arcFeature arc object returned by rte_graph_feature_arc_create() or rte_graph_feature_arc_lookup_by_name()
indexApplication specific index. Can be corresponding to interface_id/port_id etc
feature_nameName of the node which is already added via rte_graph_feature_add()
app_cookieApplication specific data which is retrieved in fast path
qsbrRCU QSBR object. After enabling feature, API calls rte_rcu_qsbr_synchronize() followed by call to struct rte_graph_feature_register::notifier_cb(), if it is set, to notify feature caller This object can be passed NULL as well if no RCU synchronization is required
Returns
0: Success <0: Failure

◆ rte_graph_feature_disable()

__rte_experimental int rte_graph_feature_disable ( rte_graph_feature_arc_t  _arc,
uint32_t  index,
const char *  feature_name,
struct rte_rcu_qsbr *  qsbr 
)

Disable already enabled feature within a feature arc

Must be called after rte_graph_create(). API is NOT Thread-safe

Parameters
_arcFeature arc object returned by rte_graph_feature_arc_create() or rte_graph_feature_arc_lookup_by_name()
indexApplication specific index. Can be corresponding to interface_id/port_id etc
feature_nameName of the node which is already added via rte_graph_feature_add()
qsbrRCU QSBR object. After disabling feature, API calls rte_rcu_qsbr_synchronize() followed by call to struct RTE_GRAPH_FEATURE_ARC_REGISTER::notifier_cb(), if it is set, to notify feature caller. This object can be passed NULL as well if no RCU synchronization is required
Returns
0: Success <0: Failure

◆ rte_graph_feature_lookup()

__rte_experimental int rte_graph_feature_lookup ( rte_graph_feature_arc_t  arc,
const char *  feature_name,
rte_graph_feature_t feature 
)

Get rte_graph_feature_t object from feature name

Parameters
arcFeature arc object returned by rte_graph_feature_arc_create() or rte_graph_feature_arc_lookup_by_name()
feature_nameFeature name provided to rte_graph_feature_add()
[out]featureFeature object
Returns
0: Success <0: Failure

◆ rte_graph_feature_arc_destroy()

__rte_experimental int rte_graph_feature_arc_destroy ( rte_graph_feature_arc_t  _arc)

Delete feature_arc object

Parameters
_arcFeature arc object returned by rte_graph_feature_arc_create() or rte_graph_feature_arc_lookup_by_name()
Returns
0: Success <0: Failure

◆ rte_graph_feature_arc_cleanup()

__rte_experimental int rte_graph_feature_arc_cleanup ( void  )

Cleanup all feature arcs

Returns
0: Success <0: Failure

◆ rte_graph_feature_arc_num_features()

__rte_experimental uint32_t rte_graph_feature_arc_num_features ( rte_graph_feature_arc_t  _arc)

Slow path API to know how many features are added (NOT enabled) within a feature arc

Parameters
_arcFeature arc object
Returns
: Number of added features to arc

◆ rte_graph_feature_arc_num_enabled_features()

__rte_experimental uint32_t rte_graph_feature_arc_num_enabled_features ( rte_graph_feature_arc_t  _arc)

Slow path API to know how many features are currently enabled within a feature arc across all indexes. If a single feature is enabled on all interfaces, this API would return "number_of_interfaces" as count (but not "1")

Parameters
_arcFeature arc object
Returns
: Number of enabled features across all indexes

◆ rte_graph_feature_arc_feature_to_name()

__rte_experimental char * rte_graph_feature_arc_feature_to_name ( rte_graph_feature_arc_t  _arc,
rte_graph_feature_t  feature 
)

Slow path API to get feature node name from rte_graph_feature_t object

Parameters
_arcFeature arc object
featureFeature object
Returns
: Name of the feature node

◆ rte_graph_feature_arc_feature_to_node()

__rte_experimental int rte_graph_feature_arc_feature_to_node ( rte_graph_feature_arc_t  _arc,
rte_graph_feature_t  feature,
rte_node_t node 
)

Slow path API to get corresponding rte_node_t from rte_graph_feature_t

Parameters
_arcFeature arc object
featureFeature object
[out]noderte_node_t of feature node, Valid only when API returns SUCCESS
Returns
: 0 on success, < 0 on failure

◆ rte_graph_feature_arc_names_get()

__rte_experimental uint32_t rte_graph_feature_arc_names_get ( char *  arc_names[])

Slow path API to dump valid feature arc names

Parameters
[out]arc_namesBuffer to copy the arc names. The NULL value is allowed in that case, the function returns the size of the array that needs to be allocated.
Returns
When next_nodes == NULL, it returns the size of the array else number of item copied.