Line data Source code
1 : /*
2 : * Copyright (c) 2016 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #ifndef included_features_h
17 : #define included_features_h
18 :
19 : #include <vnet/vnet.h>
20 : #include <vnet/api_errno.h>
21 : #include <vnet/devices/devices.h>
22 :
23 : /** feature registration object */
24 : typedef struct _vnet_feature_arc_registration
25 : {
26 : /** next registration in list of all registrations*/
27 : struct _vnet_feature_arc_registration *next;
28 : /** Feature Arc name */
29 : char *arc_name;
30 : /** Start nodes */
31 : char **start_nodes;
32 : int n_start_nodes;
33 : /** End of the arc (optional, for consistency-checking) */
34 : char *last_in_arc;
35 : /* Feature arc index, assigned by init function */
36 : u8 feature_arc_index;
37 : u8 *arc_index_ptr;
38 : } vnet_feature_arc_registration_t;
39 :
40 : /* Enable feature callback. */
41 : typedef clib_error_t *(vnet_feature_enable_disable_function_t)
42 : (u32 sw_if_index, int enable_disable);
43 :
44 : /** feature registration object */
45 : typedef struct _vnet_feature_registration
46 : {
47 : /** next registration in list of all registrations*/
48 : struct _vnet_feature_registration *next, *next_in_arc;
49 : /** Feature arc name */
50 : char *arc_name;
51 : /** Graph node name */
52 : char *node_name;
53 : /** Pointer to this feature index, filled in by vnet_feature_arc_init */
54 : u32 *feature_index_ptr;
55 : u32 feature_index;
56 : /** Constraints of the form "this feature runs before X" */
57 : char **runs_before;
58 : /** Constraints of the form "this feature runs after Y" */
59 : char **runs_after;
60 :
61 : /** Function to enable/disable feature **/
62 : vnet_feature_enable_disable_function_t *enable_disable_cb;
63 : } vnet_feature_registration_t;
64 :
65 : /** constraint registration object */
66 : typedef struct _vnet_feature_constraint_registration
67 : {
68 : /** next constraint set in list of all registrations*/
69 : struct _vnet_feature_constraint_registration *next, *next_in_arc;
70 : /** Feature arc name */
71 : char *arc_name;
72 :
73 : /** Feature arc index, assigned by init function */
74 : u8 feature_arc_index;
75 :
76 : /** Node names, to run in the specified order */
77 : char **node_names;
78 : } vnet_feature_constraint_registration_t;
79 :
80 : typedef struct vnet_feature_config_main_t_
81 : {
82 : vnet_config_main_t config_main;
83 : u32 *config_index_by_sw_if_index;
84 : } vnet_feature_config_main_t;
85 :
86 : typedef struct
87 : {
88 : /** feature arc configuration list */
89 : vnet_feature_arc_registration_t *next_arc;
90 : uword **arc_index_by_name;
91 :
92 : /** feature path configuration lists */
93 : vnet_feature_registration_t *next_feature;
94 : vnet_feature_registration_t **next_feature_by_arc;
95 : vnet_feature_constraint_registration_t *next_constraint;
96 : vnet_feature_constraint_registration_t **next_constraint_by_arc;
97 : uword **next_feature_by_name;
98 :
99 : /** feature config main objects */
100 : vnet_feature_config_main_t *feature_config_mains;
101 :
102 : /** Save partial order results for show command */
103 : char ***feature_nodes;
104 :
105 : /** bitmap of interfaces which have driver rx features configured */
106 : uword **sw_if_index_has_features;
107 :
108 : /** feature reference counts by interface */
109 : i16 **feature_count_by_sw_if_index;
110 :
111 : /** Feature arc index for device-input */
112 : u8 device_input_feature_arc_index;
113 :
114 : /** convenience */
115 : vlib_main_t *vlib_main;
116 : vnet_main_t *vnet_main;
117 : } vnet_feature_main_t;
118 :
119 : extern vnet_feature_main_t feature_main;
120 :
121 : #ifndef CLIB_MARCH_VARIANT
122 : #define VNET_FEATURE_ARC_INIT(x,...) \
123 : __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x;\
124 : static void __vnet_add_feature_arc_registration_##x (void) \
125 : __attribute__((__constructor__)) ; \
126 : static void __vnet_add_feature_arc_registration_##x (void) \
127 : { \
128 : vnet_feature_main_t * fm = &feature_main; \
129 : vnet_feat_arc_##x.next = fm->next_arc; \
130 : fm->next_arc = & vnet_feat_arc_##x; \
131 : } \
132 : static void __vnet_rm_feature_arc_registration_##x (void) \
133 : __attribute__((__destructor__)) ; \
134 : static void __vnet_rm_feature_arc_registration_##x (void) \
135 : { \
136 : vnet_feature_main_t * fm = &feature_main; \
137 : vnet_feature_arc_registration_t *r = &vnet_feat_arc_##x; \
138 : VLIB_REMOVE_FROM_LINKED_LIST (fm->next_arc, r, next); \
139 : } \
140 : __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x
141 :
142 : #define VNET_FEATURE_INIT(x,...) \
143 : __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x; \
144 : static void __vnet_add_feature_registration_##x (void) \
145 : __attribute__((__constructor__)) ; \
146 : static void __vnet_add_feature_registration_##x (void) \
147 : { \
148 : vnet_feature_main_t * fm = &feature_main; \
149 : vnet_feat_##x.next = fm->next_feature; \
150 : fm->next_feature = & vnet_feat_##x; \
151 : } \
152 : static void __vnet_rm_feature_registration_##x (void) \
153 : __attribute__((__destructor__)) ; \
154 : static void __vnet_rm_feature_registration_##x (void) \
155 : { \
156 : vnet_feature_main_t * fm = &feature_main; \
157 : vnet_feature_registration_t *r = &vnet_feat_##x; \
158 : VLIB_REMOVE_FROM_LINKED_LIST (fm->next_feature, r, next); \
159 : } \
160 : __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x
161 :
162 : #define VNET_FEATURE_ARC_ORDER(x,...) \
163 : __VA_ARGS__ vnet_feature_constraint_registration_t \
164 : vnet_feature_constraint_##x; \
165 : static void __vnet_add_constraint_registration_##x (void) \
166 : __attribute__((__constructor__)) ; \
167 : static void __vnet_add_constraint_registration_##x (void) \
168 : { \
169 : vnet_feature_main_t * fm = &feature_main; \
170 : vnet_feature_constraint_##x.next = fm->next_constraint; \
171 : fm->next_constraint = & vnet_feature_constraint_##x; \
172 : } \
173 : static void __vnet_rm_constraint_registration_##x (void) \
174 : __attribute__((__destructor__)) ; \
175 : static void __vnet_rm_constraint_registration_##x (void) \
176 : { \
177 : vnet_feature_main_t * fm = &feature_main; \
178 : vnet_feature_constraint_registration_t *r = &vnet_feature_constraint_##x; \
179 : VLIB_REMOVE_FROM_LINKED_LIST (fm->next_constraint, r, next); \
180 : } \
181 : __VA_ARGS__ vnet_feature_constraint_registration_t vnet_feature_constraint_##x
182 :
183 : #else
184 : #define VNET_FEATURE_ARC_INIT(x,...) \
185 : extern vnet_feature_arc_registration_t __clib_unused vnet_feat_arc_##x; \
186 : static vnet_feature_arc_registration_t __clib_unused __clib_unused_vnet_feat_arc_##x
187 : #define VNET_FEATURE_INIT(x,...) \
188 : extern vnet_feature_registration_t __clib_unused vnet_feat_##x; \
189 : static vnet_feature_registration_t __clib_unused __clib_unused_vnet_feat_##x
190 :
191 : #define VNET_FEATURE_ARC_ORDER(x,...) \
192 : extern vnet_feature_constraint_registration_t \
193 : __clib_unused vnet_feature_constraint_##x; \
194 : static vnet_feature_constraint_registration_t __clib_unused \
195 : __clib_unused_vnet_feature_constraint_##x
196 :
197 :
198 : #endif
199 :
200 : void
201 : vnet_config_update_feature_count (vnet_feature_main_t * fm, u8 arc,
202 : u32 sw_if_index, int is_add);
203 :
204 : u32 vnet_get_feature_index (u8 arc, const char *s);
205 : u8 vnet_get_feature_arc_index (const char *s);
206 : vnet_feature_registration_t *vnet_get_feature_reg (const char *arc_name,
207 : const char *node_name);
208 :
209 :
210 : int
211 : vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index,
212 : u32 sw_if_index, int enable_disable,
213 : void *feature_config,
214 : u32 n_feature_config_bytes);
215 :
216 : int
217 : vnet_feature_enable_disable (const char *arc_name, const char *node_name,
218 : u32 sw_if_index, int enable_disable,
219 : void *feature_config,
220 : u32 n_feature_config_bytes);
221 :
222 : u32
223 : vnet_feature_modify_end_node (u8 arc_index, u32 sw_if_index, u32 node_index);
224 :
225 : u32 vnet_feature_get_end_node (u8 arc_index, u32 sw_if_index);
226 :
227 : u32 vnet_feature_reset_end_node (u8 arc_index, u32 sw_if_index);
228 :
229 : static_always_inline u32
230 0 : vnet_get_feature_count (u8 arc, u32 sw_if_index)
231 : {
232 0 : vnet_feature_main_t *fm = &feature_main;
233 0 : return (fm->feature_count_by_sw_if_index[arc][sw_if_index]);
234 : }
235 :
236 : static inline vnet_feature_config_main_t *
237 352 : vnet_get_feature_arc_config_main (u8 arc_index)
238 : {
239 352 : vnet_feature_main_t *fm = &feature_main;
240 :
241 352 : if (arc_index == (u8) ~ 0)
242 0 : return 0;
243 :
244 352 : return &fm->feature_config_mains[arc_index];
245 : }
246 :
247 : static_always_inline vnet_feature_config_main_t *
248 2239 : vnet_feature_get_config_main (u16 arc)
249 : {
250 2239 : vnet_feature_main_t *fm = &feature_main;
251 2239 : return &fm->feature_config_mains[arc];
252 : }
253 :
254 : static_always_inline int
255 63229555 : vnet_have_features (u8 arc, u32 sw_if_index)
256 : {
257 63229555 : vnet_feature_main_t *fm = &feature_main;
258 63229555 : return clib_bitmap_get (fm->sw_if_index_has_features[arc], sw_if_index);
259 : }
260 :
261 : static_always_inline u32
262 11 : vnet_get_feature_config_index (u8 arc, u32 sw_if_index)
263 : {
264 11 : vnet_feature_main_t *fm = &feature_main;
265 11 : vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
266 11 : return vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
267 : }
268 :
269 : static_always_inline void *
270 36589535 : vnet_feature_arc_start_with_data (u8 arc, u32 sw_if_index, u32 * next,
271 : vlib_buffer_t * b, u32 n_data_bytes)
272 : {
273 36589535 : vnet_feature_main_t *fm = &feature_main;
274 : vnet_feature_config_main_t *cm;
275 36589535 : cm = &fm->feature_config_mains[arc];
276 :
277 36589535 : if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
278 : {
279 24217557 : vnet_buffer (b)->feature_arc_index = arc;
280 24217545 : b->current_config_index =
281 24217557 : vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
282 24217545 : return vnet_get_config_data (&cm->config_main, &b->current_config_index,
283 : next, n_data_bytes);
284 : }
285 12372026 : return 0;
286 : }
287 :
288 : static_always_inline void *
289 11757890 : vnet_feature_arc_start_w_cfg_index (u8 arc,
290 : u32 sw_if_index,
291 : u32 * next,
292 : vlib_buffer_t * b, u32 cfg_index)
293 : {
294 11757890 : vnet_feature_main_t *fm = &feature_main;
295 : vnet_feature_config_main_t *cm;
296 11757890 : cm = &fm->feature_config_mains[arc];
297 :
298 11757890 : vnet_buffer (b)->feature_arc_index = arc;
299 11757890 : b->current_config_index = cfg_index;
300 :
301 11757890 : return vnet_get_config_data (&cm->config_main, &b->current_config_index,
302 : next, 0);
303 : }
304 :
305 : static_always_inline void
306 36589535 : vnet_feature_arc_start (u8 arc, u32 sw_if_index, u32 * next0,
307 : vlib_buffer_t * b0)
308 : {
309 36589535 : vnet_feature_arc_start_with_data (arc, sw_if_index, next0, b0, 0);
310 36589545 : }
311 :
312 : static_always_inline void *
313 40974149 : vnet_feature_next_with_data (u32 * next0, vlib_buffer_t * b0,
314 : u32 n_data_bytes)
315 : {
316 40974149 : vnet_feature_main_t *fm = &feature_main;
317 40974149 : u8 arc = vnet_buffer (b0)->feature_arc_index;
318 40974149 : vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
319 :
320 40974149 : return vnet_get_config_data (&cm->config_main,
321 : &b0->current_config_index, next0,
322 : n_data_bytes);
323 : }
324 :
325 : static_always_inline void
326 40501860 : vnet_feature_next (u32 * next0, vlib_buffer_t * b0)
327 : {
328 40501860 : vnet_feature_next_with_data (next0, b0, 0);
329 40501899 : }
330 :
331 : static_always_inline void
332 12777 : vnet_feature_next_u16 (u16 * next0, vlib_buffer_t * b0)
333 : {
334 : u32 next32;
335 12777 : vnet_feature_next_with_data (&next32, b0, 0);
336 12777 : *next0 = next32;
337 12777 : }
338 :
339 : static_always_inline int
340 0 : vnet_device_input_have_features (u32 sw_if_index)
341 : {
342 0 : vnet_feature_main_t *fm = &feature_main;
343 0 : return vnet_have_features (fm->device_input_feature_arc_index, sw_if_index);
344 : }
345 :
346 : static_always_inline void
347 2123973 : vnet_feature_start_device_input (u32 sw_if_index, u32 *next0,
348 : vlib_buffer_t *b0)
349 : {
350 2123973 : vnet_feature_main_t *fm = &feature_main;
351 : vnet_feature_config_main_t *cm;
352 2123973 : u8 feature_arc_index = fm->device_input_feature_arc_index;
353 2123973 : cm = &fm->feature_config_mains[feature_arc_index];
354 :
355 2123973 : if (PREDICT_FALSE
356 : (clib_bitmap_get
357 : (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
358 : {
359 21 : vnet_buffer (b0)->feature_arc_index = feature_arc_index;
360 21 : b0->current_config_index =
361 21 : vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
362 21 : vnet_get_config_data (&cm->config_main, &b0->current_config_index,
363 : next0, /* # bytes of config data */ 0);
364 : }
365 2123973 : }
366 :
367 : #define VNET_FEATURES(...) (char*[]) { __VA_ARGS__, 0}
368 :
369 : clib_error_t *vnet_feature_arc_init
370 : (vlib_main_t * vm,
371 : vnet_config_main_t * vcm,
372 : char **feature_start_nodes,
373 : int num_feature_start_nodes,
374 : char *last_in_arc,
375 : vnet_feature_registration_t * first_reg,
376 : vnet_feature_constraint_registration_t * first_const_set,
377 : char ***in_feature_nodes);
378 :
379 : void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
380 : int verbose);
381 :
382 : typedef void (*vnet_feature_update_cb_t) (u32 sw_if_index,
383 : u8 arc_index,
384 : u8 is_enable, void *cb);
385 :
386 : extern void vnet_feature_register (vnet_feature_update_cb_t cb, void *data);
387 :
388 : int
389 : vnet_feature_is_enabled (const char *arc_name, const char *feature_node_name,
390 : u32 sw_if_index);
391 :
392 : #endif /* included_feature_h */
393 :
394 : /*
395 : * fd.io coding-style-patch-verification: ON
396 : *
397 : * Local Variables:
398 : * eval: (c-set-style "gnu")
399 : * End:
400 : */
|