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 features require to store data inside the mbuf. As the room in
13 * 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 typical use case is when a specific offload feature requires to
26 * register a dedicated offload field in the mbuf structure, and adding
27 * a static field or flag is not justified.
31 * - A rte_mbuf_dynfield structure is defined, containing the parameters
32 * of the dynamic field to be registered:
33 * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
34 * - The application initializes the PMD, and asks for this feature
35 * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
36 * rxconf. This will make the PMD to register the field by calling
37 * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
38 * stores the returned offset.
39 * - The application that uses the offload feature also registers
40 * the field to retrieve the same offset.
41 * - When the PMD receives a packet, it can set the field:
42 * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
43 * - In the main loop, the application can retrieve the value with
46 * To avoid wasting space, the dynamic fields or flags must only be
47 * reserved on demand, when an application asks for the related feature.
49 * The registration can be done at any moment, but it is not possible
50 * to unregister fields or flags for now.
52 * A dynamic field can be reserved and used by an application only.
53 * It can for instance be a packet mark.
56 #include <sys/types.h>
61 * Maximum length of the dynamic field or flag string.
63 #define RTE_MBUF_DYN_NAMESIZE 64
66 * Structure describing the parameters of a mbuf dynamic field.
68 struct rte_mbuf_dynfield {
69 char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
70 size_t size; /**< The number of bytes to reserve. */
71 size_t align; /**< The alignment constraint (power of 2). */
72 unsigned int flags; /**< Reserved for future use, must be 0. */
76 * Structure describing the parameters of a mbuf dynamic flag.
78 struct rte_mbuf_dynflag {
79 char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */
80 unsigned int flags; /**< Reserved for future use, must be 0. */
84 * Register space for a dynamic field in the mbuf structure.
86 * If the field is already registered (same name and parameters), its
90 * A structure containing the requested parameters (name, size,
91 * alignment constraint and flags).
93 * The offset in the mbuf structure, or -1 on error.
94 * Possible values for rte_errno:
95 * - EINVAL: invalid parameters (size, align, or flags).
96 * - EEXIST: this name is already register with different parameters.
97 * - EPERM: called from a secondary process.
98 * - ENOENT: not enough room in mbuf.
99 * - ENOMEM: allocation failure.
100 * - ENAMETOOLONG: name does not ends with \0.
103 int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
106 * Lookup for a registered dynamic mbuf field.
109 * A string identifying the dynamic field.
111 * If not NULL, and if the lookup is successful, the structure is
112 * filled with the parameters of the dynamic field.
114 * The offset of this field in the mbuf structure, or -1 on error.
115 * Possible values for rte_errno:
116 * - ENOENT: no dynamic field matches this name.
119 int rte_mbuf_dynfield_lookup(const char *name,
120 struct rte_mbuf_dynfield *params);
123 * Register a dynamic flag in the mbuf structure.
125 * If the flag is already registered (same name and parameters), its
126 * offset is returned.
129 * A structure containing the requested parameters of the dynamic
130 * flag (name and options).
132 * The number of the reserved bit, or -1 on error.
133 * Possible values for rte_errno:
134 * - EINVAL: invalid parameters (size, align, or flags).
135 * - EEXIST: this name is already register with different parameters.
136 * - EPERM: called from a secondary process.
137 * - ENOENT: no more flag available.
138 * - ENOMEM: allocation failure.
139 * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
142 int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
145 * Lookup for a registered dynamic mbuf flag.
148 * A string identifying the dynamic flag.
150 * If not NULL, and if the lookup is successful, the structure is
151 * filled with the parameters of the dynamic flag.
153 * The offset of this flag in the mbuf structure, or -1 on error.
154 * Possible values for rte_errno:
155 * - ENOENT: no dynamic flag matches this name.
158 int rte_mbuf_dynflag_lookup(const char *name,
159 struct rte_mbuf_dynflag *params);
162 * Helper macro to access to a dynamic field.
164 #define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
166 /* Placeholder for dynamic fields and flags declarations. */
167 extern const struct rte_mbuf_dynfield rte_mbuf_dynfield_timestamp;
168 extern int rte_mbuf_dynfield_timestamp_offset;
169 extern const struct rte_mbuf_dynflag rte_mbuf_dynflag_timestamp;
170 extern int rte_mbuf_dynflag_timestamp_bitnum;
173 * Register timestamp dynamic field and flag.
176 * 0 on success, or -1 on error (rte_errno is set, see
177 * rte_mbuf_dynfield_register() and rte_mbuf_dynflag_register()
181 int rte_mbuf_dyn_timestamp_register(void);
184 * Set timestamp dynamic field and flag in mbuf.
186 * rte_mbuf_dyn_timestamp_register() must have been called first.
189 static inline void rte_mbuf_dyn_timestamp_set(struct rte_mbuf *m,
192 *RTE_MBUF_DYNFIELD(m, rte_mbuf_dynfield_timestamp_offset,
193 uint64_t *) = timestamp;
194 m->ol_flags |= (1UL << rte_mbuf_dynflag_timestamp_bitnum);
198 * Get timestamp dynamic field value in mbuf.
200 * rte_mbuf_dyn_timestamp_register() must have been called first.
203 static inline uint64_t rte_mbuf_dyn_timestamp_get(const struct rte_mbuf *m)
205 return *RTE_MBUF_DYNFIELD(m, rte_mbuf_dynfield_timestamp_offset,
210 * Delete the timestamp dynamic flag in mbuf.
212 * rte_mbuf_dyn_timestamp_register() must have been called first.
215 static inline void rte_mbuf_dyn_timestamp_del(struct rte_mbuf *m)
217 m->ol_flags &= ~(1UL << rte_mbuf_dynflag_timestamp_bitnum);
221 * Check timestamp dynamic flag value in mbuf.
223 * rte_mbuf_dyn_timestamp_register() must have been called first.
226 static inline bool rte_mbuf_dyn_timestamp_avail(const struct rte_mbuf *m)
228 return m->ol_flags & (1UL << rte_mbuf_dynflag_timestamp_bitnum);