FD.io VPP  v20.09-rc2-28-g3c5414029
Vector Packet Processing
feature.c
Go to the documentation of this file.
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 #include <vnet/feature/feature.h>
17 
19 
21 {
23  void *data;
25 
27 
28 void
30 {
32 
33  vec_add2 (regs, reg, 1);
34 
35  reg->cb = cb;
36  reg->data = data;
37 }
38 
39 static void
40 vent_feature_reg_invoke (u32 sw_if_index, u8 arc_index, u8 is_enable)
41 {
43 
44  vec_foreach (reg, regs)
45  reg->cb (sw_if_index, arc_index, is_enable, reg->data);
46 }
47 
48 
49 static clib_error_t *
51 {
56  u32 arc_index = 0;
57 
58  fm->arc_index_by_name = hash_create_string (0, sizeof (uword));
59  areg = fm->next_arc;
60 
61  /* process feature arc registrations */
62  while (areg)
63  {
64  char *s;
65  int i = 0;
66  areg->feature_arc_index = arc_index;
67  if (areg->arc_index_ptr)
68  *areg->arc_index_ptr = arc_index;
69  hash_set_mem (fm->arc_index_by_name, areg->arc_name,
70  pointer_to_uword (areg));
71 
72  /* process start nodes */
73  while ((s = areg->start_nodes[i]))
74  {
75  i++;
76  }
77  areg->n_start_nodes = i;
78 
79  /* next */
80  areg = areg->next;
81  arc_index++;
82  }
83 
84  vec_validate (fm->next_feature_by_arc, arc_index - 1);
85  vec_validate (fm->feature_nodes, arc_index - 1);
86  vec_validate (fm->feature_config_mains, arc_index - 1);
87  vec_validate (fm->next_feature_by_name, arc_index - 1);
88  vec_validate (fm->sw_if_index_has_features, arc_index - 1);
89  vec_validate (fm->feature_count_by_sw_if_index, arc_index - 1);
90  vec_validate (fm->next_constraint_by_arc, arc_index - 1);
91 
92  freg = fm->next_feature;
93  while (freg)
94  {
96  uword *p = hash_get_mem (fm->arc_index_by_name, freg->arc_name);
97  if (p == 0)
98  {
99  /* Don't start vpp with broken features arcs */
100  clib_warning ("Unknown feature arc '%s'", freg->arc_name);
101  os_exit (1);
102  }
103 
105  arc_index = areg->feature_arc_index;
106 
107  next = freg->next;
108  freg->next_in_arc = fm->next_feature_by_arc[arc_index];
109  fm->next_feature_by_arc[arc_index] = freg;
110 
111  /* next */
112  freg = next;
113  }
114 
115  /* Move bulk constraints to the constraint by arc lists */
116  creg = fm->next_constraint;
117  while (creg)
118  {
120  uword *p = hash_get_mem (fm->arc_index_by_name, creg->arc_name);
121  if (p == 0)
122  {
123  /* Don't start vpp with broken features arcs */
124  clib_warning ("Unknown feature arc '%s'", creg->arc_name);
125  os_exit (1);
126  }
127 
129  arc_index = areg->feature_arc_index;
130 
131  next = creg->next;
132  creg->next_in_arc = fm->next_constraint_by_arc[arc_index];
133  fm->next_constraint_by_arc[arc_index] = creg;
134 
135  /* next */
136  creg = next;
137  }
138 
139 
140  areg = fm->next_arc;
141  while (areg)
142  {
143  clib_error_t *error;
145  vnet_config_main_t *vcm;
146  char **features_in_order, *last_feature;
147 
148  arc_index = areg->feature_arc_index;
149  cm = &fm->feature_config_mains[arc_index];
150  vcm = &cm->config_main;
151  if ((error = vnet_feature_arc_init
152  (vm, vcm, areg->start_nodes, areg->n_start_nodes,
153  areg->last_in_arc,
154  fm->next_feature_by_arc[arc_index],
155  fm->next_constraint_by_arc[arc_index],
156  &fm->feature_nodes[arc_index])))
157  {
158  clib_error_report (error);
159  os_exit (1);
160  }
161 
162  features_in_order = fm->feature_nodes[arc_index];
163 
164  /* If specified, verify that the last node in the arc is actually last */
165  if (areg->last_in_arc && vec_len (features_in_order) > 0)
166  {
167  last_feature = features_in_order[vec_len (features_in_order) - 1];
168  if (strncmp (areg->last_in_arc, last_feature,
169  strlen (areg->last_in_arc)))
171  ("WARNING: %s arc: last node is %s, but expected %s!",
172  areg->arc_name, last_feature, areg->last_in_arc);
173  }
174 
175  fm->next_feature_by_name[arc_index] =
176  hash_create_string (0, sizeof (uword));
177  freg = fm->next_feature_by_arc[arc_index];
178 
179  while (freg)
180  {
181  hash_set_mem (fm->next_feature_by_name[arc_index],
182  freg->node_name, pointer_to_uword (freg));
183  freg = freg->next_in_arc;
184  }
185 
186  /* next */
187  areg = areg->next;
188  arc_index++;
189  }
190 
191  return 0;
192 }
193 
195 
196 u8
198 {
201  uword *p;
202 
203  p = hash_get_mem (fm->arc_index_by_name, s);
204  if (p == 0)
205  return ~0;
206 
208  return reg->feature_arc_index;
209 }
210 
212 vnet_get_feature_reg (const char *arc_name, const char *node_name)
213 {
214  u8 arc_index;
215 
216  arc_index = vnet_get_feature_arc_index (arc_name);
217  if (arc_index == (u8) ~ 0)
218  return 0;
219 
222  uword *p;
223 
224  p = hash_get_mem (fm->next_feature_by_name[arc_index], node_name);
225  if (p == 0)
226  return 0;
227 
229  return reg;
230 }
231 
232 u32
233 vnet_get_feature_index (u8 arc, const char *s)
234 {
237  uword *p;
238 
239  if (s == 0)
240  return ~0;
241 
242  p = hash_get_mem (fm->next_feature_by_name[arc], s);
243  if (p == 0)
244  return ~0;
245 
247  return reg->feature_index;
248 }
249 
250 int
252  u32 sw_if_index, int enable_disable,
253  void *feature_config,
254  u32 n_feature_config_bytes)
255 {
258  i16 feature_count;
259  u32 ci;
260 
261  if (arc_index == (u8) ~ 0)
262  return VNET_API_ERROR_INVALID_VALUE;
263 
264  if (feature_index == ~0)
265  return VNET_API_ERROR_INVALID_VALUE_2;
266 
267  cm = &fm->feature_config_mains[arc_index];
270 
271  vec_validate (fm->feature_count_by_sw_if_index[arc_index], sw_if_index);
272  feature_count = fm->feature_count_by_sw_if_index[arc_index][sw_if_index];
273 
274  if (!enable_disable && feature_count < 1)
275  return 0;
276 
277  ci = (enable_disable
280  (vlib_get_main (), &cm->config_main, ci, feature_index, feature_config,
281  n_feature_config_bytes);
282  if (ci == ~0)
283  {
284  return 0;
285  }
287 
288  /* update feature count */
289  enable_disable = (enable_disable > 0);
290  feature_count += enable_disable ? 1 : -1;
291  ASSERT (feature_count >= 0);
292 
293  fm->sw_if_index_has_features[arc_index] =
294  clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index,
295  (feature_count > 0));
296  vent_feature_reg_invoke (sw_if_index, arc_index, (feature_count > 0));
297 
298  fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count;
299  return 0;
300 }
301 
302 int
303 vnet_feature_enable_disable (const char *arc_name, const char *node_name,
304  u32 sw_if_index, int enable_disable,
305  void *feature_config, u32 n_feature_config_bytes)
306 {
307  u32 feature_index;
308  u8 arc_index;
309 
310  arc_index = vnet_get_feature_arc_index (arc_name);
311 
312  if (arc_index == (u8) ~ 0)
313  return VNET_API_ERROR_INVALID_VALUE;
314 
315  feature_index = vnet_get_feature_index (arc_index, node_name);
316 
317  return vnet_feature_enable_disable_with_index (arc_index, feature_index,
318  sw_if_index, enable_disable,
319  feature_config,
320  n_feature_config_bytes);
321 }
322 
323 int
324 vnet_feature_is_enabled (const char *arc_name, const char *feature_node_name,
326 {
329  vnet_config_main_t *ccm;
330  vnet_config_t *current_config;
332  u32 feature_index;
333  u32 ci;
334  u8 arc_index;
335  u32 *p;
336 
337  arc_index = vnet_get_feature_arc_index (arc_name);
338 
339  /* No such arc? */
340  if (arc_index == (u8) ~ 0)
341  return VNET_API_ERROR_INVALID_VALUE;
342 
343  feature_index = vnet_get_feature_index (arc_index, feature_node_name);
344 
345  /* No such feature? */
346  if (feature_index == (u32) ~ 0)
347  return VNET_API_ERROR_INVALID_VALUE_2;
348 
349  cm = &fm->feature_config_mains[arc_index];
350 
351  if (sw_if_index < vec_len (cm->config_index_by_sw_if_index))
352  ci = vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
353  else
354  /* sw_if_index out of range, certainly not enabled */
355  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
356 
357  /* No features were ever configured? */
358  if (ci == ~0)
359  return 0;
360 
361  ccm = &cm->config_main;
362 
363  p = heap_elt_at_index (ccm->config_string_heap, ci);
364 
365  current_config = pool_elt_at_index (ccm->config_pool, p[-1]);
366 
367  /* Find feature with the required index */
368  vec_foreach (f, current_config->features)
369  {
370  if (f->feature_index == feature_index)
371  /* Feature was enabled */
372  return 1;
373  }
374  /* feature wasn't enabled */
375  return 0;
376 }
377 
378 
379 u32
381  u32 sw_if_index, u32 end_node_index)
382 {
385  u32 ci;
386 
387  if (arc_index == (u8) ~ 0)
388  return VNET_API_ERROR_INVALID_VALUE;
389 
390  if (end_node_index == ~0)
391  return VNET_API_ERROR_INVALID_VALUE_2;
392 
393  cm = &fm->feature_config_mains[arc_index];
396 
398  ci, end_node_index);
399 
400  if (ci != ~0)
402 
403  return ci;
404 }
405 
406 static int
407 feature_cmp (void *a1, void *a2)
408 {
409  vnet_feature_registration_t *reg1 = a1;
410  vnet_feature_registration_t *reg2 = a2;
411 
412  return (int) reg1->feature_index - reg2->feature_index;
413 }
414 
415 /** Display the set of available driver features.
416  Useful for verifying that expected features are present
417 */
418 
419 static clib_error_t *
421  unformat_input_t * input, vlib_cli_command_t * cmd)
422 {
426  vnet_feature_registration_t *feature_regs = 0;
427  int verbose = 0;
428 
429  if (unformat (input, "verbose"))
430  verbose = 1;
431 
432  vlib_cli_output (vm, "Available feature paths");
433 
434  areg = fm->next_arc;
435  while (areg)
436  {
437  if (verbose)
438  vlib_cli_output (vm, "[%2d] %s:", areg->feature_arc_index,
439  areg->arc_name);
440  else
441  vlib_cli_output (vm, "%s:", areg->arc_name);
442 
443  freg = fm->next_feature_by_arc[areg->feature_arc_index];
444  while (freg)
445  {
446  vec_add1 (feature_regs, freg[0]);
447  freg = freg->next_in_arc;
448  }
449 
450  vec_sort_with_function (feature_regs, feature_cmp);
451 
452  vec_foreach (freg, feature_regs)
453  {
454  if (verbose)
455  vlib_cli_output (vm, " [%2d]: %s\n", freg->feature_index,
456  freg->node_name);
457  else
458  vlib_cli_output (vm, " %s\n", freg->node_name);
459  }
460  vec_reset_length (feature_regs);
461  /* next */
462  areg = areg->next;
463  }
464  vec_free (feature_regs);
465 
466  return 0;
467 }
468 
469 /*?
470  * Display the set of available driver features
471  *
472  * @cliexpar
473  * Example:
474  * @cliexcmd{show features [verbose]}
475  * @cliexend
476  * @endparblock
477 ?*/
478 /* *INDENT-OFF* */
479 VLIB_CLI_COMMAND (show_features_command, static) = {
480  .path = "show features",
481  .short_help = "show features [verbose]",
482  .function = show_features_command_fn,
483 };
484 /* *INDENT-ON* */
485 
486 /** Display the set of driver features configured on a specific interface
487  * Called by "show interface" handler
488  */
489 
490 void
492 {
494  u32 node_index, current_config_index;
495  u16 feature_arc;
498  vnet_config_main_t *vcm;
499  vnet_config_t *cfg;
500  u32 cfg_index;
501  vnet_config_feature_t *feat;
502  vlib_node_t *n;
503  int i;
504 
505  vlib_cli_output (vm, "Feature paths configured on %U...",
507  vnet_get_main (), sw_if_index);
508 
509  areg = fm->next_arc;
510  while (areg)
511  {
512  feature_arc = areg->feature_arc_index;
513  vcm = &(cm[feature_arc].config_main);
514 
515  vlib_cli_output (vm, "\n%s:", areg->arc_name);
516  areg = areg->next;
517 
518  if (NULL == cm[feature_arc].config_index_by_sw_if_index ||
519  vec_len (cm[feature_arc].config_index_by_sw_if_index) <=
520  sw_if_index)
521  {
522  vlib_cli_output (vm, " none configured");
523  continue;
524  }
525 
526  current_config_index =
527  vec_elt (cm[feature_arc].config_index_by_sw_if_index, sw_if_index);
528 
529  if (current_config_index == ~0)
530  {
531  vlib_cli_output (vm, " none configured");
532  continue;
533  }
534 
535  ASSERT (current_config_index
537 
538  cfg_index = vcm->config_pool_index_by_user_index[current_config_index];
539  cfg = pool_elt_at_index (vcm->config_pool, cfg_index);
540 
541  for (i = 0; i < vec_len (cfg->features); i++)
542  {
543  feat = cfg->features + i;
544  node_index = feat->node_index;
545  n = vlib_get_node (vm, node_index);
546  if (verbose)
547  vlib_cli_output (vm, " [%2d] %v", feat->feature_index, n->name);
548  else
549  vlib_cli_output (vm, " %v", n->name);
550  }
551  if (verbose)
552  {
553  n =
554  vlib_get_node (vm,
556  [current_config_index]);
557  vlib_cli_output (vm, " [end] %v", n->name);
558  }
559  }
560 }
561 
562 static clib_error_t *
564  unformat_input_t * input,
565  vlib_cli_command_t * cmd)
566 {
567  vnet_main_t *vnm = vnet_get_main ();
568  unformat_input_t _line_input, *line_input = &_line_input;
569  clib_error_t *error = 0;
570 
571  u8 *arc_name = 0;
572  u8 *feature_name = 0;
573  u32 sw_if_index = ~0;
574  u8 enable = 1;
575 
576  /* Get a line of input. */
577  if (!unformat_user (input, unformat_line_input, line_input))
578  return 0;
579 
580  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
581  {
582  if (unformat
583  (line_input, "%U %s arc %s", unformat_vnet_sw_interface, vnm,
584  &sw_if_index, &feature_name, &arc_name))
585  ;
586  else if (unformat (line_input, "disable"))
587  enable = 0;
588  else
589  {
590  error = unformat_parse_error (line_input);
591  goto done;
592  }
593  }
594  if (!feature_name || !arc_name)
595  {
596  error = clib_error_return (0, "Both feature name and arc required...");
597  goto done;
598  }
599 
600  if (sw_if_index == ~0)
601  {
602  error = clib_error_return (0, "Interface not specified...");
603  goto done;
604  }
605 
606  vec_add1 (arc_name, 0);
607  vec_add1 (feature_name, 0);
608 
609  u8 arc_index;
610 
611  arc_index = vnet_get_feature_arc_index ((const char *) arc_name);
612 
613  if (arc_index == (u8) ~ 0)
614  {
615  error =
616  clib_error_return (0, "Unknown arc name (%s)... ",
617  (const char *) arc_name);
618  goto done;
619  }
620 
622  reg =
623  vnet_get_feature_reg ((const char *) arc_name,
624  (const char *) feature_name);
625  if (reg == 0)
626  {
627  error =
629  "Feature (%s) not registered to arc (%s)... See 'show features verbose' for valid feature/arc combinations. ",
630  feature_name, arc_name);
631  goto done;
632  }
633  if (reg->enable_disable_cb)
634  error = reg->enable_disable_cb (sw_if_index, enable);
635  if (!error)
636  vnet_feature_enable_disable ((const char *) arc_name,
637  (const char *) feature_name, sw_if_index,
638  enable, 0, 0);
639 
640 done:
641  vec_free (feature_name);
642  vec_free (arc_name);
643  unformat_free (line_input);
644  return error;
645 }
646 
647 /*?
648  * Set feature for given interface
649  *
650  * @cliexpar
651  * Example:
652  * @cliexcmd{set interface feature GigabitEthernet2/0/0 ip4_flow_classify arc ip4_unicast}
653  * @cliexend
654  * @endparblock
655 ?*/
656 /* *INDENT-OFF* */
657 VLIB_CLI_COMMAND (set_interface_feature_command, static) = {
658  .path = "set interface feature",
659  .short_help = "set interface feature <intfc> <feature_name> arc <arc_name> "
660  "[disable]",
662 };
663 /* *INDENT-ON* */
664 
665 /*
666  * fd.io coding-style-patch-verification: ON
667  *
668  * Local Variables:
669  * eval: (c-set-style "gnu")
670  * End:
671  */
vnet_config_main_t config_main
Definition: feature.h:82
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
void vnet_feature_register(vnet_feature_update_cb_t cb, void *data)
Definition: feature.c:29
vnet_feature_update_cb_t cb
Definition: feature.c:22
static void vent_feature_reg_invoke(u32 sw_if_index, u8 arc_index, u8 is_enable)
Definition: feature.c:40
vnet_config_feature_t * features
Definition: config.h:71
struct _vnet_feature_constraint_registration vnet_feature_constraint_registration_t
constraint registration object
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:197
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
char *** feature_nodes
Save partial order results for show command.
Definition: feature.h:103
vnet_feature_registration_t * next_feature
feature path configuration lists
Definition: feature.h:93
u32 vnet_config_del_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
Definition: config.c:368
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
#define heap_elt_at_index(v, index)
Definition: heap.h:296
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:630
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
#define hash_set_mem(h, key, value)
Definition: hash.h:275
vlib_main_t * vm
Definition: in2out_ed.c:1582
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define fm
clib_error_t * vnet_feature_arc_init(vlib_main_t *vm, vnet_config_main_t *vcm, char **feature_start_nodes, int num_feature_start_nodes, char *last_in_arc, vnet_feature_registration_t *first_reg, vnet_feature_constraint_registration_t *first_const_set, char ***in_feature_nodes)
Initialize a feature graph arc.
Definition: registration.c:121
u32 vnet_config_modify_end_node(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 end_node_index)
Definition: config.c:245
vnet_feature_constraint_registration_t * next_constraint
Definition: feature.h:95
static vnet_feature_upd_registration_t * regs
Definition: feature.c:26
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vnet_feature_registration_t * vnet_get_feature_reg(const char *arc_name, const char *node_name)
Definition: feature.c:212
int vnet_feature_enable_disable_with_index(u8 arc_index, u32 feature_index, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:251
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
u32 vnet_get_feature_index(u8 arc, const char *s)
Definition: feature.c:233
static clib_error_t * vnet_feature_init(vlib_main_t *vm)
Definition: feature.c:50
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
unformat_function_t unformat_line_input
Definition: format.h:283
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static clib_error_t * set_interface_features_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: feature.c:563
u32 vnet_feature_modify_end_node(u8 arc_index, u32 sw_if_index, u32 end_node_index)
Definition: feature.c:380
int vnet_feature_is_enabled(const char *arc_name, const char *feature_node_name, u32 sw_if_index)
Definition: feature.c:324
void(* vnet_feature_update_cb_t)(u32 sw_if_index, u8 arc_index, u8 is_enable, void *cb)
Definition: feature.h:485
uword ** next_feature_by_name
Definition: feature.h:97
u8 * name
Definition: node.h:263
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
u32 * config_pool_index_by_user_index
Definition: config.h:105
static int feature_cmp(void *a1, void *a2)
Definition: feature.c:407
void vnet_interface_features_show(vlib_main_t *vm, u32 sw_if_index, int verbose)
Display the set of driver features configured on a specific interface Called by "show interface" hand...
Definition: feature.c:491
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u32 * config_string_heap
Definition: config.h:95
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define clib_warning(format, args...)
Definition: error.h:59
void os_exit(int code)
Definition: unix-misc.c:183
vnet_feature_constraint_registration_t ** next_constraint_by_arc
Definition: feature.h:96
uword ** arc_index_by_name
Definition: feature.h:90
i16 ** feature_count_by_sw_if_index
feature reference counts by interface
Definition: feature.h:109
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
struct vnet_feature_upd_registration_t_ vnet_feature_upd_registration_t
vnet_feature_registration_t ** next_feature_by_arc
Definition: feature.h:94
#define clib_error_report(e)
Definition: error.h:113
u32 vnet_config_add_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
Definition: config.c:299
static uword pointer_to_uword(const void *p)
Definition: types.h:131
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
#define vec_elt(v, i)
Get vector value at index i.
#define unformat_parse_error(input)
Definition: format.h:269
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
struct _vnet_feature_arc_registration vnet_feature_arc_registration_t
feature registration object
#define hash_get_mem(h, key)
Definition: hash.h:269
vnet_feature_arc_registration_t * next_arc
feature arc configuration list
Definition: feature.h:89
uword ** sw_if_index_has_features
bitmap of interfaces which have driver rx features configured
Definition: feature.h:106
vnet_config_t * config_pool
Definition: config.h:89
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:85
#define vec_foreach(var, vec)
Vector iterator.
static clib_error_t * show_features_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Display the set of available driver features.
Definition: feature.c:420
u32 * end_node_indices_by_user_index
Definition: config.h:98
vnet_feature_config_main_t * feature_config_mains
feature config main objects
Definition: feature.h:100
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:556
vnet_feature_main_t feature_main
Definition: feature.c:18
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:303
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
struct _vnet_feature_registration vnet_feature_registration_t
feature registration object
signed short i16
Definition: types.h:46