FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
l2_efp_filter.c
Go to the documentation of this file.
1 /*
2  * l2_efp_filter.c : layer 2 egress EFP Filter processing
3  *
4  * Copyright (c) 2013 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/ethernet/ethernet.h>
21 #include <vnet/ethernet/packet.h>
22 #include <vnet/l2/feat_bitmap.h>
23 #include <vnet/l2/l2_output.h>
24 #include <vnet/ethernet/ethernet.h>
25 #include <vnet/l2/l2_efp_filter.h>
26 
27 #include <vppinfra/error.h>
28 #include <vppinfra/cache.h>
29 
30 /**
31  * @file
32  * @brief EFP-filter - Ethernet Flow Point Filter.
33  *
34  * It is possible to transmit a packet out a subinterface with VLAN tags
35  * that are not compatible with that subinterface. In other words, if that
36  * packet arrived on the output port, it would not be classified as coming
37  * from the output subinterface. This can happen in various ways: through
38  * misconfiguration, by putting subinterfaces with different VLAN encaps in
39  * the same bridge-domain, etc. The EFP Filter Check detects such packets
40  * and drops them. It consists of two checks, one that verifies the packet
41  * prior to output VLAN tag rewrite and one that verifies the packet after
42  * VLAN tag rewrite.
43  *
44  */
45 typedef struct
46 {
47  /* Next nodes for L2 output features */
48  u32 l2_out_feat_next[32];
49 
50  /* convenience variables */
54 
55 
56 typedef struct
57 {
58  /* per-pkt trace data */
59  u8 src[6];
60  u8 dst[6];
61  u8 raw[12]; /* raw data (vlans) */
64 
65 /* packet trace format function */
66 static u8 *
67 format_l2_efp_filter_trace (u8 * s, va_list * args)
68 {
69  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
70  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
71  l2_efp_filter_trace_t *t = va_arg (*args, l2_efp_filter_trace_t *);
72 
73  s = format (s, "l2-output-vtr: sw_if_index %d dst %U src %U data "
74  "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
75  t->sw_if_index,
78  t->raw[0], t->raw[1], t->raw[2], t->raw[3], t->raw[4],
79  t->raw[5], t->raw[6], t->raw[7], t->raw[8], t->raw[9],
80  t->raw[10], t->raw[11]);
81  return s;
82 }
83 
85 
86 #ifndef CLIB_MARCH_VARIANT
88 #endif /* CLIB_MARCH_VARIANT */
89 
90 #define foreach_l2_efp_filter_error \
91 _(L2_EFP_FILTER, "L2 EFP filter packets") \
92 _(DROP, "L2 EFP filter post-rewrite drops")
93 
94 typedef enum
95 {
96 #define _(sym,str) L2_EFP_FILTER_ERROR_##sym,
98 #undef _
101 
102 static char *l2_efp_filter_error_strings[] = {
103 #define _(sym,string) string,
105 #undef _
106 };
107 
108 typedef enum
109 {
113 
114 
115 /**
116  * Extract fields from the packet that will be used in interface
117  * classification.
118  */
121  u32 sw_if_index0,
122  vlib_buffer_t * b0,
123  u32 * port_sw_if_index0,
124  u16 * first_ethertype0,
125  u16 * outer_id0, u16 * inner_id0, u32 * match_flags0)
126 {
127  ethernet_header_t *e0;
129  u32 tag_len;
130  u32 tag_num;
131 
132  *port_sw_if_index0 =
134 
135  e0 = vlib_buffer_get_current (b0);
136  h0 = (ethernet_vlan_header_t *) (e0 + 1);
137 
138  *first_ethertype0 = clib_net_to_host_u16 (e0->type);
139  *outer_id0 = clib_net_to_host_u16 (h0[0].priority_cfi_and_id);
140  *inner_id0 = clib_net_to_host_u16 (h0[1].priority_cfi_and_id);
141 
142  tag_len = vnet_buffer (b0)->l2.l2_len - sizeof (ethernet_header_t);
143  tag_num = tag_len / sizeof (ethernet_vlan_header_t);
144  *match_flags0 = eth_create_valid_subint_match_flags (tag_num);
145 }
146 
147 /*
148  * EFP filtering is a basic switch feature which prevents an interface from
149  * transmitting a packet that doesn't match the interface's ingress match
150  * criteria. The check has two parts, one performed before egress vlan tag
151  * rewrite and one after.
152  *
153  * The pre-rewrite check insures the packet matches what an ingress packet looks
154  * like after going through the interface's ingress tag rewrite operation. Only
155  * pushed tags are compared. So:
156  * - if the ingress vlan tag rewrite pushes no tags (or is not enabled),
157  * any packet passes the filter
158  * - if the ingress vlan tag rewrite pushes one tag,
159  * the packet must have at least one tag, and the outer tag must match the pushed tag
160  * - if the ingress vlan tag rewrite pushes two tags,
161  * the packet must have at least two tags, and the outer two tags must match the pushed tags
162  *
163  * The pre-rewrite check is performed in the l2-output node.
164  *
165  * The post-rewrite check insures the packet matches what an ingress packet looks
166  * like before going through the interface's ingress tag rewrite operation. It verifies
167  * that such a packet arriving on the wire at this port would be classified as arriving
168  * an input interface equal to the packet's output interface. This can be done by running
169  * the output packet's vlan tags and output port through the interface classification,
170  * and checking if the resulting interface matches the output interface.
171  *
172  * The post-rewrite check is performed here.
173  */
174 
178 {
179  u32 n_left_from, *from, *to_next;
183  u32 node_counter_base_index = n->error_heap_index;
185 
187  n_left_from = frame->n_vectors; /* number of packets to process */
188  next_index = node->cached_next_index;
189 
190  while (n_left_from > 0)
191  {
192  u32 n_left_to_next;
193 
194  /* get space to enqueue frame to graph node "next_index" */
195  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
196 
197  while (n_left_from >= 6 && n_left_to_next >= 2)
198  {
199  u32 bi0, bi1;
200  vlib_buffer_t *b0, *b1;
201  u32 next0, next1;
202  u32 sw_if_index0, sw_if_index1;
203  u16 first_ethertype0, first_ethertype1;
204  u16 outer_id0, inner_id0, outer_id1, inner_id1;
205  u32 match_flags0, match_flags1;
206  u32 port_sw_if_index0, subint_sw_if_index0, port_sw_if_index1,
207  subint_sw_if_index1;
208  vnet_hw_interface_t *hi0, *hi1;
209  main_intf_t *main_intf0, *main_intf1;
210  vlan_intf_t *vlan_intf0, *vlan_intf1;
211  qinq_intf_t *qinq_intf0, *qinq_intf1;
212  u32 is_l20, is_l21;
213  __attribute__ ((unused)) u32 matched0, matched1;
214  u8 error0, error1;
215 
216  /* Prefetch next iteration. */
217  {
218  vlib_buffer_t *p2, *p3, *p4, *p5;
219  __attribute__ ((unused)) u32 sw_if_index2, sw_if_index3;
220 
221  p2 = vlib_get_buffer (vm, from[2]);
222  p3 = vlib_get_buffer (vm, from[3]);
223  p4 = vlib_get_buffer (vm, from[4]);
224  p5 = vlib_get_buffer (vm, from[5]);
225 
226  /* Prefetch the buffer header and packet for the N+2 loop iteration */
227  vlib_prefetch_buffer_header (p4, LOAD);
228  vlib_prefetch_buffer_header (p5, LOAD);
229 
232 
233  /*
234  * Prefetch the input config for the N+1 loop iteration
235  * This depends on the buffer header above
236  */
237  sw_if_index2 = vnet_buffer (p2)->sw_if_index[VLIB_TX];
238  sw_if_index3 = vnet_buffer (p3)->sw_if_index[VLIB_TX];
239  /*
240  * $$$ TODO
241  * clib_prefetch_load (vec_elt_at_index(l2output_main.configs,
242  * sw_if_index2));
243  * clib_prefetch_load (vec_elt_at_index(l2output_main.configs,
244  * sw_if_index3));
245  */
246  }
247 
248  /* speculatively enqueue b0 and b1 to the current next frame */
249  /* bi is "buffer index", b is pointer to the buffer */
250  to_next[0] = bi0 = from[0];
251  to_next[1] = bi1 = from[1];
252  from += 2;
253  to_next += 2;
254  n_left_from -= 2;
255  n_left_to_next -= 2;
256 
257  b0 = vlib_get_buffer (vm, bi0);
258  b1 = vlib_get_buffer (vm, bi1);
259 
260  /* TX interface handles */
261  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
262  sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_TX];
263 
264  /* process 2 packets */
265  em->counters[node_counter_base_index +
266  L2_EFP_FILTER_ERROR_L2_EFP_FILTER] += 2;
267 
268  /* Determine next node */
269  next0 = vnet_l2_feature_next (b0, msm->l2_out_feat_next,
270  L2OUTPUT_FEAT_EFP_FILTER);
271  next1 = vnet_l2_feature_next (b1, msm->l2_out_feat_next,
272  L2OUTPUT_FEAT_EFP_FILTER);
273 
274  /* perform the efp filter check on two packets */
275 
276  extract_keys (msm->vnet_main,
277  sw_if_index0,
278  b0,
279  &port_sw_if_index0,
280  &first_ethertype0,
281  &outer_id0, &inner_id0, &match_flags0);
282 
283  extract_keys (msm->vnet_main,
284  sw_if_index1,
285  b1,
286  &port_sw_if_index1,
287  &first_ethertype1,
288  &outer_id1, &inner_id1, &match_flags1);
289 
291  msm->vnet_main,
292  port_sw_if_index0,
293  first_ethertype0,
294  outer_id0,
295  inner_id0,
296  &hi0,
297  &main_intf0, &vlan_intf0, &qinq_intf0);
298 
300  msm->vnet_main,
301  port_sw_if_index1,
302  first_ethertype1,
303  outer_id1,
304  inner_id1,
305  &hi1,
306  &main_intf1, &vlan_intf1, &qinq_intf1);
307 
308  matched0 = eth_identify_subint (hi0,
309  match_flags0,
310  main_intf0,
311  vlan_intf0,
312  qinq_intf0,
313  &subint_sw_if_index0,
314  &error0, &is_l20);
315 
316  matched1 = eth_identify_subint (hi1,
317  match_flags1,
318  main_intf1,
319  vlan_intf1,
320  qinq_intf1,
321  &subint_sw_if_index1,
322  &error1, &is_l21);
323 
324  if (PREDICT_FALSE (sw_if_index0 != subint_sw_if_index0))
325  {
326  /* Drop packet */
327  next0 = L2_EFP_FILTER_NEXT_DROP;
328  b0->error = node->errors[L2_EFP_FILTER_ERROR_DROP];
329  }
330 
331  if (PREDICT_FALSE (sw_if_index1 != subint_sw_if_index1))
332  {
333  /* Drop packet */
334  next1 = L2_EFP_FILTER_NEXT_DROP;
335  b1->error = node->errors[L2_EFP_FILTER_ERROR_DROP];
336  }
337 
338  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
339  {
340  if (b0->flags & VLIB_BUFFER_IS_TRACED)
341  {
344  vlib_add_trace (vm, node, b0, sizeof (*t));
345  t->sw_if_index = sw_if_index0;
346  clib_memcpy_fast (t->src, h0->src_address, 6);
347  clib_memcpy_fast (t->dst, h0->dst_address, 6);
348  clib_memcpy_fast (t->raw, &h0->type, sizeof (t->raw));
349  }
350  if (b1->flags & VLIB_BUFFER_IS_TRACED)
351  {
354  vlib_add_trace (vm, node, b1, sizeof (*t));
355  t->sw_if_index = sw_if_index1;
356  clib_memcpy_fast (t->src, h1->src_address, 6);
357  clib_memcpy_fast (t->dst, h1->dst_address, 6);
358  clib_memcpy_fast (t->raw, &h1->type, sizeof (t->raw));
359  }
360  }
361 
362  /* verify speculative enqueues, maybe switch current next frame */
363  /* if next0==next1==next_index then nothing special needs to be done */
365  to_next, n_left_to_next,
366  bi0, bi1, next0, next1);
367  }
368 
369  while (n_left_from > 0 && n_left_to_next > 0)
370  {
371  u32 bi0;
372  vlib_buffer_t *b0;
373  u32 next0;
374  u32 sw_if_index0;
375  u16 first_ethertype0;
376  u16 outer_id0, inner_id0;
377  u32 match_flags0;
378  u32 port_sw_if_index0, subint_sw_if_index0;
379  vnet_hw_interface_t *hi0;
380  main_intf_t *main_intf0;
381  vlan_intf_t *vlan_intf0;
382  qinq_intf_t *qinq_intf0;
383  u32 is_l20;
384  __attribute__ ((unused)) u32 matched0;
385  u8 error0;
386 
387  /* speculatively enqueue b0 to the current next frame */
388  bi0 = from[0];
389  to_next[0] = bi0;
390  from += 1;
391  to_next += 1;
392  n_left_from -= 1;
393  n_left_to_next -= 1;
394 
395  b0 = vlib_get_buffer (vm, bi0);
396  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
397 
398  /* process 1 packet */
399  em->counters[node_counter_base_index +
400  L2_EFP_FILTER_ERROR_L2_EFP_FILTER] += 1;
401 
402  /* Determine next node */
403  next0 = vnet_l2_feature_next (b0, msm->l2_out_feat_next,
404  L2OUTPUT_FEAT_EFP_FILTER);
405 
406  /* perform the efp filter check on one packet */
407 
408  extract_keys (msm->vnet_main,
409  sw_if_index0,
410  b0,
411  &port_sw_if_index0,
412  &first_ethertype0,
413  &outer_id0, &inner_id0, &match_flags0);
414 
416  msm->vnet_main,
417  port_sw_if_index0,
418  first_ethertype0,
419  outer_id0,
420  inner_id0,
421  &hi0,
422  &main_intf0, &vlan_intf0, &qinq_intf0);
423 
424  matched0 = eth_identify_subint (hi0,
425  match_flags0,
426  main_intf0,
427  vlan_intf0,
428  qinq_intf0,
429  &subint_sw_if_index0,
430  &error0, &is_l20);
431 
432  if (PREDICT_FALSE (sw_if_index0 != subint_sw_if_index0))
433  {
434  /* Drop packet */
435  next0 = L2_EFP_FILTER_NEXT_DROP;
436  b0->error = node->errors[L2_EFP_FILTER_ERROR_DROP];
437  }
438 
439  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
440  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
441  {
444  vlib_add_trace (vm, node, b0, sizeof (*t));
445  t->sw_if_index = sw_if_index0;
446  clib_memcpy_fast (t->src, h0->src_address, 6);
447  clib_memcpy_fast (t->dst, h0->dst_address, 6);
448  clib_memcpy_fast (t->raw, &h0->type, sizeof (t->raw));
449  }
450 
451  /* verify speculative enqueue, maybe switch current next frame */
453  to_next, n_left_to_next,
454  bi0, next0);
455  }
456 
457  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
458  }
459 
460  return frame->n_vectors;
461 }
462 
463 
464 /* *INDENT-OFF* */
466  .name = "l2-efp-filter",
467  .vector_size = sizeof (u32),
468  .format_trace = format_l2_efp_filter_trace,
470 
472  .error_strings = l2_efp_filter_error_strings,
473 
474  .n_next_nodes = L2_EFP_FILTER_N_NEXT,
475 
476  /* edit / add dispositions here */
477  .next_nodes = {
478  [L2_EFP_FILTER_NEXT_DROP] = "error-drop",
479  },
480 };
481 /* *INDENT-ON* */
482 
483 #ifndef CLIB_MARCH_VARIANT
484 clib_error_t *
486 {
488 
489  mp->vlib_main = vm;
490  mp->vnet_main = vnet_get_main ();
491 
492  /* Initialize the feature next-node indexes */
494  l2_efp_filter_node.index,
497  mp->l2_out_feat_next);
498 
499  return 0;
500 }
501 
503 
504 
505 /** Enable/disable the EFP Filter check on the subinterface. */
506 void
508 {
509  /* set the interface flag */
510  l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_EFP_FILTER, enable);
511 }
512 
513 
514 /**
515  * Set subinterface egress efp filter enable/disable.
516  * The CLI format is:
517  * set interface l2 efp-filter <interface> [disable]]
518  */
519 static clib_error_t *
521  unformat_input_t * input, vlib_cli_command_t * cmd)
522 {
523  vnet_main_t *vnm = vnet_get_main ();
524  clib_error_t *error = 0;
526  u32 enable;
527 
529  {
530  error = clib_error_return (0, "unknown interface `%U'",
531  format_unformat_error, input);
532  goto done;
533  }
534 
535  enable = 1;
536  if (unformat (input, "disable"))
537  {
538  enable = 0;
539  }
540 
541  /* enable/disable the feature */
542  l2_efp_filter_configure (vnm, sw_if_index, enable);
543 
544 done:
545  return error;
546 }
547 
548 
549 /*?
550  * EFP filtering is a basic switch feature which prevents an interface from
551  * transmitting a packet that doesn't match the interface's ingress match
552  * criteria. The check has two parts, one performed before egress vlan tag
553  * rewrite and one after. This command enables or disables the EFP filtering
554  * for a given sub-interface.
555  *
556  * @cliexpar
557  * Example of how to enable a Layer 2 efp-filter on a sub-interface:
558  * @cliexcmd{set interface l2 efp-filter GigabitEthernet0/8/0.200}
559  * Example of how to disable a Layer 2 efp-filter on a sub-interface:
560  * @cliexcmd{set interface l2 efp-filter GigabitEthernet0/8/0.200 disable}
561 ?*/
562 /* *INDENT-OFF* */
564  .path = "set interface l2 efp-filter",
565  .short_help = "set interface l2 efp-filter <interface> [disable]",
566  .function = int_l2_efp_filter,
567 };
568 /* *INDENT-ON* */
569 
570 #endif /* CLIB_MARCH_VARIANT */
571 
572 /*
573  * fd.io coding-style-patch-verification: ON
574  *
575  * Local Variables:
576  * eval: (c-set-style "gnu")
577  * End:
578  */
vlib.h
vlib_error_main_t
Definition: error.h:61
extract_keys
static_always_inline void extract_keys(vnet_main_t *vnet_main, u32 sw_if_index0, vlib_buffer_t *b0, u32 *port_sw_if_index0, u16 *first_ethertype0, u16 *outer_id0, u16 *inner_id0, u32 *match_flags0)
Extract fields from the packet that will be used in interface classification.
Definition: l2_efp_filter.c:120
l2_efp_filter_trace_t
Definition: l2_efp_filter.c:56
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
eth_identify_subint
static u32 eth_identify_subint(vnet_hw_interface_t *hi, u32 match_flags, main_intf_t *main_intf, vlan_intf_t *vlan_intf, qinq_intf_t *qinq_intf, u32 *new_sw_if_index, u8 *error0, u32 *is_l2)
Definition: ethernet.h:522
l2_efp_filter_error_t
l2_efp_filter_error_t
Definition: l2_efp_filter.c:94
l2_efp_filter.h
raw
const char *const const char *const raw
Definition: cJSON.h:270
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlan_intf_t
Definition: ethernet.h:239
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
ethernet_vlan_header_t
Definition: packet.h:128
l2_efp_filter_trace_t::src
u8 src[6]
Definition: l2_efp_filter.c:59
format_ethernet_address
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
ethernet_header_t::dst_address
u8 dst_address[6]
Definition: packet.h:55
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
eth_create_valid_subint_match_flags
static u32 eth_create_valid_subint_match_flags(u32 num_tags)
Definition: ethernet.h:225
vlib_cli_command_t::path
char * path
Definition: cli.h:96
int_l2_efp_filter
static clib_error_t * int_l2_efp_filter(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set subinterface egress efp filter enable/disable.
Definition: l2_efp_filter.c:520
vlib_main_t::error_main
vlib_error_main_t error_main
Definition: main.h:179
u16
unsigned short u16
Definition: types.h:57
ethernet_header_t::type
u16 type
Definition: packet.h:59
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
l2_efp_filter_main_t::vlib_main
vlib_main_t * vlib_main
Definition: l2_efp_filter.c:51
unformat_input_t
struct _unformat_input_t unformat_input_t
int_l2_efp_filter_cli
static vlib_cli_command_t int_l2_efp_filter_cli
(constructor) VLIB_CLI_COMMAND (int_l2_efp_filter_cli)
Definition: l2_efp_filter.c:563
vlib_frame_t
Definition: node.h:372
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
ethernet.h
error
Definition: cJSON.c:88
l2_efp_filter_main_t::vnet_main
vnet_main_t * vnet_main
Definition: l2_efp_filter.c:52
L2_EFP_FILTER_NEXT_DROP
@ L2_EFP_FILTER_NEXT_DROP
Definition: l2_efp_filter.c:110
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
l2_efp_filter_init
clib_error_t * l2_efp_filter_init(vlib_main_t *vm)
Definition: l2_efp_filter.c:485
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:876
l2_efp_filter_node
vlib_node_registration_t l2_efp_filter_node
(constructor) VLIB_REGISTER_NODE (l2_efp_filter_node)
Definition: l2_efp_filter.c:465
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
packet.h
l2_efp_filter_main_t::l2_out_feat_next
u32 l2_out_feat_next[32]
Definition: l2_efp_filter.c:48
vlib_error_main_t::counters
u64 * counters
Definition: error.h:64
error.h
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
l2_output.h
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
l2output_get_feat_names
char ** l2output_get_feat_names(void)
Definition: l2_output.c:38
qinq_intf_t
Definition: ethernet.h:251
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
L2OUTPUT_N_FEAT
@ L2OUTPUT_N_FEAT
Definition: l2_output.h:105
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
main_intf_t
Definition: ethernet.h:231
static_always_inline
#define static_always_inline
Definition: clib.h:112
l2_efp_filter_next_t
l2_efp_filter_next_t
Definition: l2_efp_filter.c:108
ethernet_header_t
Definition: packet.h:52
l2_efp_filter_configure
void l2_efp_filter_configure(vnet_main_t *vnet_main, u32 sw_if_index, u8 enable)
Enable/disable the EFP Filter check on the subinterface.
Definition: l2_efp_filter.c:507
vlib_get_node
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:86
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
src
vl_api_address_t src
Definition: gre.api:54
l2_efp_filter_main
l2_efp_filter_main_t l2_efp_filter_main
Definition: l2_efp_filter.c:87
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_l2_feature_next
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_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vlib_validate_buffer_enqueue_x1
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
ethernet_main
ethernet_main_t ethernet_main
Definition: init.c:45
L2_EFP_FILTER_N_NEXT
@ L2_EFP_FILTER_N_NEXT
Definition: l2_efp_filter.c:111
l2output_intf_bitmap_enable
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
l2_efp_filter_main_t
Definition: l2_efp_filter.c:45
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:462
format
description fragment has unexpected format
Definition: map.api:433
cache.h
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
u32
unsigned int u32
Definition: types.h:88
l2_efp_filter_error_strings
static char * l2_efp_filter_error_strings[]
Definition: l2_efp_filter.c:102
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
l2_efp_filter_trace_t::dst
u8 dst[6]
Definition: l2_efp_filter.c:60
l2_efp_filter_trace_t::raw
u8 raw[12]
Definition: l2_efp_filter.c:61
vnet_main
vnet_main_t vnet_main
Definition: misc.c:43
foreach_l2_efp_filter_error
#define foreach_l2_efp_filter_error
Definition: l2_efp_filter.c:90
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
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
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
feat_bitmap.h
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
l2_efp_filter_trace_t::sw_if_index
u32 sw_if_index
Definition: l2_efp_filter.c:62
vlib_buffer_t::data
u8 data[]
Packet data.
Definition: buffer.h:204
vlib_node_t::error_heap_index
u32 error_heap_index
Definition: node.h:315
vlib_validate_buffer_enqueue_x2
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
clib_prefetch_store
static_always_inline void clib_prefetch_store(void *p)
Definition: cache.h:98
vnet.h
vlib_node_runtime_t
Definition: node.h:454
vnet_get_sup_sw_interface
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:81
vlib_cli_command_t
Definition: cli.h:92
from
from
Definition: nat44_ei_hairpinning.c:415
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vlib_get_next_frame
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:395
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
format_l2_efp_filter_trace
static u8 * format_l2_efp_filter_trace(u8 *s, va_list *args)
Definition: l2_efp_filter.c:67
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
feat_bitmap_init_next_nodes
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
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
eth_vlan_table_lookups
static void eth_vlan_table_lookups(ethernet_main_t *em, vnet_main_t *vnm, u32 port_sw_if_index0, u16 first_ethertype, u16 outer_id, u16 inner_id, vnet_hw_interface_t **hi, main_intf_t **main_intf, vlan_intf_t **vlan_intf, qinq_intf_t **qinq_intf)
Definition: ethernet.h:483
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
L2_EFP_FILTER_N_ERROR
@ L2_EFP_FILTER_N_ERROR
Definition: l2_efp_filter.c:99