FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
interface_output.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * interface_output.c: interface output node
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/vnet.h>
41 #include <vnet/ip/icmp46_packet.h>
42 #include <vnet/ip/ip4.h>
43 #include <vnet/ip/ip6.h>
44 #include <vnet/udp/udp_packet.h>
45 #include <vnet/feature/feature.h>
46 
47 typedef struct
48 {
50  u8 data[128 - sizeof (u32)];
51 }
53 
54 u8 *
56 {
57  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
58  vlib_node_t *node = va_arg (*va, vlib_node_t *);
60  vnet_main_t *vnm = vnet_get_main ();
62  u32 indent;
63 
64  if (t->sw_if_index != (u32) ~ 0)
65  {
66  indent = format_get_indent (s);
67 
70  {
71  /* the interface may have been deleted by the time the trace is printed */
72  s = format (s, "sw_if_index: %d\n%U%U",
73  t->sw_if_index,
74  format_white_space, indent,
75  node->format_buffer ? node->
76  format_buffer : format_hex_bytes, t->data,
77  sizeof (t->data));
78  }
79  else
80  {
81  si = vnet_get_sw_interface (vnm, t->sw_if_index);
82 
83  s = format (s, "%U\n%U%U",
85  format_white_space, indent,
86  node->format_buffer ? node->
87  format_buffer : format_hex_bytes, t->data,
88  sizeof (t->data));
89  }
90  }
91  return s;
92 }
93 
94 static void
96  vlib_node_runtime_t * node,
97  vlib_frame_t * frame, uword n_buffers)
98 {
99  u32 n_left, *from;
100 
101  n_left = n_buffers;
102  from = vlib_frame_args (frame);
103 
104  while (n_left >= 4)
105  {
106  u32 bi0, bi1;
107  vlib_buffer_t *b0, *b1;
108  interface_output_trace_t *t0, *t1;
109 
110  /* Prefetch next iteration. */
111  vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
112  vlib_prefetch_buffer_with_index (vm, from[3], LOAD);
113 
114  bi0 = from[0];
115  bi1 = from[1];
116 
117  b0 = vlib_get_buffer (vm, bi0);
118  b1 = vlib_get_buffer (vm, bi1);
119 
120  if (b0->flags & VLIB_BUFFER_IS_TRACED)
121  {
122  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
123  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
125  sizeof (t0->data));
126  }
127  if (b1->flags & VLIB_BUFFER_IS_TRACED)
128  {
129  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
130  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX];
132  sizeof (t1->data));
133  }
134  from += 2;
135  n_left -= 2;
136  }
137 
138  while (n_left >= 1)
139  {
140  u32 bi0;
141  vlib_buffer_t *b0;
143 
144  bi0 = from[0];
145 
146  b0 = vlib_get_buffer (vm, bi0);
147 
148  if (b0->flags & VLIB_BUFFER_IS_TRACED)
149  {
150  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
151  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
153  sizeof (t0->data));
154  }
155  from += 1;
156  n_left -= 1;
157  }
158 }
159 
162 {
163  ip4_header_t *ip4;
164  ip6_header_t *ip6;
165  tcp_header_t *th;
166  udp_header_t *uh;
167 
168  int is_ip4 = (b->flags & VNET_BUFFER_F_IS_IP4) != 0;
169  int is_ip6 = (b->flags & VNET_BUFFER_F_IS_IP6) != 0;
170 
171  ASSERT (!(is_ip4 && is_ip6));
172 
173  ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
174  ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
175  th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
176  uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
177 
178  if (is_ip4)
179  {
180  ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
181  if (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM)
182  ip4->checksum = ip4_header_checksum (ip4);
183  if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM)
184  th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4);
185  if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)
186  uh->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4);
187  }
188  if (is_ip6)
189  {
190  int bogus;
191  if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM)
192  th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus);
193  if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)
194  uh->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus);
195  }
196 
197  b->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
198  b->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
199  b->flags &= ~VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
200 }
201 
204  vlib_node_runtime_t * node,
205  vlib_frame_t * frame, vnet_main_t * vnm,
207  int do_tx_offloads)
208 {
209  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
211  u32 n_left_to_tx, *from, *from_end, *to_tx;
212  u32 n_bytes, n_buffers, n_packets;
213  u32 n_bytes_b0, n_bytes_b1, n_bytes_b2, n_bytes_b3;
214  u32 thread_index = vm->thread_index;
216  u32 next_index = VNET_INTERFACE_OUTPUT_NEXT_TX;
217  u32 current_config_index = ~0;
218  u8 arc = im->output_feature_arc_index;
219 
220  n_buffers = frame->n_vectors;
221 
222  if (node->flags & VLIB_NODE_FLAG_TRACE)
223  vnet_interface_output_trace (vm, node, frame, n_buffers);
224 
225  from = vlib_frame_args (frame);
226 
227  if (rt->is_deleted)
228  return vlib_error_drop_buffers (vm, node, from,
229  /* buffer stride */ 1,
230  n_buffers,
232  node->node_index,
234 
235  si = vnet_get_sw_interface (vnm, rt->sw_if_index);
236  hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index);
237  if (!(si->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP |
240  {
242 
245  vlib_increment_simple_counter (cm, thread_index,
246  rt->sw_if_index, n_buffers);
247 
248  return vlib_error_drop_buffers (vm, node, from,
249  /* buffer stride */ 1,
250  n_buffers,
252  node->node_index,
254  }
255 
256  from_end = from + n_buffers;
257 
258  /* Total byte count of all buffers. */
259  n_bytes = 0;
260  n_packets = 0;
261 
262  /* interface-output feature arc handling */
264  {
266  fcm = vnet_feature_get_config_main (arc);
267  current_config_index = vnet_get_feature_config_index (arc,
268  rt->sw_if_index);
269  vnet_get_config_data (&fcm->config_main, &current_config_index,
270  &next_index, 0);
271  }
272 
273  while (from < from_end)
274  {
275  /* Get new next frame since previous incomplete frame may have less
276  than VNET_FRAME_SIZE vectors in it. */
277  vlib_get_new_next_frame (vm, node, next_index, to_tx, n_left_to_tx);
278 
279  while (from + 8 <= from_end && n_left_to_tx >= 4)
280  {
281  u32 bi0, bi1, bi2, bi3;
282  vlib_buffer_t *b0, *b1, *b2, *b3;
283  u32 tx_swif0, tx_swif1, tx_swif2, tx_swif3;
284  u32 or_flags;
285 
286  /* Prefetch next iteration. */
287  vlib_prefetch_buffer_with_index (vm, from[4], LOAD);
288  vlib_prefetch_buffer_with_index (vm, from[5], LOAD);
289  vlib_prefetch_buffer_with_index (vm, from[6], LOAD);
290  vlib_prefetch_buffer_with_index (vm, from[7], LOAD);
291 
292  bi0 = from[0];
293  bi1 = from[1];
294  bi2 = from[2];
295  bi3 = from[3];
296  to_tx[0] = bi0;
297  to_tx[1] = bi1;
298  to_tx[2] = bi2;
299  to_tx[3] = bi3;
300  from += 4;
301  to_tx += 4;
302  n_left_to_tx -= 4;
303 
304  b0 = vlib_get_buffer (vm, bi0);
305  b1 = vlib_get_buffer (vm, bi1);
306  b2 = vlib_get_buffer (vm, bi2);
307  b3 = vlib_get_buffer (vm, bi3);
308 
309  /* Be grumpy about zero length buffers for benefit of
310  driver tx function. */
311  ASSERT (b0->current_length > 0);
312  ASSERT (b1->current_length > 0);
313  ASSERT (b2->current_length > 0);
314  ASSERT (b3->current_length > 0);
315 
316  n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0);
317  n_bytes_b1 = vlib_buffer_length_in_chain (vm, b1);
318  n_bytes_b2 = vlib_buffer_length_in_chain (vm, b2);
319  n_bytes_b3 = vlib_buffer_length_in_chain (vm, b3);
320  tx_swif0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
321  tx_swif1 = vnet_buffer (b1)->sw_if_index[VLIB_TX];
322  tx_swif2 = vnet_buffer (b2)->sw_if_index[VLIB_TX];
323  tx_swif3 = vnet_buffer (b3)->sw_if_index[VLIB_TX];
324 
325  n_bytes += n_bytes_b0 + n_bytes_b1;
326  n_bytes += n_bytes_b2 + n_bytes_b3;
327  n_packets += 4;
328 
329  if (PREDICT_FALSE (current_config_index != ~0))
330  {
331  b0->feature_arc_index = arc;
332  b1->feature_arc_index = arc;
333  b2->feature_arc_index = arc;
334  b3->feature_arc_index = arc;
335  b0->current_config_index = current_config_index;
336  b1->current_config_index = current_config_index;
337  b2->current_config_index = current_config_index;
338  b3->current_config_index = current_config_index;
339  }
340 
341  /* update vlan subif tx counts, if required */
342  if (PREDICT_FALSE (tx_swif0 != rt->sw_if_index))
343  {
344  vlib_increment_combined_counter (im->combined_sw_if_counters +
346  thread_index, tx_swif0, 1,
347  n_bytes_b0);
348  }
349 
350  if (PREDICT_FALSE (tx_swif1 != rt->sw_if_index))
351  {
352 
353  vlib_increment_combined_counter (im->combined_sw_if_counters +
355  thread_index, tx_swif1, 1,
356  n_bytes_b1);
357  }
358 
359  if (PREDICT_FALSE (tx_swif2 != rt->sw_if_index))
360  {
361 
362  vlib_increment_combined_counter (im->combined_sw_if_counters +
364  thread_index, tx_swif2, 1,
365  n_bytes_b2);
366  }
367  if (PREDICT_FALSE (tx_swif3 != rt->sw_if_index))
368  {
369 
370  vlib_increment_combined_counter (im->combined_sw_if_counters +
372  thread_index, tx_swif3, 1,
373  n_bytes_b3);
374  }
375 
376  or_flags = b0->flags | b1->flags | b2->flags | b3->flags;
377 
378  if (do_tx_offloads)
379  {
380  if (or_flags &
381  (VNET_BUFFER_F_OFFLOAD_TCP_CKSUM |
382  VNET_BUFFER_F_OFFLOAD_UDP_CKSUM |
383  VNET_BUFFER_F_OFFLOAD_IP_CKSUM))
384  {
385  calc_checksums (vm, b0);
386  calc_checksums (vm, b1);
387  calc_checksums (vm, b2);
388  calc_checksums (vm, b3);
389  }
390  }
391  }
392 
393  while (from + 1 <= from_end && n_left_to_tx >= 1)
394  {
395  u32 bi0;
396  vlib_buffer_t *b0;
397  u32 tx_swif0;
398 
399  bi0 = from[0];
400  to_tx[0] = bi0;
401  from += 1;
402  to_tx += 1;
403  n_left_to_tx -= 1;
404 
405  b0 = vlib_get_buffer (vm, bi0);
406 
407  /* Be grumpy about zero length buffers for benefit of
408  driver tx function. */
409  ASSERT (b0->current_length > 0);
410 
411  n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0);
412  tx_swif0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
413  n_bytes += n_bytes_b0;
414  n_packets += 1;
415 
416  if (PREDICT_FALSE (current_config_index != ~0))
417  {
418  b0->feature_arc_index = arc;
419  b0->current_config_index = current_config_index;
420  }
421 
422  if (PREDICT_FALSE (tx_swif0 != rt->sw_if_index))
423  {
424 
425  vlib_increment_combined_counter (im->combined_sw_if_counters +
427  thread_index, tx_swif0, 1,
428  n_bytes_b0);
429  }
430 
431  if (do_tx_offloads)
432  calc_checksums (vm, b0);
433  }
434 
435  vlib_put_next_frame (vm, node, next_index, n_left_to_tx);
436  }
437 
438  /* Update main interface stats. */
439  vlib_increment_combined_counter (im->combined_sw_if_counters
441  thread_index,
442  rt->sw_if_index, n_packets, n_bytes);
443  return n_buffers;
444 }
445 
446 static uword
448  vlib_frame_t * frame)
449 {
450  vnet_main_t *vnm = vnet_get_main ();
452  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
453  hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index);
454 
456  return vnet_interface_output_node_inline (vm, node, frame, vnm, hi,
457  /* do_tx_offloads */ 0);
458  else
459  return vnet_interface_output_node_inline (vm, node, frame, vnm, hi,
460  /* do_tx_offloads */ 1);
461 }
462 
465 
466 /* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
467 static uword
469  vlib_node_runtime_t * node,
470  vlib_frame_t * frame)
471 {
472  vnet_main_t *vnm = vnet_get_main ();
473  u32 n_left_to_next, *from, *to_next;
474  u32 n_left_from, next_index;
475 
476  n_left_from = frame->n_vectors;
477 
478  from = vlib_frame_args (frame);
479  next_index = node->cached_next_index;
480 
481  while (n_left_from > 0)
482  {
483  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
484 
485  while (n_left_from >= 4 && n_left_to_next >= 2)
486  {
487  u32 bi0, bi1, next0, next1;
488  vlib_buffer_t *b0, *b1;
489  vnet_hw_interface_t *hi0, *hi1;
490 
491  /* Prefetch next iteration. */
492  vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
493  vlib_prefetch_buffer_with_index (vm, from[3], LOAD);
494 
495  bi0 = from[0];
496  bi1 = from[1];
497  to_next[0] = bi0;
498  to_next[1] = bi1;
499  from += 2;
500  to_next += 2;
501  n_left_to_next -= 2;
502  n_left_from -= 2;
503 
504  b0 = vlib_get_buffer (vm, bi0);
505  b1 = vlib_get_buffer (vm, bi1);
506 
507  hi0 =
509  vnet_buffer (b0)->sw_if_index
510  [VLIB_TX]);
511  hi1 =
513  vnet_buffer (b1)->sw_if_index
514  [VLIB_TX]);
515 
516  next0 = hi0->output_node_next_index;
517  next1 = hi1->output_node_next_index;
518 
519  vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
520  n_left_to_next, bi0, bi1, next0,
521  next1);
522  }
523 
524  while (n_left_from > 0 && n_left_to_next > 0)
525  {
526  u32 bi0, next0;
527  vlib_buffer_t *b0;
528  vnet_hw_interface_t *hi0;
529 
530  bi0 = from[0];
531  to_next[0] = bi0;
532  from += 1;
533  to_next += 1;
534  n_left_to_next -= 1;
535  n_left_from -= 1;
536 
537  b0 = vlib_get_buffer (vm, bi0);
538 
539  hi0 =
541  vnet_buffer (b0)->sw_if_index
542  [VLIB_TX]);
543 
544  next0 = hi0->output_node_next_index;
545 
546  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
547  n_left_to_next, bi0, next0);
548  }
549 
550  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
551  }
552 
553  return frame->n_vectors;
554 }
555 
558 {
559  vlib_node_t *n;
560  u32 ci, ni;
561 
562  ni = vlib_error_get_node (e);
563  n = vlib_get_node (vm, ni);
564 
565  ci = vlib_error_get_code (e);
566  ASSERT (ci < n->n_errors);
567 
568  ci += n->error_heap_index;
569 
570  return ci;
571 }
572 
573 static u8 *
574 format_vnet_error_trace (u8 * s, va_list * va)
575 {
576  vlib_main_t *vm = va_arg (*va, vlib_main_t *);
577  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
578  vlib_error_t *e = va_arg (*va, vlib_error_t *);
579  vlib_node_t *error_node;
580  vlib_error_main_t *em = &vm->error_main;
581  u32 i;
582 
583  error_node = vlib_get_node (vm, vlib_error_get_node (e[0]));
584  i = counter_index (vm, e[0]);
585  s = format (s, "%v: %s", error_node->name, em->error_strings_heap[i]);
586 
587  return s;
588 }
589 
590 static void
592  vlib_node_runtime_t * node, vlib_frame_t * frame)
593 {
594  u32 n_left, *buffers;
595 
596  buffers = vlib_frame_vector_args (frame);
597  n_left = frame->n_vectors;
598 
599  while (n_left >= 4)
600  {
601  u32 bi0, bi1;
602  vlib_buffer_t *b0, *b1;
603  vlib_error_t *t0, *t1;
604 
605  /* Prefetch next iteration. */
606  vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
607  vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);
608 
609  bi0 = buffers[0];
610  bi1 = buffers[1];
611 
612  b0 = vlib_get_buffer (vm, bi0);
613  b1 = vlib_get_buffer (vm, bi1);
614 
615  if (b0->flags & VLIB_BUFFER_IS_TRACED)
616  {
617  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
618  t0[0] = b0->error;
619  }
620  if (b1->flags & VLIB_BUFFER_IS_TRACED)
621  {
622  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
623  t1[0] = b1->error;
624  }
625  buffers += 2;
626  n_left -= 2;
627  }
628 
629  while (n_left >= 1)
630  {
631  u32 bi0;
632  vlib_buffer_t *b0;
633  vlib_error_t *t0;
634 
635  bi0 = buffers[0];
636 
637  b0 = vlib_get_buffer (vm, bi0);
638 
639  if (b0->flags & VLIB_BUFFER_IS_TRACED)
640  {
641  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
642  t0[0] = b0->error;
643  }
644  buffers += 1;
645  n_left -= 1;
646  }
647 }
648 
649 static u8 *
651 {
652  uword node_index = vlib_error_get_node (e[0]);
653  uword code = vlib_error_get_code (e[0]);
654  vlib_node_t *n;
655 
656  if (node_index >= vec_len (vm->node_main.nodes))
657  return format (0, "[%d], node index out of range 0x%x, error 0x%x",
658  index, node_index, e[0]);
659 
660  n = vlib_get_node (vm, node_index);
661  if (code >= n->n_errors)
662  return format (0, "[%d], code %d out of range for node %v",
663  index, code, n->name);
664 
665  return 0;
666 }
667 
668 static u8 *
670  vlib_node_runtime_t * node, vlib_frame_t * f)
671 {
672  u32 *buffers = vlib_frame_args (f);
673  vlib_buffer_t *b;
674  u8 *msg = 0;
675  uword i;
676 
677  for (i = 0; i < f->n_vectors; i++)
678  {
679  b = vlib_get_buffer (vm, buffers[i]);
680  msg = validate_error (vm, &b->error, i);
681  if (msg)
682  return msg;
683  }
684 
685  return msg;
686 }
687 
688 typedef enum
689 {
694 
695 always_inline void
697 {
698  vlib_error_main_t *em = &vm->error_main;
699  u32 i = counter_index (vm, a);
700  em->counters[i] += 1;
701  vlib_error_elog_count (vm, i, 1);
702 }
703 
706  vlib_node_runtime_t * node,
707  vlib_frame_t * frame, vnet_error_disposition_t disposition)
708 {
709  vnet_main_t *vnm = vnet_get_main ();
710  vlib_error_main_t *em = &vm->error_main;
711  u32 *buffers, *first_buffer;
712  vlib_error_t current_error;
713  u32 current_counter_index, n_errors_left;
714  u32 current_sw_if_index, n_errors_current_sw_if_index;
715  u64 current_counter;
717  u32 thread_index = vm->thread_index;
718 
720  static char memory_init[VNET_ERROR_N_DISPOSITION];
721 
722  buffers = vlib_frame_args (frame);
723  first_buffer = buffers;
724 
725  {
726  vlib_buffer_t *b = vlib_get_buffer (vm, first_buffer[0]);
727 
728  if (!memory_init[disposition])
729  {
730  memory_init[disposition] = 1;
731  memory[disposition] = b->error;
732  }
733 
734  current_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
735  n_errors_current_sw_if_index = 0;
736  }
737 
738  current_error = memory[disposition];
739  current_counter_index = counter_index (vm, memory[disposition]);
740  current_counter = em->counters[current_counter_index];
741 
742  if (node->flags & VLIB_NODE_FLAG_TRACE)
743  trace_errors_with_buffers (vm, node, frame);
744 
745  n_errors_left = frame->n_vectors;
747  (disposition == VNET_ERROR_DISPOSITION_PUNT
750 
751  while (n_errors_left >= 2)
752  {
753  vlib_buffer_t *b0, *b1;
754  vnet_sw_interface_t *sw_if0, *sw_if1;
755  vlib_error_t e0, e1;
756  u32 bi0, bi1;
757  u32 sw_if_index0, sw_if_index1;
758 
759  bi0 = buffers[0];
760  bi1 = buffers[1];
761 
762  buffers += 2;
763  n_errors_left -= 2;
764 
765  b0 = vlib_get_buffer (vm, bi0);
766  b1 = vlib_get_buffer (vm, bi1);
767 
768  e0 = b0->error;
769  e1 = b1->error;
770 
771  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
772  sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
773 
774  /* Speculate that sw_if_index == sw_if_index[01]. */
775  n_errors_current_sw_if_index += 2;
776 
777  /* Speculatively assume all 2 (node, code) pairs are equal
778  to current (node, code). */
779  current_counter += 2;
780 
781  if (PREDICT_FALSE (e0 != current_error
782  || e1 != current_error
783  || sw_if_index0 != current_sw_if_index
784  || sw_if_index1 != current_sw_if_index))
785  {
786  current_counter -= 2;
787  n_errors_current_sw_if_index -= 2;
788 
789  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
790  vlib_increment_simple_counter (cm, thread_index, sw_if_index1, 1);
791 
792  /* Increment super-interface drop/punt counters for
793  sub-interfaces. */
794  sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0);
796  (cm, thread_index, sw_if0->sup_sw_if_index,
797  sw_if0->sup_sw_if_index != sw_if_index0);
798 
799  sw_if1 = vnet_get_sw_interface (vnm, sw_if_index1);
801  (cm, thread_index, sw_if1->sup_sw_if_index,
802  sw_if1->sup_sw_if_index != sw_if_index1);
803 
804  em->counters[current_counter_index] = current_counter;
805  do_packet (vm, e0);
806  do_packet (vm, e1);
807 
808  /* For 2 repeated errors, change current error. */
809  if (e0 == e1 && e1 != current_error)
810  {
811  current_error = e0;
812  current_counter_index = counter_index (vm, e0);
813  }
814  current_counter = em->counters[current_counter_index];
815  }
816  }
817 
818  while (n_errors_left >= 1)
819  {
820  vlib_buffer_t *b0;
821  vnet_sw_interface_t *sw_if0;
822  vlib_error_t e0;
823  u32 bi0, sw_if_index0;
824 
825  bi0 = buffers[0];
826 
827  buffers += 1;
828  n_errors_left -= 1;
829  current_counter += 1;
830 
831  b0 = vlib_get_buffer (vm, bi0);
832  e0 = b0->error;
833 
834  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
835 
836  /* Increment drop/punt counters. */
837  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
838 
839  /* Increment super-interface drop/punt counters for sub-interfaces. */
840  sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0);
841  vlib_increment_simple_counter (cm, thread_index,
842  sw_if0->sup_sw_if_index,
843  sw_if0->sup_sw_if_index != sw_if_index0);
844 
845  if (PREDICT_FALSE (e0 != current_error))
846  {
847  current_counter -= 1;
848 
849  vlib_error_elog_count (vm, current_counter_index,
850  (current_counter
851  - em->counters[current_counter_index]));
852 
853  em->counters[current_counter_index] = current_counter;
854 
855  do_packet (vm, e0);
856  current_error = e0;
857  current_counter_index = counter_index (vm, e0);
858  current_counter = em->counters[current_counter_index];
859  }
860  }
861 
862  if (n_errors_current_sw_if_index > 0)
863  {
865 
866  vlib_increment_simple_counter (cm, thread_index, current_sw_if_index,
867  n_errors_current_sw_if_index);
868 
869  si = vnet_get_sw_interface (vnm, current_sw_if_index);
870  if (si->sup_sw_if_index != current_sw_if_index)
871  vlib_increment_simple_counter (cm, thread_index, si->sup_sw_if_index,
872  n_errors_current_sw_if_index);
873  }
874 
875  vlib_error_elog_count (vm, current_counter_index,
876  (current_counter
877  - em->counters[current_counter_index]));
878 
879  /* Return cached counter. */
880  em->counters[current_counter_index] = current_counter;
881 
882  /* Save memory for next iteration. */
883  memory[disposition] = current_error;
884 
885  if (disposition == VNET_ERROR_DISPOSITION_DROP || !vm->os_punt_frame)
886  {
887  vlib_buffer_free (vm, first_buffer, frame->n_vectors);
888 
889  /* If there is no punt function, free the frame as well. */
890  if (disposition == VNET_ERROR_DISPOSITION_PUNT && !vm->os_punt_frame)
891  vlib_frame_free (vm, node, frame);
892  }
893  else
894  vm->os_punt_frame (vm, node, frame);
895 
896  return frame->n_vectors;
897 }
898 
899 static inline void
902 {
903  u32 *from;
904  u32 n_left = f->n_vectors;
905  vlib_buffer_t *b0, *p1;
906  u32 bi0;
907  i16 save_current_data;
908  u16 save_current_length;
909 
910  from = vlib_frame_vector_args (f);
911 
912  while (n_left > 0)
913  {
914  if (PREDICT_TRUE (n_left > 1))
915  {
916  p1 = vlib_get_buffer (vm, from[1]);
917  vlib_prefetch_buffer_header (p1, LOAD);
918  }
919 
920  bi0 = from[0];
921  b0 = vlib_get_buffer (vm, bi0);
922  from++;
923  n_left--;
924 
925  /* See if we're pointedly ignoring this specific error */
926  if (im->pcap_drop_filter_hash
927  && hash_get (im->pcap_drop_filter_hash, b0->error))
928  continue;
929 
930  /* Trace all drops, or drops received on a specific interface */
931  if (im->pcap_sw_if_index == 0 ||
932  im->pcap_sw_if_index == vnet_buffer (b0)->sw_if_index[VLIB_RX])
933  {
934  save_current_data = b0->current_data;
935  save_current_length = b0->current_length;
936 
937  /*
938  * Typically, we'll need to rewind the buffer
939  */
940  if (b0->current_data > 0)
941  vlib_buffer_advance (b0, (word) - b0->current_data);
942 
943  pcap_add_buffer (&im->pcap_main, vm, bi0, 512);
944 
945  b0->current_data = save_current_data;
946  b0->current_length = save_current_length;
947  }
948  }
949 }
950 
951 void
952 vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add)
953 {
955 
956  if (im->pcap_drop_filter_hash == 0)
957  im->pcap_drop_filter_hash = hash_create (0, sizeof (uword));
958 
959  if (is_add)
960  hash_set (im->pcap_drop_filter_hash, error_index, 1);
961  else
962  hash_unset (im->pcap_drop_filter_hash, error_index);
963 }
964 
965 static uword
967  vlib_node_runtime_t * node, vlib_frame_t * frame)
968 {
970 
972  pcap_drop_trace (vm, im, frame);
973 
974  return process_drop_punt (vm, node, frame, VNET_ERROR_DISPOSITION_DROP);
975 }
976 
977 static uword
979  vlib_node_runtime_t * node, vlib_frame_t * frame)
980 {
981  return process_drop_punt (vm, node, frame, VNET_ERROR_DISPOSITION_PUNT);
982 }
983 
984 /* *INDENT-OFF* */
986  .function = process_drop,
987  .name = "error-drop",
988  .flags = VLIB_NODE_FLAG_IS_DROP,
989  .vector_size = sizeof (u32),
990  .format_trace = format_vnet_error_trace,
991  .validate_frame = validate_error_frame,
992 };
993 /* *INDENT-ON* */
994 
996 
997 /* *INDENT-OFF* */
999  .function = process_punt,
1002  .name = "error-punt",
1003  .vector_size = sizeof (u32),
1004  .format_trace = format_vnet_error_trace,
1005  .validate_frame = validate_error_frame,
1006 };
1007 /* *INDENT-ON* */
1008 
1010 
1011 /* *INDENT-OFF* */
1014  .name = "interface-output",
1015  .vector_size = sizeof (u32),
1016 };
1017 /* *INDENT-ON* */
1018 
1021 
1022 static uword
1024  vlib_frame_t * from_frame)
1025 {
1026  vnet_main_t *vnm = vnet_get_main ();
1027  u32 last_sw_if_index = ~0;
1028  vlib_frame_t *to_frame = 0;
1029  vnet_hw_interface_t *hw = 0;
1030  u32 *from, *to_next = 0;
1031  u32 n_left_from;
1032 
1033  from = vlib_frame_vector_args (from_frame);
1034  n_left_from = from_frame->n_vectors;
1035  while (n_left_from > 0)
1036  {
1037  u32 bi0;
1038  vlib_buffer_t *b0;
1039  u32 sw_if_index0;
1040 
1041  bi0 = from[0];
1042  from++;
1043  n_left_from--;
1044  b0 = vlib_get_buffer (vm, bi0);
1045  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
1046 
1047  if (PREDICT_FALSE ((last_sw_if_index != sw_if_index0) || to_frame == 0))
1048  {
1049  if (to_frame)
1050  {
1051  hw = vnet_get_sup_hw_interface (vnm, last_sw_if_index);
1052  vlib_put_frame_to_node (vm, hw->tx_node_index, to_frame);
1053  }
1054  last_sw_if_index = sw_if_index0;
1055  hw = vnet_get_sup_hw_interface (vnm, sw_if_index0);
1056  to_frame = vlib_get_frame_to_node (vm, hw->tx_node_index);
1057  to_next = vlib_frame_vector_args (to_frame);
1058  }
1059 
1060  to_next[0] = bi0;
1061  to_next++;
1062  to_frame->n_vectors++;
1063  }
1064  vlib_put_frame_to_node (vm, hw->tx_node_index, to_frame);
1065  return from_frame->n_vectors;
1066 }
1067 
1068 /* *INDENT-OFF* */
1070  .function = interface_tx_node_fn,
1071  .name = "interface-tx",
1072  .vector_size = sizeof (u32),
1073  .n_next_nodes = 1,
1074  .next_nodes = {
1075  [0] = "error-drop",
1076  },
1077 };
1078 
1079 VNET_FEATURE_ARC_INIT (interface_output, static) =
1080 {
1081  .arc_name = "interface-output",
1082  .start_nodes = VNET_FEATURES (0),
1084 };
1085 
1086 VNET_FEATURE_INIT (span_tx, static) = {
1087  .arc_name = "interface-output",
1088  .node_name = "span-output",
1089  .runs_before = VNET_FEATURES ("interface-tx"),
1090 };
1091 
1092 VNET_FEATURE_INIT (interface_tx, static) = {
1093  .arc_name = "interface-output",
1094  .node_name = "interface-tx",
1095  .runs_before = 0,
1096 };
1097 /* *INDENT-ON* */
1098 
1099 clib_error_t *
1101  u32 hw_if_index,
1102  u32 is_create)
1103 {
1104  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1105  u32 next_index;
1106 
1107  if (hi->output_node_index == 0)
1108  return 0;
1109 
1110  next_index = vlib_node_add_next
1112  hi->output_node_index);
1113  hi->output_node_next_index = next_index;
1114 
1115  return 0;
1116 }
1117 
1120 
1121 void
1123  u32 hw_if_index, u32 node_index)
1124 {
1125  ASSERT (node_index);
1126  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1127  u32 next_index = vlib_node_add_next
1128  (vnm->vlib_main, vnet_per_buffer_interface_output_node.index, node_index);
1129  hi->output_node_next_index = next_index;
1130  hi->output_node_index = node_index;
1131 }
1132 
1133 static clib_error_t *
1135  unformat_input_t * input,
1136  vlib_cli_command_t * cmd)
1137 {
1138  vnet_main_t *vnm = vnet_get_main ();
1140  u8 *filename;
1141  u32 max;
1142  int matched = 0;
1143  clib_error_t *error = 0;
1144 
1145  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1146  {
1147  if (unformat (input, "on"))
1148  {
1149  if (im->drop_pcap_enable == 0)
1150  {
1151  if (im->pcap_filename == 0)
1152  im->pcap_filename = format (0, "/tmp/drop.pcap%c", 0);
1153 
1154  memset (&im->pcap_main, 0, sizeof (im->pcap_main));
1155  im->pcap_main.file_name = (char *) im->pcap_filename;
1156  im->pcap_main.n_packets_to_capture = 100;
1157  if (im->pcap_pkts_to_capture)
1159 
1160  im->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet;
1161  im->drop_pcap_enable = 1;
1162  matched = 1;
1163  vlib_cli_output (vm, "pcap drop capture on...");
1164  }
1165  else
1166  {
1167  vlib_cli_output (vm, "pcap drop capture already on...");
1168  }
1169  matched = 1;
1170  }
1171  else if (unformat (input, "off"))
1172  {
1173  matched = 1;
1174 
1175  if (im->drop_pcap_enable)
1176  {
1177  vlib_cli_output (vm, "captured %d pkts...",
1179  if (im->pcap_main.n_packets_captured)
1180  {
1183  error = pcap_write (&im->pcap_main);
1184  if (error)
1185  clib_error_report (error);
1186  else
1187  vlib_cli_output (vm, "saved to %s...", im->pcap_filename);
1188  }
1189  }
1190  else
1191  {
1192  vlib_cli_output (vm, "pcap drop capture already off...");
1193  }
1194 
1195  im->drop_pcap_enable = 0;
1196  }
1197  else if (unformat (input, "max %d", &max))
1198  {
1199  im->pcap_pkts_to_capture = max;
1200  matched = 1;
1201  }
1202 
1203  else if (unformat (input, "intfc %U",
1205  &im->pcap_sw_if_index))
1206  matched = 1;
1207  else if (unformat (input, "intfc any"))
1208  {
1209  im->pcap_sw_if_index = 0;
1210  matched = 1;
1211  }
1212  else if (unformat (input, "file %s", &filename))
1213  {
1214  u8 *chroot_filename;
1215  /* Brain-police user path input */
1216  if (strstr ((char *) filename, "..")
1217  || index ((char *) filename, '/'))
1218  {
1219  vlib_cli_output (vm, "illegal characters in filename '%s'",
1220  filename);
1221  continue;
1222  }
1223 
1224  chroot_filename = format (0, "/tmp/%s%c", filename, 0);
1225  vec_free (filename);
1226 
1227  if (im->pcap_filename)
1228  vec_free (im->pcap_filename);
1229  im->pcap_filename = chroot_filename;
1230  im->pcap_main.file_name = (char *) im->pcap_filename;
1231  matched = 1;
1232  }
1233  else if (unformat (input, "status"))
1234  {
1235  if (im->drop_pcap_enable == 0)
1236  {
1237  vlib_cli_output (vm, "pcap drop capture is off...");
1238  continue;
1239  }
1240 
1241  vlib_cli_output (vm, "pcap drop capture: %d of %d pkts...",
1244  matched = 1;
1245  }
1246 
1247  else
1248  break;
1249  }
1250 
1251  if (matched == 0)
1252  return clib_error_return (0, "unknown input `%U'",
1253  format_unformat_error, input);
1254 
1255  return 0;
1256 }
1257 
1258 /* *INDENT-OFF* */
1259 VLIB_CLI_COMMAND (pcap_trace_command, static) = {
1260  .path = "pcap drop trace",
1261  .short_help =
1262  "pcap drop trace on off max <nn> intfc <intfc> file <name> status",
1263  .function = pcap_drop_trace_command_fn,
1264 };
1265 /* *INDENT-ON* */
1266 
1267 /*
1268  * fd.io coding-style-patch-verification: ON
1269  *
1270  * Local Variables:
1271  * eval: (c-set-style "gnu")
1272  * End:
1273  */
u8 * format_vnet_interface_output_trace(u8 *s, va_list *va)
vnet_config_main_t config_main
Definition: feature.h:65
vmrglw vmrglh hi
u32 error_heap_index
Definition: node.h:278
VNET_FEATURE_ARC_INIT(interface_output, static)
#define hash_set(h, key, value)
Definition: hash.h:254
char * file_name
File name of pcap output.
Definition: pcap.h:127
pcap_main_t pcap_main
Definition: interface.h:724
#define CLIB_UNUSED(x)
Definition: clib.h:79
void vnet_set_interface_output_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Set interface output node - for interface registered without its output/tx nodes created because its ...
static_always_inline uword vnet_interface_output_node_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vnet_main_t *vnm, vnet_hw_interface_t *hi, int do_tx_offloads)
VLIB_NODE_FUNCTION_MULTIARCH_CLONE(vnet_interface_output_node)
#define hash_unset(h, key)
Definition: hash.h:260
a
Definition: bitmap.h:516
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:211
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:391
u8 runtime_data[0]
Function dependent node-runtime data.
Definition: node.h:464
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:130
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:133
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
static uword vnet_interface_output_node(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vnet_interface_main_t interface_main
Definition: vnet.h:56
#define PREDICT_TRUE(x)
Definition: clib.h:106
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 thread_index
Definition: main.h:176
#define VLIB_NODE_FLAG_IS_PUNT
Definition: node.h:255
clib_error_t * vnet_per_buffer_interface_output_hw_interface_add_del(vnet_main_t *vnm, u32 hw_if_index, u32 is_create)
static void vnet_interface_output_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, uword n_buffers)
int i
static u32 format_get_indent(u8 *s)
Definition: format.h:72
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
Definition: counter.h:78
unformat_function_t unformat_vnet_sw_interface
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:167
void vnet_pcap_drop_trace_filter_add_del(u32 error_index, int is_add)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:390
CLIB_MULTIARCH_SELECT_FN(vnet_interface_output_node)
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:107
struct _tcp_header tcp_header_t
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1110
vhost_user_memory_t memory
Definition: vhost-user.h:84
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:104
#define static_always_inline
Definition: clib.h:93
uword * pcap_drop_filter_hash
Definition: interface.h:728
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
Definition: buffer_funcs.h:181
static u8 * validate_error_frame(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
#define always_inline
Definition: clib.h:92
static_always_inline void calc_checksums(vlib_main_t *vm, vlib_buffer_t *b)
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static u32 counter_index(vlib_main_t *vm, vlib_error_t e)
vlib_node_t ** nodes
Definition: node.h:640
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:191
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:182
u8 feature_arc_index
Used to identify feature arcs by intermediate feature node.
Definition: buffer.h:137
#define vlib_get_new_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:369
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned long u64
Definition: types.h:89
static vlib_node_registration_t drop_buffers
(constructor) VLIB_REGISTER_NODE (drop_buffers)
A collection of simple counters.
Definition: counter.h:58
static void pcap_drop_trace(vlib_main_t *vm, vnet_interface_main_t *im, vlib_frame_t *f)
static vlib_node_registration_t vnet_per_buffer_interface_output_node
(constructor) VLIB_REGISTER_NODE (vnet_per_buffer_interface_output_node)
static uword interface_tx_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
u8 data[128-sizeof(u32)]
#define hash_get(h, key)
Definition: hash.h:248
format_function_t format_vnet_sw_interface_name
vlib_main_t * vlib_main
Definition: vnet.h:78
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:108
static u8 * format_vnet_error_trace(u8 *s, va_list *va)
vlib_error_main_t error_main
Definition: main.h:141
#define VNET_SW_INTERFACE_FLAG_BOND_SLAVE
Definition: interface.h:597
VNET_FEATURE_INIT(span_tx, static)
uword vlib_error_drop_buffers(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u32 next_buffer_stride, u32 n_buffers, u32 next_index, u32 drop_error_node, u32 drop_error_code)
Definition: error.c:44
struct _unformat_input_t unformat_input_t
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:191
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:209
vnet_error_disposition_t
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:122
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
Definition: main.c:211
static void pcap_add_buffer(pcap_main_t *pm, vlib_main_t *vm, u32 buffer_index, u32 n_bytes_in_trace)
Add buffer (vlib_buffer_t) to the trace.
Definition: pcap.h:202
#define PREDICT_FALSE(x)
Definition: clib.h:105
u32 vlib_error_t
Definition: error.h:44
vnet_main_t vnet_main
Definition: misc.c:43
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:717
format_function_t * format_buffer
Definition: node.h:311
u32 node_index
Node index.
Definition: node.h:437
#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
#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:218
#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:364
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:130
static u32 vlib_error_get_code(vlib_error_t e)
Definition: error.h:53
u8 * name
Definition: node.h:221
u64 * counters
Definition: error.h:78
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
static_always_inline uword process_drop_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vnet_error_disposition_t disposition)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
char ** error_strings_heap
Definition: error.h:85
u16 n_vectors
Definition: node.h:344
vlib_main_t * vm
Definition: buffer.c:294
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:250
#define clib_memcpy(a, b, c)
Definition: string.h:75
VLIB_NODE_FUNCTION_MULTIARCH(drop_buffers, process_drop)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:270
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD
Definition: interface.h:431
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
clib_error_t * pcap_write(pcap_main_t *pm)
Write PCAP file.
Definition: pcap.c:89
static uword process_drop(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
Definition: ip6_forward.c:865
#define hash_create(elts, value_bytes)
Definition: hash.h:681
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:456
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:588
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
Definition: ip4_forward.c:1041
static void trace_errors_with_buffers(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define clib_error_report(e)
Definition: error.h:113
static void * vlib_frame_args(vlib_frame_t *f)
Get pointer to frame scalar data.
Definition: node_funcs.h:284
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:222
static vlib_node_registration_t interface_tx
(constructor) VLIB_REGISTER_NODE (interface_tx)
#define VNET_FEATURES(...)
Definition: feature.h:375
u64 uword
Definition: types.h:112
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:55
VNET_HW_INTERFACE_ADD_DEL_FUNCTION(vnet_per_buffer_interface_output_hw_interface_add_del)
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:133
Definition: defs.h:47
unsigned short u16
Definition: types.h:57
i64 word
Definition: types.h:111
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static_always_inline u32 vnet_get_feature_config_index(u8 arc, u32 sw_if_index)
Definition: feature.h:174
vlib_node_main_t node_main
Definition: main.h:132
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:709
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
#define VLIB_NODE_FLAG_IS_DROP
Definition: node.h:254
static clib_error_t * pcap_drop_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
short i16
Definition: types.h:46
#define vnet_buffer(b)
Definition: buffer.h:372
static void vlib_error_elog_count(vlib_main_t *vm, uword counter, uword increment)
Definition: error_funcs.h:46
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u16 n_errors
Definition: node.h:271
static vlib_node_registration_t punt_buffers
(constructor) VLIB_REGISTER_NODE (punt_buffers)
u8 data[0]
Packet data.
Definition: buffer.h:179
static uword vnet_per_buffer_interface_output(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
void(* os_punt_frame)(struct vlib_main_t *vm, struct vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: main.h:145
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
u16 flags
Copy of main node flags.
Definition: node.h:450
static uword process_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
static u32 vlib_error_get_node(vlib_error_t e)
Definition: error.h:47
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
static_always_inline vnet_feature_config_main_t * vnet_feature_get_config_main(u16 arc)
Definition: feature.h:160
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
static void do_packet(vlib_main_t *vm, vlib_error_t a)
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:136
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:239
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static u8 * validate_error(vlib_main_t *vm, vlib_error_t *e, u32 index)