]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright 2019 6WIND S.A. | |
3 | */ | |
4 | ||
5 | #ifndef _RTE_MBUF_DYN_H_ | |
6 | #define _RTE_MBUF_DYN_H_ | |
7 | ||
8 | /** | |
9 | * @file | |
10 | * RTE Mbuf dynamic fields and flags | |
11 | * | |
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 | |
15 | * the API or ABI. | |
16 | * | |
17 | * This module addresses this issue, by enabling the dynamic | |
18 | * registration of fields or flags: | |
19 | * | |
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 | |
23 | * in mbuf->ol_flags. | |
24 | * | |
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. | |
29 | * | |
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. | |
33 | * | |
34 | * Example of use: | |
35 | * | |
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 | |
49 | * the same macro. | |
50 | * | |
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. | |
53 | * | |
54 | * The registration can be done at any moment, but it is not possible | |
55 | * to unregister fields or flags for now. | |
56 | * | |
57 | * A dynamic field can be reserved and used by an application only. | |
58 | * It can for instance be a packet mark. | |
59 | * | |
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 in PMD | |
66 | * - any name that does not start with "rte_" in an application | |
67 | */ | |
68 | ||
69 | #include <sys/types.h> | |
70 | /** | |
71 | * Maximum length of the dynamic field or flag string. | |
72 | */ | |
73 | #define RTE_MBUF_DYN_NAMESIZE 64 | |
74 | ||
75 | /** | |
76 | * Structure describing the parameters of a mbuf dynamic field. | |
77 | */ | |
78 | struct rte_mbuf_dynfield { | |
79 | char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */ | |
80 | size_t size; /**< The number of bytes to reserve. */ | |
81 | size_t align; /**< The alignment constraint (power of 2). */ | |
82 | unsigned int flags; /**< Reserved for future use, must be 0. */ | |
83 | }; | |
84 | ||
85 | /** | |
86 | * Structure describing the parameters of a mbuf dynamic flag. | |
87 | */ | |
88 | struct rte_mbuf_dynflag { | |
89 | char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */ | |
90 | unsigned int flags; /**< Reserved for future use, must be 0. */ | |
91 | }; | |
92 | ||
93 | /** | |
94 | * Register space for a dynamic field in the mbuf structure. | |
95 | * | |
96 | * If the field is already registered (same name and parameters), its | |
97 | * offset is returned. | |
98 | * | |
99 | * @param params | |
100 | * A structure containing the requested parameters (name, size, | |
101 | * alignment constraint and flags). | |
102 | * @return | |
103 | * The offset in the mbuf structure, or -1 on error. | |
104 | * Possible values for rte_errno: | |
105 | * - EINVAL: invalid parameters (size, align, or flags). | |
106 | * - EEXIST: this name is already register with different parameters. | |
107 | * - EPERM: called from a secondary process. | |
108 | * - ENOENT: not enough room in mbuf. | |
109 | * - ENOMEM: allocation failure. | |
110 | * - ENAMETOOLONG: name does not ends with \0. | |
111 | */ | |
112 | __rte_experimental | |
113 | int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params); | |
114 | ||
115 | /** | |
116 | * Register space for a dynamic field in the mbuf structure at offset. | |
117 | * | |
118 | * If the field is already registered (same name, parameters and offset), | |
119 | * the offset is returned. | |
120 | * | |
121 | * @param params | |
122 | * A structure containing the requested parameters (name, size, | |
123 | * alignment constraint and flags). | |
124 | * @param offset | |
125 | * The requested offset. Ignored if SIZE_MAX is passed. | |
126 | * @return | |
127 | * The offset in the mbuf structure, or -1 on error. | |
128 | * Possible values for rte_errno: | |
129 | * - EINVAL: invalid parameters (size, align, flags, or offset). | |
130 | * - EEXIST: this name is already register with different parameters. | |
131 | * - EBUSY: the requested offset cannot be used. | |
132 | * - EPERM: called from a secondary process. | |
133 | * - ENOENT: not enough room in mbuf. | |
134 | * - ENOMEM: allocation failure. | |
135 | * - ENAMETOOLONG: name does not ends with \0. | |
136 | */ | |
137 | __rte_experimental | |
138 | int rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params, | |
139 | size_t offset); | |
140 | ||
141 | /** | |
142 | * Lookup for a registered dynamic mbuf field. | |
143 | * | |
144 | * @param name | |
145 | * A string identifying the dynamic field. | |
146 | * @param params | |
147 | * If not NULL, and if the lookup is successful, the structure is | |
148 | * filled with the parameters of the dynamic field. | |
149 | * @return | |
150 | * The offset of this field in the mbuf structure, or -1 on error. | |
151 | * Possible values for rte_errno: | |
152 | * - ENOENT: no dynamic field matches this name. | |
153 | */ | |
154 | __rte_experimental | |
155 | int rte_mbuf_dynfield_lookup(const char *name, | |
156 | struct rte_mbuf_dynfield *params); | |
157 | ||
158 | /** | |
159 | * Register a dynamic flag in the mbuf structure. | |
160 | * | |
161 | * If the flag is already registered (same name and parameters), its | |
162 | * bitnum is returned. | |
163 | * | |
164 | * @param params | |
165 | * A structure containing the requested parameters of the dynamic | |
166 | * flag (name and options). | |
167 | * @return | |
168 | * The number of the reserved bit, or -1 on error. | |
169 | * Possible values for rte_errno: | |
170 | * - EINVAL: invalid parameters (size, align, or flags). | |
171 | * - EEXIST: this name is already register with different parameters. | |
172 | * - EPERM: called from a secondary process. | |
173 | * - ENOENT: no more flag available. | |
174 | * - ENOMEM: allocation failure. | |
175 | * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1. | |
176 | */ | |
177 | __rte_experimental | |
178 | int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params); | |
179 | ||
180 | /** | |
181 | * Register a dynamic flag in the mbuf structure specifying bitnum. | |
182 | * | |
183 | * If the flag is already registered (same name, parameters and bitnum), | |
184 | * the bitnum is returned. | |
185 | * | |
186 | * @param params | |
187 | * A structure containing the requested parameters of the dynamic | |
188 | * flag (name and options). | |
189 | * @param bitnum | |
190 | * The requested bitnum. Ignored if UINT_MAX is passed. | |
191 | * @return | |
192 | * The number of the reserved bit, or -1 on error. | |
193 | * Possible values for rte_errno: | |
194 | * - EINVAL: invalid parameters (size, align, or flags). | |
195 | * - EEXIST: this name is already register with different parameters. | |
196 | * - EBUSY: the requested bitnum cannot be used. | |
197 | * - EPERM: called from a secondary process. | |
198 | * - ENOENT: no more flag available. | |
199 | * - ENOMEM: allocation failure. | |
200 | * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1. | |
201 | */ | |
202 | __rte_experimental | |
203 | int rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params, | |
204 | unsigned int bitnum); | |
205 | ||
206 | /** | |
207 | * Lookup for a registered dynamic mbuf flag. | |
208 | * | |
209 | * @param name | |
210 | * A string identifying the dynamic flag. | |
211 | * @param params | |
212 | * If not NULL, and if the lookup is successful, the structure is | |
213 | * filled with the parameters of the dynamic flag. | |
214 | * @return | |
215 | * The offset of this flag in the mbuf structure, or -1 on error. | |
216 | * Possible values for rte_errno: | |
217 | * - ENOENT: no dynamic flag matches this name. | |
218 | */ | |
219 | __rte_experimental | |
220 | int rte_mbuf_dynflag_lookup(const char *name, | |
221 | struct rte_mbuf_dynflag *params); | |
222 | ||
223 | /** | |
224 | * Helper macro to access to a dynamic field. | |
225 | */ | |
226 | #define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset))) | |
227 | ||
228 | /** | |
229 | * Dump the status of dynamic fields and flags. | |
230 | * | |
231 | * @param out | |
232 | * The stream where the status is displayed. | |
233 | */ | |
234 | __rte_experimental | |
235 | void rte_mbuf_dyn_dump(FILE *out); | |
236 | ||
237 | /* | |
238 | * Placeholder for dynamic fields and flags declarations. | |
239 | * This is centralizing point to gather all field names | |
240 | * and parameters together. | |
241 | */ | |
242 | ||
243 | /* | |
244 | * The metadata dynamic field provides some extra packet information | |
245 | * to interact with RTE Flow engine. The metadata in sent mbufs can be | |
246 | * used to match on some Flows. The metadata in received mbufs can | |
247 | * provide some feedback from the Flows. The metadata flag tells | |
248 | * whether the field contains actual value to send, or received one. | |
249 | */ | |
250 | #define RTE_MBUF_DYNFIELD_METADATA_NAME "rte_flow_dynfield_metadata" | |
251 | #define RTE_MBUF_DYNFLAG_METADATA_NAME "rte_flow_dynflag_metadata" | |
252 | ||
253 | #endif |