1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2025 Marvell International Ltd.
*/
#ifndef _RTE_GRAPH_MBUF_DYNFIELD_H_
#define _RTE_GRAPH_MBUF_DYNFIELD_H_
#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_mbuf_dyn.h>
/**
* @file: rte_node_mbuf_dynfield.h
*
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Defines rte_node specific mbuf dynamic field region [rte_node_mbuf_dynfield_t]
* which can be used by both DPDK built-in and out-of-tree nodes
* for storing per-mbuf fields for graph walk.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE
/** Size of persistent mbuf fields */
#define RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE (0)
#endif /* !RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE */
#ifndef RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE
/** Size of overloadable mbuf fields */
#define RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE (8)
#endif /* !RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE */
/** Size of node mbuf dynamic field */
#define RTE_NODE_MBUF_DYNFIELD_SIZE \
(RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE + RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE)
/**
* Node mbuf overloadable data.
*
* Out-of-tree nodes can repurpose overloadable fields via
* rte_node_mbuf_overload_fields_get(mbuf). Overloadable fields are not
* preserved and typically can be used with-in two adjacent nodes in the graph.
*/
typedef struct rte_node_mbuf_overload_fields {
union {
/* Following fields used by ip[4|6]-lookup -> ip[4|6]-rewrite nodes */
union {
struct {
uint16_t nh;
uint16_t ttl;
uint32_t cksum;
};
uint64_t u;
};
uint8_t data[RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE];
};
} rte_node_mbuf_overload_fields_t;
/**
* rte_node specific mbuf dynamic field structure [rte_node_mbuf_dynfield_t]
*
* It holds two types of fields:
* 1. Persistent fields: Fields which are preserved across nodes during graph walk.
* - Eg: rx/tx interface etc
* 2. Overloadable fields: Fields which can be repurposed by two adjacent nodes.
*/
typedef struct rte_node_mbuf_dynfield {
#if RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE > 0
/**
* Persistent mbuf region across nodes in graph walk
*
* These fields are preserved across graph walk and can be accessed by
* rte_node_mbuf_dynfield_get() in fast path.
*/
union {
uint8_t persistent_data[RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE];
};
#endif
/**
* Overloadable mbuf fields across graph walk. Fields which can change.
*
* Two adjacent nodes (producer, consumer) can use this memory region for
* sharing per-mbuf specific information. Once mbuf leaves a consumer node,
* this region can be repurposed by another sets of [producer, consumer] node.
*
* In fast path, this region can be accessed by rte_node_mbuf_overload_fields_get().
*/
rte_node_mbuf_overload_fields_t overloadable_data;
} rte_node_mbuf_dynfield_t;
/**
* For a given mbuf and dynamic offset, return pointer to rte_node_mbuf_dynfield_t *
*
* @param m
* Mbuf
* @param offset
* Dynamic offset returned by @ref rte_node_mbuf_dynfield_register()
* @return
* Pointer to node specific mbuf dynamic field structure
*/
__rte_experimental
static __rte_always_inline rte_node_mbuf_dynfield_t *
rte_node_mbuf_dynfield_get(struct rte_mbuf *m, const int offset)
{
return RTE_MBUF_DYNFIELD(m, offset, struct rte_node_mbuf_dynfield *);
}
/**
* For a given mbuf and dynamic offset, return pointer to overloadable fields.
* Nodes can typecast returned pointer to reuse for their own purpose.
*
* @param m
* Mbuf
* @param offset
* Dynamic offset returned by @ref rte_node_mbuf_dynfield_register()
* @return
* Pointer to node mbuf overloadable fields
*/
__rte_experimental
static __rte_always_inline rte_node_mbuf_overload_fields_t *
rte_node_mbuf_overload_fields_get(struct rte_mbuf *m, const int offset)
{
rte_node_mbuf_dynfield_t *f = NULL;
f = RTE_MBUF_DYNFIELD(m, offset, rte_node_mbuf_dynfield_t *);
return &(f->overloadable_data);
}
/**
* Register rte_node specific common mbuf dynamic field region. Can be called
* in rte_node_register()->init() function to save offset in node->ctx
*
* In process() function, node->ctx can be passed to
* - rte_node_mbuf_dynfield_get(mbuf, offset)
* - rte_node_mbuf_overload_fields_get(mbuf, offset)
*
* Can be called multiple times by any number of nodes in init() function.
* - Very first call registers dynamic field and returns offset.
* - Subsequent calls return same offset.
*
* @return
* <0 on error: rte_errno set to one of:
* - ENOMEM - no memory
* >=0 on success: dynamic field offset
*/
__rte_experimental
int rte_node_mbuf_dynfield_register(void);
#ifdef __cplusplus
}
#endif
#endif /* _RTE_GRAPH_MBUF_DYNFIELD_H_ */
|