1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2019 6WIND S.A.
5 #ifndef _RTE_MBUF_DYN_H_
6 #define _RTE_MBUF_DYN_H_
10 * RTE Mbuf dynamic fields and flags
12 * Many DPDK features require to store data inside the mbuf. As the room
13 * in mbuf structure is limited, it is not possible to have a field for
14 * each feature. Also, changing fields in the mbuf structure can break
17 * This module addresses this issue, by enabling the dynamic
18 * registration of fields or flags:
20 * - a dynamic field is a named area in the rte_mbuf structure, with a
21 * given size (>= 1 byte) and alignment constraint.
22 * - a dynamic flag is a named bit in the rte_mbuf structure, stored
25 * The placement of the field or flag can be automatic, in this case the
26 * zones that have the smallest size and alignment constraint are
27 * selected in priority. Else, a specific field offset or flag bit
28 * number can be requested through the API.
30 * The typical use case is when a specific offload feature requires to
31 * register a dedicated offload field in the mbuf structure, and adding
32 * a static field or flag is not justified.
36 * - A rte_mbuf_dynfield structure is defined, containing the parameters
37 * of the dynamic field to be registered:
38 * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
39 * - The application initializes the PMD, and asks for this feature
40 * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
41 * rxconf. This will make the PMD to register the field by calling
42 * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
43 * stores the returned offset.
44 * - The application that uses the offload feature also registers
45 * the field to retrieve the same offset.
46 * - When the PMD receives a packet, it can set the field:
47 * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
48 * - In the main loop, the application can retrieve the value with
51 * To avoid wasting space, the dynamic fields or flags must only be
52 * reserved on demand, when an application asks for the related feature.
54 * The registration can be done at any moment, but it is not possible
55 * to unregister fields or flags for now.
57 * A dynamic field can be reserved and used by an application only.
58 * It can for instance be a packet mark.
60 * To avoid namespace collisions, the dynamic mbuf field or flag names
61 * have to be chosen with care. It is advised to use the same
62 * conventions than function names in dpdk:
63 * - "rte_mbuf_dynfield_<name>" if defined in mbuf library
64 * - "rte_<libname>_dynfield_<name>" if defined in another library
65 * - "rte_net_<pmd>_dynfield_<name>" if defined in a PMD
66 * - any name that does not start with "rte_" in an application
71 #include <sys/types.h>
73 #include <rte_compat.h>
80 * Maximum length of the dynamic field or flag string.
82 #define RTE_MBUF_DYN_NAMESIZE 64
85 * Structure describing the parameters of a mbuf dynamic field.
87 struct rte_mbuf_dynfield {
88 char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
89 size_t size; /**< The number of bytes to reserve. */
90 size_t align; /**< The alignment constraint (power of 2). */
91 unsigned int flags; /**< Reserved for future use, must be 0. */
95 * Structure describing the parameters of a mbuf dynamic flag.
97 struct rte_mbuf_dynflag {
98 char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */
99 unsigned int flags; /**< Reserved for future use, must be 0. */
103 * Register space for a dynamic field in the mbuf structure.
105 * If the field is already registered (same name and parameters), its
106 * offset is returned.
109 * A structure containing the requested parameters (name, size,
110 * alignment constraint and flags).
112 * The offset in the mbuf structure, or -1 on error.
113 * Possible values for rte_errno:
114 * - EINVAL: invalid parameters (size, align, or flags).
115 * - EEXIST: this name is already register with different parameters.
116 * - EPERM: called from a secondary process.
117 * - ENOENT: not enough room in mbuf.
118 * - ENOMEM: allocation failure.
119 * - ENAMETOOLONG: name does not ends with \0.
122 int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
125 * Register space for a dynamic field in the mbuf structure at offset.
127 * If the field is already registered (same name, parameters and offset),
128 * the offset is returned.
131 * A structure containing the requested parameters (name, size,
132 * alignment constraint and flags).
134 * The requested offset. Ignored if SIZE_MAX is passed.
136 * The offset in the mbuf structure, or -1 on error.
137 * Possible values for rte_errno:
138 * - EINVAL: invalid parameters (size, align, flags, or offset).
139 * - EEXIST: this name is already register with different parameters.
140 * - EBUSY: the requested offset cannot be used.
141 * - EPERM: called from a secondary process.
142 * - ENOENT: not enough room in mbuf.
143 * - ENOMEM: allocation failure.
144 * - ENAMETOOLONG: name does not ends with \0.
147 int rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
151 * Lookup for a registered dynamic mbuf field.
154 * A string identifying the dynamic field.
156 * If not NULL, and if the lookup is successful, the structure is
157 * filled with the parameters of the dynamic field.
159 * The offset of this field in the mbuf structure, or -1 on error.
160 * Possible values for rte_errno:
161 * - ENOENT: no dynamic field matches this name.
164 int rte_mbuf_dynfield_lookup(const char *name,
165 struct rte_mbuf_dynfield *params);
168 * Register a dynamic flag in the mbuf structure.
170 * If the flag is already registered (same name and parameters), its
171 * bitnum is returned.
174 * A structure containing the requested parameters of the dynamic
175 * flag (name and options).
177 * The number of the reserved bit, or -1 on error.
178 * Possible values for rte_errno:
179 * - EINVAL: invalid parameters (size, align, or flags).
180 * - EEXIST: this name is already register with different parameters.
181 * - EPERM: called from a secondary process.
182 * - ENOENT: no more flag available.
183 * - ENOMEM: allocation failure.
184 * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
187 int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
190 * Register a dynamic flag in the mbuf structure specifying bitnum.
192 * If the flag is already registered (same name, parameters and bitnum),
193 * the bitnum is returned.
196 * A structure containing the requested parameters of the dynamic
197 * flag (name and options).
199 * The requested bitnum. Ignored if UINT_MAX is passed.
201 * The number of the reserved bit, or -1 on error.
202 * Possible values for rte_errno:
203 * - EINVAL: invalid parameters (size, align, or flags).
204 * - EEXIST: this name is already register with different parameters.
205 * - EBUSY: the requested bitnum cannot be used.
206 * - EPERM: called from a secondary process.
207 * - ENOENT: no more flag available.
208 * - ENOMEM: allocation failure.
209 * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
212 int rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
213 unsigned int bitnum);
216 * Lookup for a registered dynamic mbuf flag.
219 * A string identifying the dynamic flag.
221 * If not NULL, and if the lookup is successful, the structure is
222 * filled with the parameters of the dynamic flag.
224 * The offset of this flag in the mbuf structure, or -1 on error.
225 * Possible values for rte_errno:
226 * - ENOENT: no dynamic flag matches this name.
229 int rte_mbuf_dynflag_lookup(const char *name,
230 struct rte_mbuf_dynflag *params);
233 * Helper macro to access to a dynamic field.
235 #define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
238 * Dump the status of dynamic fields and flags.
241 * The stream where the status is displayed.
244 void rte_mbuf_dyn_dump(FILE *out);
247 * Placeholder for dynamic fields and flags declarations.
248 * This is centralizing point to gather all field names
249 * and parameters together.
253 * The metadata dynamic field provides some extra packet information
254 * to interact with RTE Flow engine. The metadata in sent mbufs can be
255 * used to match on some Flows. The metadata in received mbufs can
256 * provide some feedback from the Flows. The metadata flag tells
257 * whether the field contains actual value to send, or received one.
259 #define RTE_MBUF_DYNFIELD_METADATA_NAME "rte_flow_dynfield_metadata"
260 #define RTE_MBUF_DYNFLAG_METADATA_NAME "rte_flow_dynflag_metadata"
263 * The timestamp dynamic field provides some timing information, the
264 * units and time references (initial phase) are not explicitly defined
265 * but are maintained always the same for a given port. Some devices allow
266 * to query rte_eth_read_clock() that will return the current device
267 * timestamp. The dynamic Tx timestamp flag tells whether the field contains
268 * actual timestamp value for the packets being sent, this value can be
269 * used by PMD to schedule packet sending.
271 #define RTE_MBUF_DYNFIELD_TIMESTAMP_NAME "rte_dynfield_timestamp"
272 typedef uint64_t rte_mbuf_timestamp_t;
275 * Indicate that the timestamp field in the mbuf was filled by the driver.
277 #define RTE_MBUF_DYNFLAG_RX_TIMESTAMP_NAME "rte_dynflag_rx_timestamp"
281 * @b EXPERIMENTAL: this API may change without prior notice.
283 * Register dynamic mbuf field and flag for Rx timestamp.
285 * @param field_offset
286 * Pointer to the offset of the registered mbuf field, can be NULL.
287 * The same field is shared for Rx and Tx timestamp.
289 * Pointer to the mask of the registered offload flag, can be NULL.
291 * 0 on success, -1 otherwise.
292 * Possible values for rte_errno:
293 * - EEXIST: already registered with different parameters.
294 * - EPERM: called from a secondary process.
295 * - ENOENT: no more field or flag available.
296 * - ENOMEM: allocation failure.
299 int rte_mbuf_dyn_rx_timestamp_register(int *field_offset, uint64_t *rx_flag);
302 * When PMD sees the RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME flag set on the
303 * packet being sent it tries to synchronize the time of packet appearing
304 * on the wire with the specified packet timestamp. If the specified one
305 * is in the past it should be ignored, if one is in the distant future
306 * it should be capped with some reasonable value (in range of seconds).
308 * There is no any packet reordering according to timestamps is supposed,
309 * neither for packet within the burst, nor for the whole bursts, it is
310 * an entirely application responsibility to generate packets and its
311 * timestamps in desired order. The timestamps might be put only in
312 * the first packet in the burst providing the entire burst scheduling.
314 #define RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME "rte_dynflag_tx_timestamp"
318 * @b EXPERIMENTAL: this API may change without prior notice.
320 * Register dynamic mbuf field and flag for Tx timestamp.
322 * @param field_offset
323 * Pointer to the offset of the registered mbuf field, can be NULL.
324 * The same field is shared for Rx and Tx timestamp.
326 * Pointer to the mask of the registered offload flag, can be NULL.
328 * 0 on success, -1 otherwise.
329 * Possible values for rte_errno:
330 * - EEXIST: already registered with different parameters.
331 * - EPERM: called from a secondary process.
332 * - ENOENT: no more field or flag available.
333 * - ENOMEM: allocation failure.
336 int rte_mbuf_dyn_tx_timestamp_register(int *field_offset, uint64_t *tx_flag);
342 #endif /* _RTE_MBUF_DYN_H_ */