FD.io VPP  v20.09-64-g4f7b92f0a
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 vnet_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  vnet_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 (!vnet_have_features (feature_arc, sw_if_index))
519  {
520  vlib_cli_output (vm, " none configured");
521  continue;
522  }
523 
524  current_config_index =
525  vec_elt (cm[feature_arc].config_index_by_sw_if_index, sw_if_index);
526  cfg_index =
527  vec_elt (vcm->config_pool_index_by_user_index, current_config_index);
528  cfg = pool_elt_at_index (vcm->config_pool, cfg_index);
529 
530  for (i = 0; i < vec_len (cfg->features); i++)
531  {
532  feat = cfg->features + i;
533  node_index = feat->node_index;
534  n = vlib_get_node (vm, node_index);
535  if (verbose)
536  vlib_cli_output (vm, " [%2d] %v", feat->feature_index, n->name);
537  else
538  vlib_cli_output (vm, " %v", n->name);
539  }
540  if (verbose)
541  {
542  n =
543  vlib_get_node (vm,
545  [current_config_index]);
546  vlib_cli_output (vm, " [end] %v", n->name);
547  }
548  }
549 }
550 
551 static clib_error_t *
553  unformat_input_t * input,
554  vlib_cli_command_t * cmd)
555 {
556  vnet_main_t *vnm = vnet_get_main ();
557  unformat_input_t _line_input, *line_input = &_line_input;
558  clib_error_t *error = 0;
559 
560  u8 *arc_name = 0;
561  u8 *feature_name = 0;
562  u32 sw_if_index = ~0;
563  u8 enable = 1;
564 
565  /* Get a line of input. */
566  if (!unformat_user (input, unformat_line_input, line_input))
567  return 0;
568 
569  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
570  {
571  if (unformat
572  (line_input, "%U %s arc %s", unformat_vnet_sw_interface, vnm,
573  &sw_if_index, &feature_name, &arc_name))
574  ;
575  else if (unformat (line_input, "disable"))
576  enable = 0;
577  else
578  {
579  error = unformat_parse_error (line_input);
580  goto done;
581  }
582  }
583  if (!feature_name || !arc_name)
584  {
585  error = clib_error_return (0, "Both feature name and arc required...");
586  goto done;
587  }
588 
589  if (sw_if_index == ~0)
590  {
591  error = clib_error_return (0, "Interface not specified...");
592  goto done;
593  }
594 
595  vec_add1 (arc_name, 0);
596  vec_add1 (feature_name, 0);
597 
598  u8 arc_index;
599 
600  arc_index = vnet_get_feature_arc_index ((const char *) arc_name);
601 
602  if (arc_index == (u8) ~ 0)
603  {
604  error =
605  clib_error_return (0, "Unknown arc name (%s)... ",
606  (const char *) arc_name);
607  goto done;
608  }
609 
611  reg =
612  vnet_get_feature_reg ((const char *) arc_name,
613  (const char *) feature_name);
614  if (reg == 0)
615  {
616  error =
618  "Feature (%s) not registered to arc (%s)... See 'show features verbose' for valid feature/arc combinations. ",
619  feature_name, arc_name);
620  goto done;
621  }
622  if (reg->enable_disable_cb)
623  error = reg->enable_disable_cb (sw_if_index, enable);
624  if (!error)
625  vnet_feature_enable_disable ((const char *) arc_name,
626  (const char *) feature_name, sw_if_index,
627  enable, 0, 0);
628 
629 done:
630  vec_free (feature_name);
631  vec_free (arc_name);
632  unformat_free (line_input);
633  return error;
634 }
635 
636 /*?
637  * Set feature for given interface
638  *
639  * @cliexpar
640  * Example:
641  * @cliexcmd{set interface feature GigabitEthernet2/0/0 ip4_flow_classify arc ip4_unicast}
642  * @cliexend
643  * @endparblock
644 ?*/
645 /* *INDENT-OFF* */
646 VLIB_CLI_COMMAND (set_interface_feature_command, static) = {
647  .path = "set interface feature",
648  .short_help = "set interface feature <intfc> <feature_name> arc <arc_name> "
649  "[disable]",
651 };
652 /* *INDENT-ON* */
653 
654 static clib_error_t *
656  u32 is_add)
657 {
660 
661  if (is_add)
662  return 0;
663 
664  /*
665  * remove all enabled features from an interface on deletion
666  */
667  for (far = fm->next_arc; far != 0; far = far->next)
668  {
669  const u8 arc_index = far->feature_arc_index;
671  vec_elt_at_index (fm->feature_config_mains, arc_index);
672  const u32 ci =
674  sw_if_index ? ~0 : vec_elt (cm->config_index_by_sw_if_index,
675  sw_if_index);
676 
677  if (~0 == ci)
678  continue;
679 
680  fm->sw_if_index_has_features[arc_index] =
681  clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index,
682  0);
683 
684  vnet_feature_reg_invoke (sw_if_index, arc_index, 0);
685 
686  if (vec_len (fm->feature_count_by_sw_if_index[arc_index]) > sw_if_index)
687  vec_elt (fm->feature_count_by_sw_if_index[arc_index], sw_if_index) =
688  0;
689 
690  vec_elt (cm->config_index_by_sw_if_index, sw_if_index) = ~0;
691  vnet_config_del (&cm->config_main, ci);
692  }
693 
694  return 0;
695 }
696 
699 
700 /*
701  * fd.io coding-style-patch-verification: ON
702  *
703  * Local Variables:
704  * eval: (c-set-style "gnu")
705  * End:
706  */
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
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:376
#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
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:251
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:253
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
VNET_SW_INTERFACE_ADD_DEL_FUNCTION_PRIO(vnet_feature_add_del_sw_interface, VNET_ITF_FUNC_PRIORITY_HIGH)
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 vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#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
static clib_error_t * vnet_feature_add_del_sw_interface(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: feature.c:655
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:552
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
static void vnet_feature_reg_invoke(u32 sw_if_index, u8 arc_index, u8 is_enable)
Definition: feature.c:40
#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:307
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
void vnet_config_del(vnet_config_main_t *cm, u32 config_id)
Definition: config.c:245
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