FD.io VPP  v19.04.4-rc0-5-ge88582fac
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 
132 
133 #ifndef CLIB_MARCH_VARIANT
135 #endif /* CLIB_MARCH_VARIANT */
136 
137 #define get_u16(addr) ( *((u16 *)(addr)) )
138 #define L2_FEAT_ARC_VEC_SIZE 2
139 
141 buffer_prefetch_xN (int vector_sz, vlib_buffer_t ** b)
142 {
143  int ii;
144  for (ii = 0; ii < vector_sz; ii++)
145  CLIB_PREFETCH (b[ii], CLIB_CACHE_LINE_BYTES, STORE);
146 }
147 
149 get_sw_if_index_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
150  u32 * out_sw_if_index)
151 {
152  int ii;
153  for (ii = 0; ii < vector_sz; ii++)
154  if (is_output)
155  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_TX];
156  else
157  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_RX];
158 }
159 
161 get_ethertype_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
162  u16 * out_ethertype)
163 {
164  int ii;
165  for (ii = 0; ii < vector_sz; ii++)
166  {
168  u8 *l3h0 = (u8 *) h0 + vnet_buffer (b[ii])->l2.l2_len;
169  out_ethertype[ii] = clib_net_to_host_u16 (get_u16 (l3h0 - 2));
170  }
171 }
172 
173 
175 set_next_in_arc_head_xN (int vector_sz, int is_output, u32 * next_nodes,
176  vlib_buffer_t ** b, u32 * sw_if_index,
177  u16 * ethertype, u8 ip4_arc, u8 ip6_arc,
178  u8 nonip_arc, u16 * out_next)
179 {
180  int ii;
181  for (ii = 0; ii < vector_sz; ii++)
182  {
183  u32 next_index = 0;
184  u8 feature_arc;
185  switch (ethertype[ii])
186  {
187  case ETHERNET_TYPE_IP4:
188  feature_arc = ip4_arc;
189  break;
190  case ETHERNET_TYPE_IP6:
191  feature_arc = ip6_arc;
192  break;
193  default:
194  feature_arc = nonip_arc;
195  }
196  if (PREDICT_TRUE (vnet_have_features (feature_arc, sw_if_index[ii])))
197  vnet_feature_arc_start (feature_arc,
198  sw_if_index[ii], &next_index, b[ii]);
199  else
200  next_index =
201  vnet_l2_feature_next (b[ii], next_nodes,
202  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
203  L2INPUT_FEAT_INPUT_FEAT_ARC);
204 
205  out_next[ii] = next_index;
206  }
207 }
208 
210 set_next_in_arc_tail_xN (int vector_sz, int is_output, u32 * next_nodes,
211  vlib_buffer_t ** b, u16 * out_next)
212 {
213  int ii;
214  for (ii = 0; ii < vector_sz; ii++)
215  {
216  out_next[ii] =
217  vnet_l2_feature_next (b[ii], next_nodes,
218  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
219  L2INPUT_FEAT_INPUT_FEAT_ARC);
220  }
221 
222 }
223 
224 
226 maybe_trace_xN (int vector_sz, int arc_head, vlib_main_t * vm,
227  vlib_node_runtime_t * node, vlib_buffer_t ** b,
228  u32 * sw_if_index, u16 * ethertype, u16 * next)
229 {
230  int ii;
231  for (ii = 0; ii < vector_sz; ii++)
232  if (PREDICT_FALSE (b[ii]->flags & VLIB_BUFFER_IS_TRACED))
233  {
235  vlib_add_trace (vm, node, b[ii], sizeof (*t));
236  t->arc_head = arc_head;
237  t->sw_if_index = arc_head ? sw_if_index[ii] : ~0;
238  t->feature_bitmap = vnet_buffer (b[ii])->l2.feature_bitmap;
239  t->ethertype = arc_head ? ethertype[ii] : 0;
240  t->next_index = next[ii];
241  }
242 }
243 
246  vlib_node_runtime_t * node, vlib_frame_t * frame,
247  int is_output, vlib_node_registration_t * fa_node,
248  int arc_head, int do_trace)
249 {
250  u32 n_left, *from;
251  u16 nexts[VLIB_FRAME_SIZE], *next;
252  u16 ethertypes[VLIB_FRAME_SIZE], *ethertype;
253  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
254  u32 sw_if_indices[VLIB_FRAME_SIZE], *sw_if_index;
256 
257  u8 ip4_arc_index = fam->ip4_feat_arc_index[is_output];
258  u8 ip6_arc_index = fam->ip6_feat_arc_index[is_output];
259  u8 nonip_arc_index = fam->nonip_feat_arc_index[is_output];
260  u32 *next_node_indices = fam->feat_next_node_index[is_output];
261 
262  from = vlib_frame_vector_args (frame);
263  vlib_get_buffers (vm, from, bufs, frame->n_vectors);
264  /* set the initial values for the current buffer the next pointers */
265  b = bufs;
266  next = nexts;
267  ethertype = ethertypes;
268  sw_if_index = sw_if_indices;
269  n_left = frame->n_vectors;
270 
271  CLIB_PREFETCH (next_node_indices, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
272 
273  while (n_left > 3 * L2_FEAT_ARC_VEC_SIZE)
274  {
275  const int vec_sz = L2_FEAT_ARC_VEC_SIZE;
276  /* prefetch next N buffers */
277  buffer_prefetch_xN (vec_sz, b + 2 * vec_sz);
278 
279  if (arc_head)
280  {
281  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
282  get_ethertype_xN (vec_sz, is_output, b, ethertype);
283  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
284  sw_if_index, ethertype, ip4_arc_index,
285  ip6_arc_index, nonip_arc_index, next);
286  }
287  else
288  {
289  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
290  next);
291  }
292  if (do_trace)
293  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
294  next);
295 
296  next += vec_sz;
297  b += vec_sz;
298  sw_if_index += vec_sz;
299  ethertype += vec_sz;
300 
301  n_left -= vec_sz;
302  }
303 
304  while (n_left > 0)
305  {
306  const int vec_sz = 1;
307 
308  if (arc_head)
309  {
310  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
311  get_ethertype_xN (vec_sz, is_output, b, ethertype);
312  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
313  sw_if_index, ethertype, ip4_arc_index,
314  ip6_arc_index, nonip_arc_index, next);
315  }
316  else
317  {
318  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
319  next);
320  }
321  if (do_trace)
322  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
323  next);
324 
325  next += vec_sz;
326  b += vec_sz;
327  sw_if_index += vec_sz;
328  ethertype += vec_sz;
329 
330  n_left -= vec_sz;
331  }
332 
333  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
334 
335  return frame->n_vectors;
336 }
337 
338 VLIB_NODE_FN (l2_in_feat_arc_node) (vlib_main_t * vm,
339  vlib_node_runtime_t * node,
340  vlib_frame_t * frame)
341 {
342  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
343  return l2_in_out_feat_arc_node_fn (vm, node, frame,
345  &l2_in_feat_arc_node, 1, 1);
346  else
347  return l2_in_out_feat_arc_node_fn (vm, node, frame,
349  &l2_in_feat_arc_node, 1, 0);
350 }
351 
352 VLIB_NODE_FN (l2_out_feat_arc_node) (vlib_main_t * vm,
353  vlib_node_runtime_t * node,
354  vlib_frame_t * frame)
355 {
356  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
357  return l2_in_out_feat_arc_node_fn (vm, node, frame,
359  &l2_out_feat_arc_node, 1, 1);
360  else
361  return l2_in_out_feat_arc_node_fn (vm, node, frame,
363  &l2_out_feat_arc_node, 1, 0);
364 }
365 
366 VLIB_NODE_FN (l2_in_feat_arc_end_node) (vlib_main_t * vm,
367  vlib_node_runtime_t * node,
368  vlib_frame_t * frame)
369 {
370  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
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 
380 VLIB_NODE_FN (l2_out_feat_arc_end_node) (vlib_main_t * vm,
381  vlib_node_runtime_t * node,
382  vlib_frame_t * frame)
383 {
384  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
385  return l2_in_out_feat_arc_node_fn (vm, node, frame,
387  &l2_out_feat_arc_end_node, 0, 1);
388  else
389  return l2_in_out_feat_arc_node_fn (vm, node, frame,
391  &l2_out_feat_arc_end_node, 0, 0);
392 }
393 
394 
395 #ifndef CLIB_MARCH_VARIANT
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 #endif /* CLIB_MARCH_VARIANT */
408 
409 /* *INDENT-OFF* */
410 VNET_FEATURE_ARC_INIT (l2_in_ip4_arc, static) =
411 {
412  .arc_name = "l2-input-ip4",
413  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
414  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
415 };
416 
417 VNET_FEATURE_ARC_INIT (l2_out_ip4_arc, static) =
418 {
419  .arc_name = "l2-output-ip4",
420  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
421  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
422 };
423 
424 VNET_FEATURE_ARC_INIT (l2_out_ip6_arc, static) =
425 {
426  .arc_name = "l2-input-ip6",
427  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
428  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
429 };
430 VNET_FEATURE_ARC_INIT (l2_in_ip6_arc, static) =
431 {
432  .arc_name = "l2-output-ip6",
433  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
434  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
435 };
436 
437 VNET_FEATURE_ARC_INIT (l2_out_nonip_arc, static) =
438 {
439  .arc_name = "l2-input-nonip",
440  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
441  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
442 };
443 VNET_FEATURE_ARC_INIT (l2_in_nonip_arc, static) =
444 {
445  .arc_name = "l2-output-nonip",
446  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
447  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
448 };
449 
450 
451 /* *INDENT-ON* */
452 
453 
454 /* *INDENT-OFF* */
455 VLIB_REGISTER_NODE (l2_in_feat_arc_node) = {
456  .name = "l2-input-feat-arc",
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) = {
467  .name = "l2-output-feat-arc",
468  .vector_size = sizeof (u32),
469  .format_trace = format_l2_out_feat_arc_trace,
470  .type = VLIB_NODE_TYPE_INTERNAL,
471 
472  .n_errors = ARRAY_LEN(l2_out_feat_arc_error_strings),
473  .error_strings = l2_out_feat_arc_error_strings,
474 
475 };
476 
477 VLIB_REGISTER_NODE (l2_in_feat_arc_end_node) = {
478  .name = "l2-input-feat-arc-end",
479  .vector_size = sizeof (u32),
480  .format_trace = format_l2_in_feat_arc_trace,
481  .sibling_of = "l2-input-feat-arc",
482 };
483 
484 VLIB_REGISTER_NODE (l2_out_feat_arc_end_node) = {
485  .name = "l2-output-feat-arc-end",
486  .vector_size = sizeof (u32),
487  .format_trace = format_l2_out_feat_arc_trace,
488  .sibling_of = "l2-output-feat-arc",
489 };
490 
491 VNET_FEATURE_INIT (l2_in_ip4_arc_end, static) =
492 {
493  .arc_name = "l2-input-ip4",
494  .node_name = "l2-input-feat-arc-end",
495  .runs_before = 0, /* not before any other features */
496 };
497 
498 VNET_FEATURE_INIT (l2_out_ip4_arc_end, static) =
499 {
500  .arc_name = "l2-output-ip4",
501  .node_name = "l2-output-feat-arc-end",
502  .runs_before = 0, /* not before any other features */
503 };
504 
505 VNET_FEATURE_INIT (l2_in_ip6_arc_end, static) =
506 {
507  .arc_name = "l2-input-ip6",
508  .node_name = "l2-input-feat-arc-end",
509  .runs_before = 0, /* not before any other features */
510 };
511 
512 
513 VNET_FEATURE_INIT (l2_out_ip6_arc_end, static) =
514 {
515  .arc_name = "l2-output-ip6",
516  .node_name = "l2-output-feat-arc-end",
517  .runs_before = 0, /* not before any other features */
518 };
519 
520 VNET_FEATURE_INIT (l2_in_nonip_arc_end, static) =
521 {
522  .arc_name = "l2-input-nonip",
523  .node_name = "l2-input-feat-arc-end",
524  .runs_before = 0, /* not before any other features */
525 };
526 
527 
528 VNET_FEATURE_INIT (l2_out_nonip_arc_end, static) =
529 {
530  .arc_name = "l2-output-nonip",
531  .node_name = "l2-output-feat-arc-end",
532  .runs_before = 0, /* not before any other features */
533 };
534 /* *INDENT-ON* */
535 
536 
537 #ifndef CLIB_MARCH_VARIANT
538 clib_error_t *
540 {
542 
543  mp->vlib_main = vm;
544  mp->vnet_main = vnet_get_main ();
545 
546  /* Initialize the feature next-node indexes */
548  l2_in_feat_arc_end_node.index,
553  feat_bitmap_init_next_nodes (vm, l2_out_feat_arc_end_node.index,
557  return 0;
558 }
559 
560 
561 static int
563 {
564  int has_features = 0;
566  has_features +=
567  vnet_have_features (mp->ip4_feat_arc_index[is_output], sw_if_index);
568  has_features +=
569  vnet_have_features (mp->ip6_feat_arc_index[is_output], sw_if_index);
570  has_features +=
571  vnet_have_features (mp->nonip_feat_arc_index[is_output], sw_if_index);
572  return has_features > 0;
573 }
574 
575 static int
576 l2_is_output_arc (u8 arc_index)
577 {
580  return (mp->ip4_feat_arc_index[idx] == arc_index
581  || mp->ip6_feat_arc_index[idx] == arc_index
582  || mp->nonip_feat_arc_index[idx] == arc_index);
583 }
584 
585 static int
586 l2_is_input_arc (u8 arc_index)
587 {
590  return (mp->ip4_feat_arc_index[idx] == arc_index
591  || mp->ip6_feat_arc_index[idx] == arc_index
592  || mp->nonip_feat_arc_index[idx] == arc_index);
593 }
594 
595 int
596 vnet_l2_feature_enable_disable (const char *arc_name, const char *node_name,
597  u32 sw_if_index, int enable_disable,
598  void *feature_config,
599  u32 n_feature_config_bytes)
600 {
601  u8 arc_index = vnet_get_feature_arc_index (arc_name);
602  if (arc_index == (u8) ~ 0)
603  return VNET_API_ERROR_INVALID_VALUE;
604 
605  /* check the state before we tried to enable/disable */
606  int had_features = vnet_have_features (arc_index, sw_if_index);
607 
608  int ret = vnet_feature_enable_disable (arc_name, node_name, sw_if_index,
609  enable_disable, feature_config,
610  n_feature_config_bytes);
611  if (ret)
612  return ret;
613 
614  int has_features = vnet_have_features (arc_index, sw_if_index);
615 
616  if (had_features != has_features)
617  {
618  if (l2_is_output_arc (arc_index))
619  {
622  (sw_if_index, 1));
623  }
624  if (l2_is_input_arc (arc_index))
625  {
628  (sw_if_index, 0));
629  }
630  }
631  return 0;
632 }
633 
634 
636 #endif /* CLIB_MARCH_VARIANT */
637 
638 /*
639  * fd.io coding-style-patch-verification: ON
640  *
641  * Local Variables:
642  * eval: (c-set-style "gnu")
643  * End:
644  */
VNET_FEATURE_ARC_INIT(l2_in_ip4_arc, static)
u32 sw_if_index
Definition: ipsec_gre.api:37
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:424
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:241
#define VLIB_NODE_FN(node)
Definition: node.h:201
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
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
#define foreach_l2_out_feat_arc_error
#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:376
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:229
#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:395
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
vlib_main_t * vm
Definition: buffer.c:312
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:62
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:536
u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
#define VNET_FEATURES(...)
Definition: feature.h:435
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)
VLIB buffer representation.
Definition: buffer.h:102
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:244
#define vnet_buffer(b)
Definition: buffer.h:369
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:244
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:301
#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