FD.io VPP  v21.06
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/ethernet/ethernet.h>
20 #include <vnet/ip/ip_packet.h>
21 #include <vnet/l2/l2_input.h>
22 #include <vnet/l2/l2_output.h>
24 
25 #include <vppinfra/error.h>
26 #include <vppinfra/hash.h>
27 #include <vppinfra/cache.h>
28 
29 
30 typedef struct
31 {
32 
33  /* Next nodes for each feature */
34  u32 feat_next_node_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS][32];
35  u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
36  u8 ip6_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
37  u8 nonip_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS];
39 } l2_in_out_feat_arc_main_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
40 
41 typedef struct
42 {
49 
50 /* packet trace format function */
51 static u8 *
52 format_l2_in_out_feat_arc_trace (u8 * s, u32 is_output, va_list * args)
53 {
54  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
55  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
57  va_arg (*args, l2_in_out_feat_arc_trace_t *);
58 
59  s =
60  format (s,
61  "%s: head %d feature_bitmap %x ethertype %x sw_if_index %d, next_index %d",
62  is_output ? "OUT-FEAT-ARC" : "IN-FEAT-ARC", t->arc_head,
64  return s;
65 }
66 
67 static u8 *
68 format_l2_in_feat_arc_trace (u8 * s, va_list * args)
69 {
72  args);
73 }
74 
75 static u8 *
76 format_l2_out_feat_arc_trace (u8 * s, va_list * args)
77 {
80  args);
81 }
82 
83 
84 #define foreach_l2_in_feat_arc_error \
85 _(DEFAULT, "in default") \
86 
87 
88 #define foreach_l2_out_feat_arc_error \
89 _(DEFAULT, "out default") \
90 
91 
92 typedef enum
93 {
94 #define _(sym,str) L2_IN_FEAT_ARC_ERROR_##sym,
96 #undef _
99 
100 static char *l2_in_feat_arc_error_strings[] = {
101 #define _(sym,string) string,
103 #undef _
104 };
105 
106 typedef enum
107 {
108 #define _(sym,str) L2_OUT_FEAT_ARC_ERROR_##sym,
110 #undef _
113 
114 static char *l2_out_feat_arc_error_strings[] = {
115 #define _(sym,string) string,
117 #undef _
118 };
119 
121 
122 #ifndef CLIB_MARCH_VARIANT
124 #endif /* CLIB_MARCH_VARIANT */
125 
126 #define get_u16(addr) ( *((u16 *)(addr)) )
127 #define L2_FEAT_ARC_VEC_SIZE 2
128 
130 buffer_prefetch_xN (int vector_sz, vlib_buffer_t ** b)
131 {
132  int ii;
133  for (ii = 0; ii < vector_sz; ii++)
134  CLIB_PREFETCH (b[ii], CLIB_CACHE_LINE_BYTES, STORE);
135 }
136 
138 get_sw_if_index_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
139  u32 * out_sw_if_index)
140 {
141  int ii;
142  for (ii = 0; ii < vector_sz; ii++)
143  if (is_output)
144  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_TX];
145  else
146  out_sw_if_index[ii] = vnet_buffer (b[ii])->sw_if_index[VLIB_RX];
147 }
148 
150 get_ethertype_xN (int vector_sz, int is_output, vlib_buffer_t ** b,
151  u16 * out_ethertype)
152 {
153  int ii;
154  for (ii = 0; ii < vector_sz; ii++)
155  {
157  u8 *l3h0 = (u8 *) h0 + vnet_buffer (b[ii])->l2.l2_len;
158  out_ethertype[ii] = clib_net_to_host_u16 (get_u16 (l3h0 - 2));
159  }
160 }
161 
162 
164 set_next_in_arc_head_xN (int vector_sz, int is_output, u32 * next_nodes,
166  u16 * ethertype, u8 ip4_arc, u8 ip6_arc,
167  u8 nonip_arc, u16 * out_next)
168 {
169  int ii;
170  for (ii = 0; ii < vector_sz; ii++)
171  {
172  u32 next_index = 0;
173  u8 feature_arc;
174  switch (ethertype[ii])
175  {
176  case ETHERNET_TYPE_IP4:
177  feature_arc = ip4_arc;
178  break;
179  case ETHERNET_TYPE_IP6:
180  feature_arc = ip6_arc;
181  break;
182  default:
183  feature_arc = nonip_arc;
184  }
185  if (PREDICT_TRUE (vnet_have_features (feature_arc, sw_if_index[ii])))
186  vnet_feature_arc_start (feature_arc,
187  sw_if_index[ii], &next_index, b[ii]);
188  else
189  next_index =
190  vnet_l2_feature_next (b[ii], next_nodes,
191  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
192  L2INPUT_FEAT_INPUT_FEAT_ARC);
193 
194  out_next[ii] = next_index;
195  }
196 }
197 
199 set_next_in_arc_tail_xN (int vector_sz, int is_output, u32 * next_nodes,
200  vlib_buffer_t ** b, u16 * out_next)
201 {
202  int ii;
203  for (ii = 0; ii < vector_sz; ii++)
204  {
205  out_next[ii] =
206  vnet_l2_feature_next (b[ii], next_nodes,
207  is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
208  L2INPUT_FEAT_INPUT_FEAT_ARC);
209  }
210 
211 }
212 
213 
215 maybe_trace_xN (int vector_sz, int arc_head, vlib_main_t * vm,
217  u32 * sw_if_index, u16 * ethertype, u16 * next)
218 {
219  int ii;
220  for (ii = 0; ii < vector_sz; ii++)
221  if (PREDICT_FALSE (b[ii]->flags & VLIB_BUFFER_IS_TRACED))
222  {
224  vlib_add_trace (vm, node, b[ii], sizeof (*t));
225  t->arc_head = arc_head;
226  t->sw_if_index = arc_head ? sw_if_index[ii] : ~0;
227  t->feature_bitmap = vnet_buffer (b[ii])->l2.feature_bitmap;
228  t->ethertype = arc_head ? ethertype[ii] : 0;
229  t->next_index = next[ii];
230  }
231 }
232 
236  int is_output, vlib_node_registration_t * fa_node,
237  int arc_head, int do_trace)
238 {
239  u32 n_left, *from;
241  u16 ethertypes[VLIB_FRAME_SIZE], *ethertype;
245 
246  u8 ip4_arc_index = fam->ip4_feat_arc_index[is_output];
247  u8 ip6_arc_index = fam->ip6_feat_arc_index[is_output];
248  u8 nonip_arc_index = fam->nonip_feat_arc_index[is_output];
249  u32 *next_node_indices = fam->feat_next_node_index[is_output];
250 
251  from = vlib_frame_vector_args (frame);
252  vlib_get_buffers (vm, from, bufs, frame->n_vectors);
253  /* set the initial values for the current buffer the next pointers */
254  b = bufs;
255  next = nexts;
256  ethertype = ethertypes;
257  sw_if_index = sw_if_indices;
258  n_left = frame->n_vectors;
259 
260  CLIB_PREFETCH (next_node_indices, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
261 
262  while (n_left > 3 * L2_FEAT_ARC_VEC_SIZE)
263  {
264  const int vec_sz = L2_FEAT_ARC_VEC_SIZE;
265  /* prefetch next N buffers */
266  buffer_prefetch_xN (vec_sz, b + 2 * vec_sz);
267 
268  if (arc_head)
269  {
270  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
271  get_ethertype_xN (vec_sz, is_output, b, ethertype);
272  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
273  sw_if_index, ethertype, ip4_arc_index,
274  ip6_arc_index, nonip_arc_index, next);
275  }
276  else
277  {
278  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
279  next);
280  }
281  if (do_trace)
282  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
283  next);
284 
285  next += vec_sz;
286  b += vec_sz;
287  sw_if_index += vec_sz;
288  ethertype += vec_sz;
289 
290  n_left -= vec_sz;
291  }
292 
293  while (n_left > 0)
294  {
295  const int vec_sz = 1;
296 
297  if (arc_head)
298  {
299  get_sw_if_index_xN (vec_sz, is_output, b, sw_if_index);
300  get_ethertype_xN (vec_sz, is_output, b, ethertype);
301  set_next_in_arc_head_xN (vec_sz, is_output, next_node_indices, b,
302  sw_if_index, ethertype, ip4_arc_index,
303  ip6_arc_index, nonip_arc_index, next);
304  }
305  else
306  {
307  set_next_in_arc_tail_xN (vec_sz, is_output, next_node_indices, b,
308  next);
309  }
310  if (do_trace)
311  maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
312  next);
313 
314  next += vec_sz;
315  b += vec_sz;
316  sw_if_index += vec_sz;
317  ethertype += vec_sz;
318 
319  n_left -= vec_sz;
320  }
321 
322  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
323 
324  return frame->n_vectors;
325 }
326 
327 VLIB_NODE_FN (l2_in_feat_arc_node) (vlib_main_t * vm,
330 {
331  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
332  return l2_in_out_feat_arc_node_fn (vm, node, frame,
334  &l2_in_feat_arc_node, 1, 1);
335  else
336  return l2_in_out_feat_arc_node_fn (vm, node, frame,
338  &l2_in_feat_arc_node, 1, 0);
339 }
340 
341 VLIB_NODE_FN (l2_out_feat_arc_node) (vlib_main_t * vm,
344 {
345  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
346  return l2_in_out_feat_arc_node_fn (vm, node, frame,
348  &l2_out_feat_arc_node, 1, 1);
349  else
350  return l2_in_out_feat_arc_node_fn (vm, node, frame,
352  &l2_out_feat_arc_node, 1, 0);
353 }
354 
355 VLIB_NODE_FN (l2_in_feat_arc_end_node) (vlib_main_t * vm,
358 {
359  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
360  return l2_in_out_feat_arc_node_fn (vm, node, frame,
362  &l2_in_feat_arc_end_node, 0, 1);
363  else
364  return l2_in_out_feat_arc_node_fn (vm, node, frame,
366  &l2_in_feat_arc_end_node, 0, 0);
367 }
368 
369 VLIB_NODE_FN (l2_out_feat_arc_end_node) (vlib_main_t * vm,
372 {
373  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
374  return l2_in_out_feat_arc_node_fn (vm, node, frame,
376  &l2_out_feat_arc_end_node, 0, 1);
377  else
378  return l2_in_out_feat_arc_node_fn (vm, node, frame,
380  &l2_out_feat_arc_end_node, 0, 0);
381 }
382 
383 
384 #ifndef CLIB_MARCH_VARIANT
385 void
387  int enable_disable)
388 {
389  if (is_output)
390  l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_OUTPUT_FEAT_ARC,
391  (u32) enable_disable);
392  else
393  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_INPUT_FEAT_ARC,
394  (u32) enable_disable);
395 }
396 #endif /* CLIB_MARCH_VARIANT */
397 
398 /* *INDENT-OFF* */
399 VNET_FEATURE_ARC_INIT (l2_in_ip4_arc, static) =
400 {
401  .arc_name = "l2-input-ip4",
402  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
403  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
404 };
405 
406 VNET_FEATURE_ARC_INIT (l2_out_ip4_arc, static) =
407 {
408  .arc_name = "l2-output-ip4",
409  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
410  .arc_index_ptr = &l2_in_out_feat_arc_main.ip4_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
411 };
412 
413 VNET_FEATURE_ARC_INIT (l2_out_ip6_arc, static) =
414 {
415  .arc_name = "l2-input-ip6",
416  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
417  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
418 };
419 VNET_FEATURE_ARC_INIT (l2_in_ip6_arc, static) =
420 {
421  .arc_name = "l2-output-ip6",
422  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
423  .arc_index_ptr = &l2_in_out_feat_arc_main.ip6_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
424 };
425 
426 VNET_FEATURE_ARC_INIT (l2_out_nonip_arc, static) =
427 {
428  .arc_name = "l2-input-nonip",
429  .start_nodes = VNET_FEATURES ("l2-input-feat-arc"),
430  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_INPUT_TABLE_GROUP],
431 };
432 VNET_FEATURE_ARC_INIT (l2_in_nonip_arc, static) =
433 {
434  .arc_name = "l2-output-nonip",
435  .start_nodes = VNET_FEATURES ("l2-output-feat-arc"),
436  .arc_index_ptr = &l2_in_out_feat_arc_main.nonip_feat_arc_index[IN_OUT_FEAT_ARC_OUTPUT_TABLE_GROUP],
437 };
438 
439 
440 /* *INDENT-ON* */
441 
442 
443 /* *INDENT-OFF* */
444 VLIB_REGISTER_NODE (l2_in_feat_arc_node) = {
445  .name = "l2-input-feat-arc",
446  .vector_size = sizeof (u32),
447  .format_trace = format_l2_in_feat_arc_trace,
449 
450  .n_errors = ARRAY_LEN(l2_in_feat_arc_error_strings),
451  .error_strings = l2_in_feat_arc_error_strings,
452 
453 };
454 
455 VLIB_REGISTER_NODE (l2_out_feat_arc_node) = {
456  .name = "l2-output-feat-arc",
457  .vector_size = sizeof (u32),
458  .format_trace = format_l2_out_feat_arc_trace,
460 
461  .n_errors = ARRAY_LEN(l2_out_feat_arc_error_strings),
462  .error_strings = l2_out_feat_arc_error_strings,
463 
464 };
465 
466 VLIB_REGISTER_NODE (l2_in_feat_arc_end_node) = {
467  .name = "l2-input-feat-arc-end",
468  .vector_size = sizeof (u32),
469  .format_trace = format_l2_in_feat_arc_trace,
470  .sibling_of = "l2-input-feat-arc",
471 };
472 
473 VLIB_REGISTER_NODE (l2_out_feat_arc_end_node) = {
474  .name = "l2-output-feat-arc-end",
475  .vector_size = sizeof (u32),
476  .format_trace = format_l2_out_feat_arc_trace,
477  .sibling_of = "l2-output-feat-arc",
478 };
479 
480 VNET_FEATURE_INIT (l2_in_ip4_arc_end, static) =
481 {
482  .arc_name = "l2-input-ip4",
483  .node_name = "l2-input-feat-arc-end",
484  .runs_before = 0, /* not before any other features */
485 };
486 
487 VNET_FEATURE_INIT (l2_out_ip4_arc_end, static) =
488 {
489  .arc_name = "l2-output-ip4",
490  .node_name = "l2-output-feat-arc-end",
491  .runs_before = 0, /* not before any other features */
492 };
493 
494 VNET_FEATURE_INIT (l2_in_ip6_arc_end, static) =
495 {
496  .arc_name = "l2-input-ip6",
497  .node_name = "l2-input-feat-arc-end",
498  .runs_before = 0, /* not before any other features */
499 };
500 
501 
502 VNET_FEATURE_INIT (l2_out_ip6_arc_end, static) =
503 {
504  .arc_name = "l2-output-ip6",
505  .node_name = "l2-output-feat-arc-end",
506  .runs_before = 0, /* not before any other features */
507 };
508 
509 VNET_FEATURE_INIT (l2_in_nonip_arc_end, static) =
510 {
511  .arc_name = "l2-input-nonip",
512  .node_name = "l2-input-feat-arc-end",
513  .runs_before = 0, /* not before any other features */
514 };
515 
516 
517 VNET_FEATURE_INIT (l2_out_nonip_arc_end, static) =
518 {
519  .arc_name = "l2-output-nonip",
520  .node_name = "l2-output-feat-arc-end",
521  .runs_before = 0, /* not before any other features */
522 };
523 /* *INDENT-ON* */
524 
525 
526 #ifndef CLIB_MARCH_VARIANT
527 clib_error_t *
529 {
531 
532  /* Initialize the feature next-node indexes */
534  l2_in_feat_arc_end_node.index,
539  feat_bitmap_init_next_nodes (vm, l2_out_feat_arc_end_node.index,
543  return 0;
544 }
545 
546 
547 static int
549 {
550  int has_features = 0;
552  has_features +=
553  vnet_have_features (mp->ip4_feat_arc_index[is_output], sw_if_index);
554  has_features +=
555  vnet_have_features (mp->ip6_feat_arc_index[is_output], sw_if_index);
556  has_features +=
557  vnet_have_features (mp->nonip_feat_arc_index[is_output], sw_if_index);
558  return has_features > 0;
559 }
560 
561 static int
563 {
566  return (mp->ip4_feat_arc_index[idx] == arc_index
567  || mp->ip6_feat_arc_index[idx] == arc_index
568  || mp->nonip_feat_arc_index[idx] == arc_index);
569 }
570 
571 static int
573 {
576  return (mp->ip4_feat_arc_index[idx] == arc_index
577  || mp->ip6_feat_arc_index[idx] == arc_index
578  || mp->nonip_feat_arc_index[idx] == arc_index);
579 }
580 
581 int
582 vnet_l2_feature_enable_disable (const char *arc_name, const char *node_name,
583  u32 sw_if_index, int enable_disable,
584  void *feature_config,
585  u32 n_feature_config_bytes)
586 {
588  if (arc_index == (u8) ~ 0)
589  return VNET_API_ERROR_INVALID_VALUE;
590 
591  /* check the state before we tried to enable/disable */
592  int had_features = vnet_have_features (arc_index, sw_if_index);
593 
594  int ret = vnet_feature_enable_disable (arc_name, node_name, sw_if_index,
595  enable_disable, feature_config,
596  n_feature_config_bytes);
597  if (ret)
598  return ret;
599 
600  int has_features = vnet_have_features (arc_index, sw_if_index);
601 
602  if (had_features != has_features)
603  {
604  if (l2_is_output_arc (arc_index))
605  {
608  (sw_if_index, 1));
609  }
610  if (l2_is_input_arc (arc_index))
611  {
614  (sw_if_index, 0));
615  }
616  }
617  return 0;
618 }
619 
620 
622 #endif /* CLIB_MARCH_VARIANT */
623 
624 /*
625  * fd.io coding-style-patch-verification: ON
626  *
627  * Local Variables:
628  * eval: (c-set-style "gnu")
629  * End:
630  */
VNET_FEATURE_ARC_INIT(l2_in_ip4_arc, static)
static u8 * format_l2_out_feat_arc_trace(u8 *s, va_list *args)
#define CLIB_UNUSED(x)
Definition: clib.h:90
char ** l2output_get_feat_names(void)
Definition: l2_output.c:38
static int l2_is_input_arc(u8 arc_index)
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:197
static int l2_has_features(u32 sw_if_index, int is_output)
u32 sw_if_indices[VLIB_FRAME_SIZE]
u8 nonip_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
#define PREDICT_TRUE(x)
Definition: clib.h:125
u16 nexts[VLIB_FRAME_SIZE]
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)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
static char * l2_in_feat_arc_error_strings[]
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:251
#define VLIB_NODE_FN(node)
Definition: node.h:202
unsigned char u8
Definition: types.h:56
vlib_buffer_t ** b
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
unsigned int u32
Definition: types.h:88
VNET_FEATURE_INIT(l2_in_ip4_arc_end, static)
#define static_always_inline
Definition: clib.h:112
l2_in_feat_arc_error_t
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
#define foreach_l2_out_feat_arc_error
vlib_get_buffers(vm, from, b, n_left_from)
description fragment has unexpected format
Definition: map.api:433
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)
vlib_buffer_enqueue_to_next(vm, node, from,(u16 *) nexts, frame->n_vectors)
#define VLIB_FRAME_SIZE
Definition: node.h:369
vl_api_fib_path_type_t type
Definition: fib_types.api:123
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)
u16 * next
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
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:257
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)
#define PREDICT_FALSE(x)
Definition: clib.h:124
#define L2_FEAT_ARC_VEC_SIZE
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
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:625
u32 n_left
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:388
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
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:70
char ** l2input_get_feat_names(void)
Return an array of strings containing graph node names of each feature.
Definition: l2_input.c:59
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 always_inline
Definition: rdma_mlx5dv.h:23
#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:177
u8 arc_index
nat44_ei_hairpin_src_next_t next_index
u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
#define VNET_FEATURES(...)
Definition: feature.h:470
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_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
VLIB buffer representation.
Definition: buffer.h:111
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:301
#define vnet_buffer(b)
Definition: buffer.h:437
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:292
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
u8 ip6_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
Definition: defs.h:46
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:302