FD.io VPP  v19.01.2-3-gf61a1a8
Vector Packet Processing
l2_in_out_feat_arc.c
Go to the documentation of this file.
1 /*
2  * l2_in_out_feat_arc.c : layer 2 input/output acl processing
3  *
4  * Copyright (c) 2013,2018 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20 #include <vnet/pg/pg.h>
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/ethernet/packet.h>
23 #include <vnet/ip/ip_packet.h>
24 #include <vnet/ip/ip4_packet.h>
25 #include <vnet/ip/ip6_packet.h>
26 #include <vlib/cli.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2/l2_output.h>
29 #include <vnet/l2/feat_bitmap.h>
31 
32 #include <vppinfra/error.h>
33 #include <vppinfra/hash.h>
34 #include <vppinfra/cache.h>
35 
36 
37 typedef struct
38 {
39 
40  /* Next nodes for each feature */
41  u32 feat_next_node_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS][32];
42  u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
43  u8 ip6_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
44  u8 nonip_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
46 
47  /* convenience variables */
50 } l2_in_out_feat_arc_main_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
51 
52 typedef struct
53 {
60 
61 /* packet trace format function */
62 static u8 *
63 format_l2_in_out_feat_arc_trace (u8 * s, u32 is_output, va_list * args)
64 {
65  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
66  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
68  va_arg (*args, l2_in_out_feat_arc_trace_t *);
69 
70  s =
71  format (s,
72  "%s: head %d feature_bitmap %x ethertype %x sw_if_index %d, next_index %d",
73  is_output ? "OUT-FEAT-ARC" : "IN-FEAT-ARC", t->arc_head,
75  return s;
76 }
77 
78 static u8 *
79 format_l2_in_feat_arc_trace (u8 * s, va_list * args)
80 {
83  args);
84 }
85 
86 static u8 *
87 format_l2_out_feat_arc_trace (u8 * s, va_list * args)
88 {
91  args);
92 }
93 
94 
95 #define foreach_l2_in_feat_arc_error \
96 _(DEFAULT, "in default") \
97 
98 
99 #define foreach_l2_out_feat_arc_error \
100 _(DEFAULT, "out default") \
101 
102 
103 typedef enum
104 {
105 #define _(sym,str) L2_IN_FEAT_ARC_ERROR_##sym,
107 #undef _
110 
111 static char *l2_in_feat_arc_error_strings[] = {
112 #define _(sym,string) string,
114 #undef _
115 };
116 
117 typedef enum
118 {
119 #define _(sym,str) L2_OUT_FEAT_ARC_ERROR_##sym,
121 #undef _
124 
125 static char *l2_out_feat_arc_error_strings[] = {
126 #define _(sym,string) string,
128 #undef _
129 };
130 
131 
133 
134 #define get_u16(addr) ( *((u16 *)(addr)) )
135 #define L2_FEAT_ARC_VEC_SIZE 2
136 
138 buffer_prefetch_xN (int vector_sz, vlib_buffer_t ** b)
139 {
140  int ii;
141  for (ii = 0; ii < vector_sz; ii++)
142  CLIB_PREFETCH (b[ii], CLIB_CACHE_LINE_BYTES, STORE);
143 }
144 
146 get_sw_if_index_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
147  u32 * out_sw_if_index)
148 {
149  int ii;
150  for (ii = 0; ii < vector_sz; ii++)
151  if (is_output)
152  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_TX];
153  else
154  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_RX];
155 }
156 
158 get_ethertype_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
159  u16 * out_ethertype)
160 {
161  int ii;
162  for (ii = 0; ii < vector_sz; ii++)
163  {
165  u8 *l3h0 = (u8 *) h0 + vnet_buffer (b[ii])->l2.l2_len;
166  out_ethertype[ii] = clib_net_to_host_u16 (get_u16 (l3h0 - 2));
167  }
168 }
169 
170 
172 set_next_in_arc_head_xN (int vector_sz, int is_output, u32 * next_nodes,
173  vlib_buffer_t ** b, u32 * sw_if_index,
174  u16 * ethertype, u8 ip4_arc, u8 ip6_arc,
175  u8 nonip_arc, u16 * out_next)
176 {
177  int ii;
178  for (ii = 0; ii < vector_sz; ii++)
179  {
180  u32 next_index = 0;
181  u8 feature_arc;
182  switch (ethertype[ii])
183  {
184  case ETHERNET_TYPE_IP4:
185  feature_arc = ip4_arc;
186  break;
187  case ETHERNET_TYPE_IP6:
188  feature_arc = ip6_arc;
189  break;
190  default:
191  feature_arc = nonip_arc;
192  }
193  if (PREDICT_TRUE (vnet_have_features (feature_arc, sw_if_index[ii])))
194  vnet_feature_arc_start (feature_arc,
195  sw_if_index[ii], &next_index, b[ii]);
196  else
197  next_index =
198  vnet_l2_feature_next (b[ii], next_nodes,
199  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
200  L2INPUT_FEAT_INPUT_FEAT_ARC);
201 
202  out_next[ii] = next_index;
203  }
204 }
205 
207 set_next_in_arc_tail_xN (int vector_sz, int is_output, u32 * next_nodes,
208  vlib_buffer_t ** b, u16 * out_next)
209 {
210  int ii;
211  for (ii = 0; ii < vector_sz; ii++)
212  {
213  out_next[ii] =
214  vnet_l2_feature_next (b[ii], next_nodes,
215  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
216  L2INPUT_FEAT_INPUT_FEAT_ARC);
217  }
218 
219 }
220 
221 
223 maybe_trace_xN (int vector_sz, int arc_head, vlib_main_t * vm,
224  vlib_node_runtime_t * node, vlib_buffer_t ** b,
225  u32 * sw_if_index, u16 * ethertype, u16 * next)
226 {
227  int ii;
228  for (ii = 0; ii < vector_sz; ii++)
229  if (PREDICT_FALSE (b[ii]->flags & VLIB_BUFFER_IS_TRACED))
230  {
232  vlib_add_trace (vm, node, b[ii], sizeof (*t));
233  t->arc_head = arc_head;
234  t->sw_if_index = arc_head ? sw_if_index[ii] : ~0;
235  t->feature_bitmap = vnet_buffer (b[ii])->l2.feature_bitmap;
236  t->ethertype = arc_head ? ethertype[ii] : 0;
237  t->next_index = next[ii];
238  }
239 }
240 
243  vlib_node_runtime_t * node, vlib_frame_t * frame,
244  int is_output, vlib_node_registration_t * fa_node,
245  int arc_head, int do_trace)
246 {
247  u32 n_left, *from;
248  u16 nexts[VLIB_FRAME_SIZE], *next;
249  u16 ethertypes[VLIB_FRAME_SIZE], *ethertype;
250  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
251  u32 sw_if_indices[VLIB_FRAME_SIZE], *sw_if_index;
253 
254  u8 ip4_arc_index = fam->ip4_feat_arc_index[is_output];
255  u8 ip6_arc_index = fam->ip6_feat_arc_index[is_output];
256  u8 nonip_arc_index = fam->nonip_feat_arc_index[is_output];
257  u32 *next_node_indices = fam->feat_next_node_index[is_output];
258 
259  from = vlib_frame_vector_args (frame);
260  vlib_get_buffers (vm, from, bufs, frame->n_vectors);
261  /* set the initial values for the current buffer the next pointers */
262  b = bufs;
263  next = nexts;
264  ethertype = ethertypes;
265  sw_if_index = sw_if_indices;
266  n_left = frame->n_vectors;
267 
268  CLIB_PREFETCH (next_node_indices, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
269 
270  while (n_left > 3 * L2_FEAT_ARC_VEC_SIZE)
271  {
272  const int vec_sz = L2_FEAT_ARC_VEC_SIZE;
273  /* prefetch next N buffers */
274  buffer_prefetch_xN (vec_sz, b + 2 * vec_sz);
275 
276  if (arc_head)
277  {
278  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
279  get_ethertype_xN (vec_sz, is_output, b, ethertype);
280  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
281  sw_if_index, ethertype, ip4_arc_index,
282  ip6_arc_index, nonip_arc_index, next);
283  }
284  else
285  {
286  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
287  next);
288  }
289  if (do_trace)
290  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
291  next);
292 
293  next += vec_sz;
294  b += vec_sz;
295  sw_if_index += vec_sz;
296  ethertype += vec_sz;
297 
298  n_left -= vec_sz;
299  }
300 
301  while (n_left > 0)
302  {
303  const int vec_sz = 1;
304 
305  if (arc_head)
306  {
307  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
308  get_ethertype_xN (vec_sz, is_output, b, ethertype);
309  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
310  sw_if_index, ethertype, ip4_arc_index,
311  ip6_arc_index, nonip_arc_index, next);
312  }
313  else
314  {
315  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
316  next);
317  }
318  if (do_trace)
319  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
320  next);
321 
322  next += vec_sz;
323  b += vec_sz;
324  sw_if_index += vec_sz;
325  ethertype += vec_sz;
326 
327  n_left -= vec_sz;
328  }
329 
330  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
331 
332  return frame->n_vectors;
333 }
334 
336 static uword
338  vlib_node_runtime_t * node, vlib_frame_t * frame)
339 {
341  return l2_in_out_feat_arc_node_fn (vm, node, frame,
343  &l2_in_feat_arc_node, 1, 1);
344  else
345  return l2_in_out_feat_arc_node_fn (vm, node, frame,
347  &l2_in_feat_arc_node, 1, 0);
348 }
349 
351 static uword
353  vlib_node_runtime_t * node, vlib_frame_t * frame)
354 {
356  return l2_in_out_feat_arc_node_fn (vm, node, frame,
358  &l2_out_feat_arc_node, 1, 1);
359  else
360  return l2_in_out_feat_arc_node_fn (vm, node, frame,
362  &l2_out_feat_arc_node, 1, 0);
363 }
364 
366 static uword
368  vlib_node_runtime_t * node, vlib_frame_t * frame)
369 {
371  return l2_in_out_feat_arc_node_fn (vm, node, frame,
373  &l2_in_feat_arc_end_node, 0, 1);
374  else
375  return l2_in_out_feat_arc_node_fn (vm, node, frame,
377  &l2_in_feat_arc_end_node, 0, 0);
378 }
379 
381 static uword
383  vlib_node_runtime_t * node, vlib_frame_t * frame)
384 {
386  return l2_in_out_feat_arc_node_fn (vm, node, frame,
388  &l2_out_feat_arc_end_node, 0, 1);
389  else
390  return l2_in_out_feat_arc_node_fn (vm, node, frame,
392  &l2_out_feat_arc_end_node, 0, 0);
393 }
394 
395 
396 void
398  int enable_disable)
399 {
400  if (is_output)
401  l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_OUTPUT_FEAT_ARC,
402  (u32) enable_disable);
403  else
404  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_INPUT_FEAT_ARC,
405  (u32) enable_disable);
406 }
407 
408 /* *INDENT-OFF* */
409 VNET_FEATURE_ARC_INIT (l2_in_ip4_arc, static) =
410 {
411  .arc_name = "l2-input-ip4",
412  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
413  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
414 };
415 
416 VNET_FEATURE_ARC_INIT (l2_out_ip4_arc, static) =
417 {
418  .arc_name = "l2-output-ip4",
419  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
420  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
421 };
422 
423 VNET_FEATURE_ARC_INIT (l2_out_ip6_arc, static) =
424 {
425  .arc_name = "l2-input-ip6",
426  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
427  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
428 };
429 VNET_FEATURE_ARC_INIT (l2_in_ip6_arc, static) =
430 {
431  .arc_name = "l2-output-ip6",
432  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
433  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
434 };
435 
436 VNET_FEATURE_ARC_INIT (l2_out_nonip_arc, static) =
437 {
438  .arc_name = "l2-input-nonip",
439  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
440  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
441 };
442 VNET_FEATURE_ARC_INIT (l2_in_nonip_arc, static) =
443 {
444  .arc_name = "l2-output-nonip",
445  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
446  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
447 };
448 
449 
450 /* *INDENT-ON* */
451 
452 
453 /* *INDENT-OFF* */
454 VLIB_REGISTER_NODE (l2_in_feat_arc_node,static) = {
455  .name = "l2-input-feat-arc",
456  .function = l2_in_feat_arc_node_fn,
457  .vector_size = sizeof (u32),
458  .format_trace = format_l2_in_feat_arc_trace,
459  .type = VLIB_NODE_TYPE_INTERNAL,
460 
461  .n_errors = ARRAY_LEN(l2_in_feat_arc_error_strings),
462  .error_strings = l2_in_feat_arc_error_strings,
463 
464 };
465 
466 VLIB_REGISTER_NODE (l2_out_feat_arc_node,static) = {
467  .name = "l2-output-feat-arc",
468  .function = l2_out_feat_arc_node_fn,
469  .vector_size = sizeof (u32),
470  .format_trace = format_l2_out_feat_arc_trace,
471  .type = VLIB_NODE_TYPE_INTERNAL,
472 
473  .n_errors = ARRAY_LEN(l2_out_feat_arc_error_strings),
474  .error_strings = l2_out_feat_arc_error_strings,
475 
476 };
477 
478 VLIB_REGISTER_NODE (l2_in_feat_arc_end_node,static) = {
479  .name = "l2-input-feat-arc-end",
480  .function = l2_in_feat_arc_end_node_fn,
481  .vector_size = sizeof (u32),
482  .format_trace = format_l2_in_feat_arc_trace,
483  .sibling_of = "l2-input-feat-arc",
484 };
485 
486 VLIB_REGISTER_NODE (l2_out_feat_arc_end_node,static) = {
487  .name = "l2-output-feat-arc-end",
488  .function = l2_out_feat_arc_end_node_fn,
489  .vector_size = sizeof (u32),
490  .format_trace = format_l2_out_feat_arc_trace,
491  .sibling_of = "l2-output-feat-arc",
492 };
493 
494 VNET_FEATURE_INIT (l2_in_ip4_arc_end, static) =
495 {
496  .arc_name = "l2-input-ip4",
497  .node_name = "l2-input-feat-arc-end",
498  .runs_before = 0, /* not before any other features */
499 };
500 
501 VNET_FEATURE_INIT (l2_out_ip4_arc_end, static) =
502 {
503  .arc_name = "l2-output-ip4",
504  .node_name = "l2-output-feat-arc-end",
505  .runs_before = 0, /* not before any other features */
506 };
507 
508 VNET_FEATURE_INIT (l2_in_ip6_arc_end, static) =
509 {
510  .arc_name = "l2-input-ip6",
511  .node_name = "l2-input-feat-arc-end",
512  .runs_before = 0, /* not before any other features */
513 };
514 
515 
516 VNET_FEATURE_INIT (l2_out_ip6_arc_end, static) =
517 {
518  .arc_name = "l2-output-ip6",
519  .node_name = "l2-output-feat-arc-end",
520  .runs_before = 0, /* not before any other features */
521 };
522 
523 VNET_FEATURE_INIT (l2_in_nonip_arc_end, static) =
524 {
525  .arc_name = "l2-input-nonip",
526  .node_name = "l2-input-feat-arc-end",
527  .runs_before = 0, /* not before any other features */
528 };
529 
530 
531 VNET_FEATURE_INIT (l2_out_nonip_arc_end, static) =
532 {
533  .arc_name = "l2-output-nonip",
534  .node_name = "l2-output-feat-arc-end",
535  .runs_before = 0, /* not before any other features */
536 };
537 
538 
543 
544 /* *INDENT-ON* */
545 
546 
547 clib_error_t *
549 {
551 
552  mp->vlib_main = vm;
553  mp->vnet_main = vnet_get_main ();
554 
555  /* Initialize the feature next-node indexes */
557  l2_in_feat_arc_end_node.index,
562  feat_bitmap_init_next_nodes (vm, l2_out_feat_arc_end_node.index,
566  return 0;
567 }
568 
569 
570 static int
572 {
573  int has_features = 0;
575  has_features +=
576  vnet_have_features (mp->ip4_feat_arc_index[is_output], sw_if_index);
577  has_features +=
578  vnet_have_features (mp->ip6_feat_arc_index[is_output], sw_if_index);
579  has_features +=
580  vnet_have_features (mp->nonip_feat_arc_index[is_output], sw_if_index);
581  return has_features > 0;
582 }
583 
584 static int
585 l2_is_output_arc (u8 arc_index)
586 {
589  return (mp->ip4_feat_arc_index[idx] == arc_index
590  || mp->ip6_feat_arc_index[idx] == arc_index
591  || mp->nonip_feat_arc_index[idx] == arc_index);
592 }
593 
594 static int
595 l2_is_input_arc (u8 arc_index)
596 {
599  return (mp->ip4_feat_arc_index[idx] == arc_index
600  || mp->ip6_feat_arc_index[idx] == arc_index
601  || mp->nonip_feat_arc_index[idx] == arc_index);
602 }
603 
604 int
605 vnet_l2_feature_enable_disable (const char *arc_name, const char *node_name,
606  u32 sw_if_index, int enable_disable,
607  void *feature_config,
608  u32 n_feature_config_bytes)
609 {
610  u8 arc_index = vnet_get_feature_arc_index (arc_name);
611  if (arc_index == (u8) ~ 0)
612  return VNET_API_ERROR_INVALID_VALUE;
613 
614  /* check the state before we tried to enable/disable */
615  int had_features = vnet_have_features (arc_index, sw_if_index);
616 
617  int ret = vnet_feature_enable_disable (arc_name, node_name, sw_if_index,
618  enable_disable, feature_config,
619  n_feature_config_bytes);
620  if (ret)
621  return ret;
622 
623  int has_features = vnet_have_features (arc_index, sw_if_index);
624 
625  if (had_features != has_features)
626  {
627  if (l2_is_output_arc (arc_index))
628  {
631  (sw_if_index, 1));
632  }
633  if (l2_is_input_arc (arc_index))
634  {
637  (sw_if_index, 0));
638  }
639  }
640  return 0;
641 }
642 
643 
645 
646 /*
647  * fd.io coding-style-patch-verification: ON
648  *
649  * Local Variables:
650  * eval: (c-set-style "gnu")
651  * End:
652  */
static vlib_node_registration_t l2_in_feat_arc_end_node
(constructor) VLIB_REGISTER_NODE (l2_in_feat_arc_end_node)
VNET_FEATURE_ARC_INIT(l2_in_ip4_arc, static)
u32 flags
Definition: vhost_user.h:115
static u8 * format_l2_out_feat_arc_trace(u8 *s, va_list *args)
#define CLIB_UNUSED(x)
Definition: clib.h:82
char ** l2output_get_feat_names(void)
Definition: l2_output.c:39
static int l2_is_input_arc(u8 arc_index)
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:168
static int l2_has_features(u32 sw_if_index, int is_output)
u8 nonip_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define PREDICT_TRUE(x)
Definition: clib.h:112
static_always_inline void get_sw_if_index_xN(int vector_sz, int is_output, vlib_buffer_t **b, u32 *out_sw_if_index)
void vnet_l2_in_out_feat_arc_enable_disable(u32 sw_if_index, int is_output, int enable_disable)
static char * l2_in_feat_arc_error_strings[]
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:241
unsigned char u8
Definition: types.h:56
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
Definition: feat_bitmap.h:94
VNET_FEATURE_INIT(l2_in_ip4_arc_end, static)
#define static_always_inline
Definition: clib.h:99
l2_in_feat_arc_error_t
static vlib_node_registration_t l2_out_feat_arc_node
(constructor) VLIB_REGISTER_NODE (l2_out_feat_arc_node)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
#define foreach_l2_out_feat_arc_error
u32 sw_if_index
Definition: vxlan_gbp.api:37
#define always_inline
Definition: clib.h:98
static u8 * format_l2_in_feat_arc_trace(u8 *s, va_list *args)
static_always_inline void get_ethertype_xN(int vector_sz, int is_output, vlib_buffer_t **b, u16 *out_ethertype)
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:401
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
Definition: node.h:223
static_always_inline void set_next_in_arc_tail_xN(int vector_sz, int is_output, u32 *next_nodes, vlib_buffer_t **b, u16 *out_next)
unsigned short u16
Definition: types.h:57
l2_out_feat_arc_error_t
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:214
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define L2_FEAT_ARC_VEC_SIZE
void l2output_intf_bitmap_enable(u32 sw_if_index, l2output_feat_masks_t feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_output.c:626
static_always_inline void maybe_trace_xN(int vector_sz, int arc_head, vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t **b, u32 *sw_if_index, u16 *ethertype, u16 *next)
static char * l2_out_feat_arc_error_strings[]
int vnet_l2_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)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:420
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:79
vlib_main_t * vm
Definition: buffer.c:301
static vlib_node_registration_t l2_out_feat_arc_end_node
(constructor) VLIB_REGISTER_NODE (l2_out_feat_arc_end_node)
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:332
static uword l2_in_out_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_output, vlib_node_registration_t *fa_node, int arc_head, int do_trace)
static void feat_bitmap_init_next_nodes(vlib_main_t *vm, u32 node_index, u32 num_features, char **feat_names, u32 *next_nodes)
Initialize the feature next-node indexes of a graph node.
Definition: feat_bitmap.h:43
static_always_inline void buffer_prefetch_xN(int vector_sz, vlib_buffer_t **b)
#define ARRAY_LEN(x)
Definition: clib.h:62
char ** l2input_get_feat_names(void)
Return an array of strings containing graph node names of each feature.
Definition: l2_input.c:60
static uword l2_in_feat_arc_end_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 feat_next_node_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS][32]
static_always_inline void set_next_in_arc_head_xN(int vector_sz, int is_output, u32 *next_nodes, vlib_buffer_t **b, u32 *sw_if_index, u16 *ethertype, u8 ip4_arc, u8 ip6_arc, u8 nonip_arc, u16 *out_next)
#define foreach_l2_in_feat_arc_error
#define get_u16(addr)
u32 l2input_intf_bitmap_enable(u32 sw_if_index, l2input_feat_masks_t feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:530
u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
#define VNET_FEATURES(...)
Definition: feature.h:435
static uword l2_out_feat_arc_end_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:57
clib_error_t * l2_in_out_feat_arc_init(vlib_main_t *vm)
struct _vlib_node_registration vlib_node_registration_t
Definition: defs.h:47
l2_in_out_feat_arc_main_t l2_in_out_feat_arc_main
static u8 * format_l2_in_out_feat_arc_trace(u8 *s, u32 is_output, va_list *args)
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:274
static uword l2_out_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword l2_in_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define vnet_buffer(b)
Definition: buffer.h:368
static vlib_node_registration_t l2_in_feat_arc_node
(constructor) VLIB_REGISTER_NODE (l2_in_feat_arc_node)
u16 flags
Copy of main node flags.
Definition: node.h:532
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:145
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:326
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u8 ip6_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
Definition: defs.h:46
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:274
static int l2_is_output_arc(u8 arc_index)
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:275