FD.io VPP  v21.06-3-gbb25fbf28
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/ethernet/packet.h>
43 #include <vnet/ip/format.h>
44 #include <vnet/ip/ip4.h>
45 #include <vnet/ip/ip6.h>
46 #include <vnet/udp/udp_packet.h>
47 #include <vnet/feature/feature.h>
49 #include <vnet/interface_output.h>
50 #include <vppinfra/vector_funcs.h>
51 
52 typedef struct
53 {
56  u8 data[128 - 2 * sizeof (u32)];
57 }
59 
60 #ifndef CLIB_MARCH_VARIANT
61 u8 *
63 {
64  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
65  vlib_node_t *node = va_arg (*va, vlib_node_t *);
67  vnet_main_t *vnm = vnet_get_main ();
69  u32 indent;
70 
71  if (t->sw_if_index != (u32) ~ 0)
72  {
73  indent = format_get_indent (s);
74 
77  {
78  /* the interface may have been deleted by the time the trace is printed */
79  s = format (s, "sw_if_index: %d ", t->sw_if_index);
80  }
81  else
82  {
84  s =
85  format (s, "%U ", format_vnet_sw_interface_name, vnm, si,
86  t->flags);
87  }
88  s =
89  format (s, "\n%U%U", format_white_space, indent,
90  node->format_buffer ? node->format_buffer : format_hex_bytes,
91  t->data, sizeof (t->data));
92  }
93  return s;
94 }
95 #endif /* CLIB_MARCH_VARIANT */
96 
97 static void
101 {
102  u32 n_left, *from;
103 
104  n_left = n_buffers;
106 
107  while (n_left >= 4)
108  {
109  u32 bi0, bi1;
110  vlib_buffer_t *b0, *b1;
111  interface_output_trace_t *t0, *t1;
112 
113  /* Prefetch next iteration. */
116 
117  bi0 = from[0];
118  bi1 = from[1];
119 
120  b0 = vlib_get_buffer (vm, bi0);
121  b1 = vlib_get_buffer (vm, bi1);
122 
123  if (b0->flags & VLIB_BUFFER_IS_TRACED)
124  {
125  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
126  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
127  t0->flags = b0->flags;
129  sizeof (t0->data));
130  }
131  if (b1->flags & VLIB_BUFFER_IS_TRACED)
132  {
133  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
134  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX];
135  t1->flags = b1->flags;
137  sizeof (t1->data));
138  }
139  from += 2;
140  n_left -= 2;
141  }
142 
143  while (n_left >= 1)
144  {
145  u32 bi0;
146  vlib_buffer_t *b0;
148 
149  bi0 = from[0];
150 
151  b0 = vlib_get_buffer (vm, bi0);
152 
153  if (b0->flags & VLIB_BUFFER_IS_TRACED)
154  {
155  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
156  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
157  t0->flags = b0->flags;
159  sizeof (t0->data));
160  }
161  from += 1;
162  n_left -= 1;
163  }
164 }
165 
168 {
169  vnet_calc_checksums_inline (vm, b, b->flags & VNET_BUFFER_F_IS_IP4,
170  b->flags & VNET_BUFFER_F_IS_IP6);
171 }
172 
178  int arc_or_subif)
179 {
180  u32 n_bytes = 0;
181  u32 n_bytes0, n_bytes1, n_bytes2, n_bytes3;
182  u32 ti = vm->thread_index;
183 
184  while (n_left >= 8)
185  {
186  u32 or_flags;
187 
188  /* Prefetch next iteration. */
189  vlib_prefetch_buffer_header (b[4], LOAD);
190  vlib_prefetch_buffer_header (b[5], LOAD);
191  vlib_prefetch_buffer_header (b[6], LOAD);
192  vlib_prefetch_buffer_header (b[7], LOAD);
193 
194  if (do_tx_offloads)
195  or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags;
196 
197  /* Be grumpy about zero length buffers for benefit of
198  driver tx function. */
199  ASSERT (b[0]->current_length > 0);
200  ASSERT (b[1]->current_length > 0);
201  ASSERT (b[2]->current_length > 0);
202  ASSERT (b[3]->current_length > 0);
203 
204  n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);
205  n_bytes += n_bytes1 = vlib_buffer_length_in_chain (vm, b[1]);
206  n_bytes += n_bytes2 = vlib_buffer_length_in_chain (vm, b[2]);
207  n_bytes += n_bytes3 = vlib_buffer_length_in_chain (vm, b[3]);
208 
209  if (arc_or_subif)
210  {
211  u32 tx_swif0, tx_swif1, tx_swif2, tx_swif3;
212  tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
213  tx_swif1 = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
214  tx_swif2 = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
215  tx_swif3 = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
216 
217  /* update vlan subif tx counts, if required */
218  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
219  vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
220 
221  if (PREDICT_FALSE (tx_swif1 != sw_if_index))
222  vlib_increment_combined_counter (ccm, ti, tx_swif1, 1, n_bytes1);
223 
224  if (PREDICT_FALSE (tx_swif2 != sw_if_index))
225  vlib_increment_combined_counter (ccm, ti, tx_swif2, 1, n_bytes2);
226 
227  if (PREDICT_FALSE (tx_swif3 != sw_if_index))
228  vlib_increment_combined_counter (ccm, ti, tx_swif3, 1, n_bytes3);
229 
230  if (PREDICT_FALSE (config_index != ~0))
231  {
232  vnet_buffer (b[0])->feature_arc_index = arc;
234  vnet_buffer (b[1])->feature_arc_index = arc;
236  vnet_buffer (b[2])->feature_arc_index = arc;
238  vnet_buffer (b[3])->feature_arc_index = arc;
240  }
241  }
242 
243  if (do_tx_offloads && (or_flags & VNET_BUFFER_F_OFFLOAD))
244  {
249  }
250 
251  n_left -= 4;
252  b += 4;
253  }
254 
255  while (n_left)
256  {
257  /* Be grumpy about zero length buffers for benefit of
258  driver tx function. */
259  ASSERT (b[0]->current_length > 0);
260 
261  n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);
262 
263  if (arc_or_subif)
264  {
265  u32 tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
266 
267  if (PREDICT_FALSE (config_index != ~0))
268  {
269  vnet_buffer (b[0])->feature_arc_index = arc;
271  }
272 
273  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
274  vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
275  }
276 
277  if (do_tx_offloads)
279 
280  n_left -= 1;
281  b += 1;
282  }
283 
284  return n_bytes;
285 }
286 
289  int sw_if_index_from_buffer)
290 {
291  vnet_main_t *vnm = vnet_get_main ();
292  u32 n_left_from, *from;
294  vnet_pcap_t *pp = &vnm->pcap;
295 
296  if (PREDICT_TRUE (pp->pcap_tx_enable == 0))
297  return;
298 
299  if (sw_if_index_from_buffer == 0)
300  {
301  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
303  }
304  else
305  sw_if_index = ~0;
306 
307  n_left_from = frame->n_vectors;
309 
310  while (n_left_from > 0)
311  {
312  u32 bi0 = from[0];
313  vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
314  from++;
315  n_left_from--;
316 
317  if (sw_if_index_from_buffer)
318  sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
319 
320  if (vnet_is_packet_pcaped (pp, b0, sw_if_index))
321  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
322  }
323 }
324 
328 {
329  if (r)
331 }
332 
336 {
339  u32 n_free, n_copy, *to;
341  vlib_frame_t *f;
342 
344 
347 
350 
351  if (f->n_vectors > 0 && (r == 0 || tf->queue_id == r->frame.queue_id))
352  {
353  /* append current next frame */
355  n_copy = clib_min (n_vectors, n_free);
356  n_vectors -= n_copy;
358  to += f->n_vectors;
359  }
360  else
361  {
362  if (f->n_vectors > 0)
363  {
364  /* current frame doesn't fit - grab empty one */
367  }
368 
369  /* empty frame - store scalar data */
373  n_copy = n_vectors;
374  n_vectors = 0;
375  }
376 
377  vlib_buffer_copy_indices (to, from, n_copy);
379 
380  if (n_vectors == 0)
381  return;
382 
383  /* we have more indices to store, take empty frame */
384  from += n_copy;
389 }
390 
393 {
394  vnet_main_t *vnm = vnet_get_main ();
399  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
401  u32 n_bytes, n_buffers = frame->n_vectors;
407  int arc_or_subif = 0;
408  int do_tx_offloads = 0;
410 
411  if (node->flags & VLIB_NODE_FLAG_TRACE)
413 
415 
416  if (rt->is_deleted)
417  return vlib_error_drop_buffers (
418  vm, node, from,
421 
423  0 /* sw_if_index_from_buffer */ );
424 
426 
429 
432  {
434 
438 
439  return vlib_error_drop_buffers (
440  vm, node, from,
441  /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP,
443  }
444 
445  /* interface-output feature arc handling */
447  {
452  arc_or_subif = 1;
453  }
455  arc_or_subif = 1;
456 
458 
460  do_tx_offloads = 1;
461 
462  if (do_tx_offloads == 0 && arc_or_subif == 0)
465  else if (do_tx_offloads == 0 && arc_or_subif == 1)
468  else if (do_tx_offloads == 1 && arc_or_subif == 0)
471  else
474 
477  {
478  enqueu_to_tx_node (vm, node, hi, from, frame->n_vectors);
479  }
480  else
481  {
483  frame->n_vectors);
484  }
485 
486  /* Update main interface stats. */
488  return n_buffers;
489 }
490 
492  .name = "interface-output-template",
493  .vector_size = sizeof (u32),
494 };
495 
496 /* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
499  node,
501 {
502  vnet_main_t *vnm = vnet_get_main ();
503  u32 n_left_to_next, *from, *to_next;
505 
507  1 /* sw_if_index_from_buffer */ );
508 
509  n_left_from = frame->n_vectors;
510 
512  next_index = node->cached_next_index;
513 
514  while (n_left_from > 0)
515  {
516  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
517 
518  while (n_left_from >= 4 && n_left_to_next >= 2)
519  {
520  u32 bi0, bi1, next0, next1;
521  vlib_buffer_t *b0, *b1;
522  vnet_hw_interface_t *hi0, *hi1;
523 
524  /* Prefetch next iteration. */
527 
528  bi0 = from[0];
529  bi1 = from[1];
530  to_next[0] = bi0;
531  to_next[1] = bi1;
532  from += 2;
533  to_next += 2;
534  n_left_to_next -= 2;
535  n_left_from -= 2;
536 
537  b0 = vlib_get_buffer (vm, bi0);
538  b1 = vlib_get_buffer (vm, bi1);
539 
540  hi0 =
543  [VLIB_TX]);
544  hi1 =
547  [VLIB_TX]);
548 
549  next0 = hi0->output_node_next_index;
550  next1 = hi1->output_node_next_index;
551 
553  n_left_to_next, bi0, bi1, next0,
554  next1);
555  }
556 
557  while (n_left_from > 0 && n_left_to_next > 0)
558  {
559  u32 bi0, next0;
560  vlib_buffer_t *b0;
561  vnet_hw_interface_t *hi0;
562 
563  bi0 = from[0];
564  to_next[0] = bi0;
565  from += 1;
566  to_next += 1;
567  n_left_to_next -= 1;
568  n_left_from -= 1;
569 
570  b0 = vlib_get_buffer (vm, bi0);
571 
572  hi0 =
575  [VLIB_TX]);
576 
577  next0 = hi0->output_node_next_index;
578 
580  n_left_to_next, bi0, next0);
581  }
582 
583  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
584  }
585 
586  return frame->n_vectors;
587 }
588 
589 typedef struct vnet_error_trace_t_
590 {
594  u8 pad[2];
596  ip46_address_t src, dst;
598 
599 static u8 *
600 format_vnet_error_trace (u8 * s, va_list * va)
601 {
602  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
603  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
604  vnet_error_trace_t *t = va_arg (*va, vnet_error_trace_t *);
605 
606  /* Normal, non-catchup trace */
607  if (t->details_valid == 0)
608  {
609  s = format (s, "rx:%U", format_vnet_sw_if_index_name,
610  vnet_get_main (), t->sw_if_index);
611  }
612  else if (t->details_valid == 1)
613  {
614  /* The trace capture code didn't understant the mactype */
615  s = format (s, "mactype 0x%4x (not decoded)", t->mactype);
616  }
617  else if (t->details_valid == 2)
618  {
619  /* Dump the src/dst addresses */
620  if (t->is_ip6 == 0)
621  s = format (s, "IP4: %U -> %U",
622  format_ip4_address, &t->src.ip4,
623  format_ip4_address, &t->dst.ip4);
624  else
625  s = format (s, "IP6: %U -> %U",
626  format_ip6_address, &t->src.ip6,
627  format_ip6_address, &t->dst.ip6);
628  }
629  return s;
630 }
631 
632 static void
635 {
636  u32 n_left, *buffers;
637 
638  buffers = vlib_frame_vector_args (frame);
639  n_left = frame->n_vectors;
640 
641  while (n_left >= 4)
642  {
643  u32 bi0, bi1;
644  vlib_buffer_t *b0, *b1;
645  vnet_error_trace_t *t0, *t1;
646 
647  /* Prefetch next iteration. */
648  vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
649  vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);
650 
651  bi0 = buffers[0];
652  bi1 = buffers[1];
653 
654  b0 = vlib_get_buffer (vm, bi0);
655  b1 = vlib_get_buffer (vm, bi1);
656 
657  if (b0->flags & VLIB_BUFFER_IS_TRACED)
658  {
659  t0 = vlib_add_trace (vm, node, b0,
661  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
662  t0->details_valid = 0;
663  }
664  if (b1->flags & VLIB_BUFFER_IS_TRACED)
665  {
666  t1 = vlib_add_trace (vm, node, b1,
668  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX];
669  t1->details_valid = 0;
670  }
671  buffers += 2;
672  n_left -= 2;
673  }
674 
675  while (n_left >= 1)
676  {
677  u32 bi0;
678  vlib_buffer_t *b0;
679  vnet_error_trace_t *t0;
680 
681  bi0 = buffers[0];
682 
683  b0 = vlib_get_buffer (vm, bi0);
684 
685  if (b0->flags & VLIB_BUFFER_IS_TRACED)
686  {
687  t0 = vlib_add_trace (vm, node, b0,
689  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
690  t0->details_valid = 0;
691  }
692  buffers += 1;
693  n_left -= 1;
694  }
695 }
696 
697 typedef enum
698 {
703 
704 static void
707 {
708  /* Can we safely rewind the buffer? If not, fagedaboudit */
709  if (b->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
710  {
712  ip4_header_t *ip4;
713  ip6_header_t *ip6;
714  ethernet_header_t *eh;
715  i16 delta;
716 
717  t = vlib_add_trace (vm, node, b, sizeof (*t));
718  delta = vnet_buffer (b)->l2_hdr_offset - b->current_data;
719  vlib_buffer_advance (b, delta);
720 
721  eh = vlib_buffer_get_current (b);
722  /* Save mactype */
723  t->mactype = clib_net_to_host_u16 (eh->type);
724  t->details_valid = 1;
725  switch (t->mactype)
726  {
727  case ETHERNET_TYPE_IP4:
728  ip4 = (void *) (eh + 1);
729  t->details_valid = 2;
730  t->is_ip6 = 0;
731  t->src.ip4.as_u32 = ip4->src_address.as_u32;
732  t->dst.ip4.as_u32 = ip4->dst_address.as_u32;
733  break;
734 
735  case ETHERNET_TYPE_IP6:
736  ip6 = (void *) (eh + 1);
737  t->details_valid = 2;
738  t->is_ip6 = 1;
739  clib_memcpy_fast (t->src.as_u8, ip6->src_address.as_u8,
740  sizeof (ip6_address_t));
741  clib_memcpy_fast (t->dst.as_u8, ip6->dst_address.as_u8,
742  sizeof (ip6_address_t));
743  break;
744 
745  default:
746  /* Dunno, do nothing, leave details_valid alone */
747  break;
748  }
749  /* Restore current data (probably unnecessary) */
750  vlib_buffer_advance (b, -delta);
751  }
752 }
753 
758  vnet_error_disposition_t disposition)
759 {
765  u32 n_trace;
766  vnet_main_t *vnm;
767 
768  vnm = vnet_get_main ();
771  n_left = frame->n_vectors;
772  b = bufs;
774 
776 
777  /* "trace add error-drop NNN?" */
778  if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node))))
779  {
780  /* If pkts aren't otherwise traced... */
781  if ((node->flags & VLIB_NODE_FLAG_TRACE) == 0)
782  {
783  /* Trace them from here */
784  node->flags |= VLIB_NODE_FLAG_TRACE;
785  while (n_trace && n_left)
786  {
787  if (PREDICT_TRUE
788  (vlib_trace_buffer (vm, node, 0 /* next_index */ , b[0],
789  0 /* follow chain */ )))
790  {
791  /*
792  * Here we have a wireshark dissector problem.
793  * Packets may be well-formed, or not. We
794  * must not blow chunks in any case.
795  *
796  * Try to produce trace records which will help
797  * folks understand what's going on.
798  */
799  drop_catchup_trace (vm, node, b[0]);
800  n_trace--;
801  }
802  n_left--;
803  b++;
804  }
805  }
806 
807  vlib_set_trace_count (vm, node, n_trace);
808  b = bufs;
809  n_left = frame->n_vectors;
810  }
811 
812  if (node->flags & VLIB_NODE_FLAG_TRACE)
814 
815  /* All going to drop regardless, this is just a counting exercise */
816  clib_memset (nexts, 0, sizeof (nexts));
817 
819  (disposition == VNET_ERROR_DISPOSITION_PUNT
822 
823  /* collect the array of interfaces first ... */
824  while (n_left >= 4)
825  {
826  if (n_left >= 12)
827  {
828  /* Prefetch 8 ahead - there's not much going on in each iteration */
829  vlib_prefetch_buffer_header (b[4], LOAD);
830  vlib_prefetch_buffer_header (b[5], LOAD);
831  vlib_prefetch_buffer_header (b[6], LOAD);
832  vlib_prefetch_buffer_header (b[7], LOAD);
833  }
834  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
835  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
836  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
837  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
838 
839  sw_if_index += 4;
840  n_left -= 4;
841  b += 4;
842  }
843  while (n_left)
844  {
845  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
846 
847  sw_if_index += 1;
848  n_left -= 1;
849  b += 1;
850  }
851 
852  /* ... then count against them in blocks */
853  n_left = frame->n_vectors;
854 
855  while (n_left)
856  {
857  vnet_sw_interface_t *sw_if0;
858  u16 off, count;
859 
860  off = frame->n_vectors - n_left;
861 
863 
865  n_left -= count;
866 
868 
869  /* Increment super-interface drop/punt counters for
870  sub-interfaces. */
871  sw_if0 = vnet_get_sw_interface (vnm, sw_if_index[0]);
872  if (sw_if0->sup_sw_if_index != sw_if_index[0])
874  (cm, thread_index, sw_if0->sup_sw_if_index, count);
875  }
876 
878 
879  return frame->n_vectors;
880 }
881 
882 static inline void
885  vnet_pcap_t * pp, vlib_frame_t * f)
886 {
887  u32 *from;
888  u32 n_left = f->n_vectors;
889  vlib_buffer_t *b0, *p1;
890  u32 bi0;
891  i16 save_current_data;
892  u16 save_current_length;
894 
896 
897  while (n_left > 0)
898  {
899  if (PREDICT_TRUE (n_left > 1))
900  {
901  p1 = vlib_get_buffer (vm, from[1]);
902  vlib_prefetch_buffer_header (p1, LOAD);
903  }
904 
905  bi0 = from[0];
906  b0 = vlib_get_buffer (vm, bi0);
907  from++;
908  n_left--;
909 
910  /* See if we're pointedly ignoring this specific error */
913  continue;
914 
915  if (!vnet_is_packet_pcaped (pp, b0, ~0))
916  continue; /* not matching, skip */
917 
918  /* Trace all drops, or drops received on a specific interface */
919  save_current_data = b0->current_data;
920  save_current_length = b0->current_length;
921 
922  /*
923  * Typically, we'll need to rewind the buffer
924  * if l2_hdr_offset is valid, make sure to rewind to the start of
925  * the L2 header. This may not be the buffer start in case we pop-ed
926  * vlan tags.
927  * Otherwise, rewind to buffer start and hope for the best.
928  */
929  if (b0->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
930  {
931  if (b0->current_data > vnet_buffer (b0)->l2_hdr_offset)
932  vlib_buffer_advance (b0, vnet_buffer (b0)->l2_hdr_offset -
933  b0->current_data);
934  }
935  else if (b0->current_data > 0)
936  {
938  }
939 
940  {
941  vlib_buffer_t *last = b0;
942  u32 error_node_index;
943  int drop_string_len;
944  vlib_node_t *n;
945  /* Length of the error string */
946  int error_string_len =
947  clib_strnlen (em->counters_heap[b0->error].name, 128);
948 
949  /* Dig up the drop node */
950  error_node_index = vm->node_main.node_by_error[b0->error];
951  n = vlib_get_node (vm, error_node_index);
952 
953  /* Length of full drop string, w/ "nodename: " prepended */
954  drop_string_len = error_string_len + vec_len (n->name) + 2;
955 
956  /* Find the last buffer in the chain */
957  while (last->flags & VLIB_BUFFER_NEXT_PRESENT)
958  last = vlib_get_buffer (vm, last->next_buffer);
959 
960  /*
961  * Append <nodename>: <error-string> to the capture,
962  * only if we can do that without allocating a new buffer.
963  */
964  if (PREDICT_TRUE ((last->current_data + last->current_length) <
965  (VLIB_BUFFER_DEFAULT_DATA_SIZE - drop_string_len)))
966  {
967  clib_memcpy_fast (last->data + last->current_data +
968  last->current_length,
969  n->name, vec_len (n->name));
970  clib_memcpy_fast (last->data + last->current_data +
971  last->current_length + vec_len (n->name),
972  ": ", 2);
973  clib_memcpy_fast (last->data + last->current_data +
974  last->current_length + vec_len (n->name) + 2,
975  em->counters_heap[b0->error].name,
976  error_string_len);
977  last->current_length += drop_string_len;
978  b0->flags &= ~(VLIB_BUFFER_TOTAL_LENGTH_VALID);
979  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
980  last->current_length -= drop_string_len;
981  b0->current_data = save_current_data;
982  b0->current_length = save_current_length;
983  continue;
984  }
985  }
986 
987  /*
988  * Didn't have space in the last buffer, here's the dropped
989  * packet as-is
990  */
991  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
992 
993  b0->current_data = save_current_data;
994  b0->current_length = save_current_length;
995  }
996 }
997 
998 #ifndef CLIB_MARCH_VARIANT
999 void
1000 vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add)
1001 {
1003 
1004  if (im->pcap_drop_filter_hash == 0)
1005  im->pcap_drop_filter_hash = hash_create (0, sizeof (uword));
1006 
1007  if (is_add)
1008  hash_set (im->pcap_drop_filter_hash, error_index, 1);
1009  else
1010  hash_unset (im->pcap_drop_filter_hash, error_index);
1011 }
1012 #endif /* CLIB_MARCH_VARIANT */
1013 
1016  vlib_frame_t * frame)
1017 {
1018  vnet_main_t *vnm = vnet_get_main ();
1020  vnet_pcap_t *pp = &vnm->pcap;
1021 
1022  if (PREDICT_FALSE (pp->pcap_drop_enable))
1023  pcap_drop_trace (vm, im, pp, frame);
1024 
1026 }
1027 
1030  vlib_frame_t * frame)
1031 {
1033 }
1034 
1035 /* *INDENT-OFF* */
1037  .name = "error-drop",
1038  .vector_size = sizeof (u32),
1039  .format_trace = format_vnet_error_trace,
1041  .n_next_nodes = 1,
1042  .next_nodes = {
1043  [0] = "drop",
1044  },
1045 };
1046 /* *INDENT-ON* */
1047 
1048 /* *INDENT-OFF* */
1050  .name = "error-punt",
1051  .vector_size = sizeof (u32),
1052  .format_trace = format_vnet_error_trace,
1054  .n_next_nodes = 1,
1055  .next_nodes = {
1056  [0] = "punt",
1057  },
1058 };
1059 /* *INDENT-ON* */
1060 
1062  .name = "interface-output",
1063  .vector_size = sizeof (u32),
1064 };
1065 
1068 {
1069  vnet_main_t *vnm = vnet_get_main ();
1079  u16 next_index;
1081 
1083  n_left = frame->n_vectors;
1085 
1086  while (n_left >= 8)
1087  {
1088  vlib_prefetch_buffer_header (b[4], LOAD);
1089  vlib_prefetch_buffer_header (b[5], LOAD);
1090  vlib_prefetch_buffer_header (b[6], LOAD);
1091  vlib_prefetch_buffer_header (b[7], LOAD);
1092  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
1093  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
1094  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
1095  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
1096 
1097  b += 4;
1098  sw_if_index += 4;
1099  n_left -= 4;
1100  }
1101 
1102  while (n_left)
1103  {
1104  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
1105  b++;
1106  sw_if_index++;
1107  n_left--;
1108  }
1109 
1110  n_left = frame->n_vectors;
1111  swif = sw_if_indices[0];
1112  off = 0;
1113 
1114  /* a bit ugly but it allows us to reuse stack space for temporary store
1115  * which may also improve memory latency */
1116  tmp = (u32 *) bufs;
1117 
1118 more:
1125 
1126  if (f->n_vectors > 0 && (r == 0 || r->frame.queue_id == tf->queue_id))
1127  {
1128  /* append frame */
1130  if (n_free >= f->n_vectors)
1132  else
1133  to = tmp;
1134  }
1135  else
1136  {
1137  if (f->n_vectors > 0)
1138  {
1139  /* current frame doesn't fit - grab empty one */
1142  }
1143 
1144  /* empty frame - store scalar data */
1148  }
1149 
1150  /* compare and compress based on comparison mask */
1152  n_comp = clib_compress_u32 (to, from, mask, frame->n_vectors);
1153 
1154  if (tmp != to)
1155  {
1156  /* indices already written to frame, just close it */
1158  }
1159  else if (n_free >= n_comp)
1160  {
1161  /* enough space in the existing frame */
1165  }
1166  else
1167  {
1168  /* full frame */
1172 
1173  /* second frame */
1181  }
1182 
1183  n_left -= n_comp;
1184  if (n_left)
1185  {
1186  /* store comparison mask so we can find next unused element */
1187  for (int i = 0; i < ARRAY_LEN (used_elts); i++)
1188  used_elts[i] |= mask[i];
1189 
1190  /* fine first unused sw_if_index by scanning trough used_elts bitmap */
1191  while (PREDICT_FALSE (used_elts[off] == ~0))
1192  off++;
1193 
1194  swif =
1196  goto more;
1197  }
1198 
1199  return frame->n_vectors;
1200 }
1201 
1203  .name = "interface-output-arc-end",
1204  .vector_size = sizeof (u32),
1205  .n_next_nodes = 1,
1206  .next_nodes = {
1207  [0] = "error-drop",
1208  },
1209 };
1210 
1211 VNET_FEATURE_ARC_INIT (interface_output, static) = {
1212  .arc_name = "interface-output",
1213  .start_nodes = VNET_FEATURES (0),
1214  .last_in_arc = "interface-output-arc-end",
1216 };
1217 
1218 VNET_FEATURE_INIT (span_tx, static) = {
1219  .arc_name = "interface-output",
1220  .node_name = "span-output",
1221  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
1222 };
1223 
1224 VNET_FEATURE_INIT (ipsec_if_tx, static) = {
1225  .arc_name = "interface-output",
1226  .node_name = "ipsec-if-output",
1227  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
1228 };
1229 
1230 VNET_FEATURE_INIT (interface_output_arc_end, static) = {
1231  .arc_name = "interface-output",
1232  .node_name = "interface-output-arc-end",
1233  .runs_before = 0,
1234 };
1235 
1236 #ifndef CLIB_MARCH_VARIANT
1237 clib_error_t *
1239  u32 hw_if_index,
1240  u32 is_create)
1241 {
1242  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1243  u32 next_index;
1244 
1245  if (hi->output_node_index == 0)
1246  return 0;
1247 
1252 
1253  return 0;
1254 }
1255 
1258 
1259 void
1261  u32 hw_if_index, u32 node_index)
1262 {
1263  ASSERT (node_index);
1264  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1269 }
1270 #endif /* CLIB_MARCH_VARIANT */
1271 
1272 /*
1273  * fd.io coding-style-patch-verification: ON
1274  *
1275  * Local Variables:
1276  * eval: (c-set-style "gnu")
1277  * End:
1278  */
to
u32 * to
Definition: interface_output.c:1078
vnet_pcap_drop_trace_filter_add_del
void vnet_pcap_drop_trace_filter_add_del(u32 error_index, int is_add)
Definition: interface_output.c:1000
tmp
u32 * tmp
Definition: interface_output.c:1078
vlib_error_main_t
Definition: error.h:61
vnet_error_trace_t_::src
ip46_address_t src
Definition: interface_output.c:596
vlib_frame_t::n_vectors
u16 n_vectors
Definition: node.h:387
format_vnet_error_trace
static u8 * format_vnet_error_trace(u8 *s, va_list *va)
Definition: interface_output.c:600
VNET_ERROR_DISPOSITION_PUNT
@ VNET_ERROR_DISPOSITION_PUNT
Definition: interface_output.c:700
vnet_feature_config_main_t_
Definition: feature.h:80
im
vnet_interface_main_t * im
Definition: interface_output.c:395
vnet_hw_interface_t::sub_interface_sw_if_index_by_id
uword * sub_interface_sw_if_index_by_id
Definition: interface.h:703
n_vectors
return frame n_vectors
Definition: interface_output.c:1199
vnet_hw_interface_t::output_node_thread_runtimes
vnet_hw_if_output_node_runtime_t * output_node_thread_runtimes
Definition: interface.h:673
vnet_hw_if_output_node_runtime_t
Definition: interface.h:629
format_vnet_interface_output_trace
u8 * format_vnet_interface_output_trace(u8 *s, va_list *va)
Definition: interface_output.c:62
vnet_pcap_t::pcap_main
pcap_main_t pcap_main
Definition: vnet.h:71
vnet_feature_config_main_t_::config_main
vnet_config_main_t config_main
Definition: feature.h:82
vnet_have_features
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:251
n_frame2
u32 n_frame2
Definition: interface_output.c:1174
count_trailing_zeros
#define count_trailing_zeros(x)
Definition: clib.h:161
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:492
drop_catchup_trace
static void drop_catchup_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b)
Definition: interface_output.c:705
vnet_sw_interface_t
Definition: interface.h:868
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
n_comp
u32 n_comp
Definition: interface_output.c:1078
interface_output_trace_t::flags
u32 flags
Definition: interface_output.c:55
vnet_error_disposition_t
vnet_error_disposition_t
Definition: interface_output.c:697
vnet_hw_interface_t::caps
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
n_buffers
u32 n_buffers
Definition: interface_output.c:401
vnet_error_trace_t_::dst
ip46_address_t dst
Definition: interface_output.c:596
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
format_ip4_address
format_function_t format_ip4_address
Definition: format.h:73
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
VNET_INTERFACE_COUNTER_TX
@ VNET_INTERFACE_COUNTER_TX
Definition: interface.h:918
vlib_error_main_t::counters_heap
vlib_error_desc_t * counters_heap
Definition: error.h:71
vlib_buffer_copy_indices
vlib_buffer_copy_indices(to, tmp, n_free)
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
f
vlib_frame_t * f
Definition: interface_output.c:1080
interface_drop_punt
static_always_inline uword interface_drop_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vnet_error_disposition_t disposition)
Definition: interface_output.c:755
VNET_INTERFACE_OUTPUT_NEXT_DROP
VNET_INTERFACE_OUTPUT_NEXT_DROP
Definition: interface_output.c:419
format_hex_bytes
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
vnet_hw_interface_t::flags
vnet_hw_interface_flags_t flags
Definition: interface.h:642
hi
vnet_hw_interface_t * hi
Definition: interface_output.c:397
vm
vlib_main_t * vm
Definition: interface_output.c:392
VNET_INTERFACE_OUTPUT_NEXT_TX
@ VNET_INTERFACE_OUTPUT_NEXT_TX
Definition: interface_funcs.h:489
vnet_interface_main_t
Definition: interface.h:989
vnet_interface_output_node
vlib_node_registration_t vnet_interface_output_node
(constructor) VLIB_REGISTER_NODE (vnet_interface_output_node)
Definition: interface_output.c:491
vlib_main_t::error_main
vlib_error_main_t error_main
Definition: main.h:177
u16
unsigned short u16
Definition: types.h:57
vnet_interface_output_runtime_t::sw_if_index
u32 sw_if_index
Definition: interface_funcs.h:475
vlib_main_t::node_main
vlib_node_main_t node_main
Definition: main.h:171
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:843
vlib_node_main_t::node_by_error
u32 * node_by_error
Definition: node.h:733
ethernet_header_t::type
u16 type
Definition: packet.h:59
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: interface_output.c:393
vnet_interface_output_node_inline
static_always_inline uword vnet_interface_output_node_inline(vlib_main_t *vm, u32 sw_if_index, vlib_combined_counter_main_t *ccm, vlib_buffer_t **b, u32 config_index, u8 arc, u32 n_left, int do_tx_offloads, int arc_or_subif)
Definition: interface_output.c:174
vnet_hw_if_tx_frame_t::queue_id
u32 queue_id
Definition: interface.h:626
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:420
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
vlib_get_trace_count
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
Definition: trace_funcs.h:212
vnet_interface_main_t::sw_if_counters
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:1022
vnet_error_trace_t_::pad
u8 pad[2]
Definition: interface_output.c:594
b
vlib_buffer_t ** b
Definition: interface_output.c:1074
vlib_buffer_enqueue_to_next
vlib_buffer_enqueue_to_next(vm, node, from,(u16 *) nexts, frame->n_vectors)
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: interface_output.c:400
VLIB_BUFFER_DEFAULT_DATA_SIZE
#define VLIB_BUFFER_DEFAULT_DATA_SIZE
Definition: buffer.h:53
ccm
vlib_combined_counter_main_t * ccm
Definition: interface_output.c:396
pcap_add_buffer
static void pcap_add_buffer(pcap_main_t *pm, struct vlib_main_t *vm, u32 buffer_index, u32 n_bytes_in_trace)
Add buffer (vlib_buffer_t) to the trace.
Definition: interface_funcs.h:525
vnet_calc_checksums_inline
static_always_inline void vnet_calc_checksums_inline(vlib_main_t *vm, vlib_buffer_t *b, int is_ip4, int is_ip6)
Definition: interface_output.h:83
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1071
vlib_frame_t
Definition: node.h:372
do_tx_offloads
int do_tx_offloads
Definition: interface_output.c:408
hash_create
#define hash_create(elts, value_bytes)
Definition: hash.h:695
vlib_buffer_length_in_chain
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:433
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
interface_trace_buffers
static void interface_trace_buffers(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: interface_output.c:633
ip4_header_t
Definition: ip4_packet.h:87
vlib_error_desc_t::name
char * name
Definition: error.h:56
vnet_sw_interface_t::flags
vnet_sw_interface_flags_t flags
Definition: interface.h:872
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
enqueu_to_tx_node
static_always_inline void enqueu_to_tx_node(vlib_main_t *vm, vlib_node_runtime_t *node, vnet_hw_interface_t *hi, u32 *from, u32 n_vectors)
Definition: interface_output.c:334
i16
signed short i16
Definition: types.h:46
STRUCT_OFFSET_OF
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:73
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
ti
u32 ti
Definition: interface_output.c:405
vlib_increment_simple_counter
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:74
vlib_buffer_enqueue_to_single_next
static_always_inline void vlib_buffer_enqueue_to_single_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 next_index, u32 count)
Definition: buffer_node.h:348
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
count
u8 count
Definition: dhcp.api:208
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
VNET_HW_INTERFACE_ADD_DEL_FUNCTION
VNET_HW_INTERFACE_ADD_DEL_FUNCTION(vnet_per_buffer_interface_output_hw_interface_add_del)
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
packet.h
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
feature.h
VNET_ERROR_DISPOSITION_DROP
@ VNET_ERROR_DISPOSITION_DROP
Definition: interface_output.c:699
next_index
u32 next_index
Definition: interface_output.c:404
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vnet_per_buffer_interface_output_hw_interface_add_del
clib_error_t * vnet_per_buffer_interface_output_hw_interface_add_del(vnet_main_t *vnm, u32 hw_if_index, u32 is_create)
Definition: interface_output.c:1238
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
format.h
interface_drop
vlib_node_registration_t interface_drop
(constructor) VLIB_REGISTER_NODE (interface_drop)
Definition: interface_output.c:1036
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
interface_output_trace_t::sw_if_index
u32 sw_if_index
Definition: interface_output.c:54
vector_funcs.h
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
interface_output_trace_t
Definition: interface_output.c:52
vnet_error_trace_t_::sw_if_index
u32 sw_if_index
Definition: interface_output.c:591
vnet_interface_output_runtime_t::is_deleted
u32 is_deleted
Definition: interface_funcs.h:477
store_tx_frame_scalar_data
static_always_inline void store_tx_frame_scalar_data(vnet_hw_if_output_node_runtime_t *r, vnet_hw_if_tx_frame_t *tf)
Definition: interface_output.c:326
interface_output.h
static_always_inline
#define static_always_inline
Definition: clib.h:112
VNET_FEATURE_ARC_INIT
VNET_FEATURE_ARC_INIT(interface_output, static)
vlib_prefetch_buffer_with_index
#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:507
udp_packet.h
uword
u64 uword
Definition: types.h:112
pcap_drop_trace
static void pcap_drop_trace(vlib_main_t *vm, vnet_interface_main_t *im, vnet_pcap_t *pp, vlib_frame_t *f)
Definition: interface_output.c:883
last
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
vlib_error_drop_buffers
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:45
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
hash_get
#define hash_get(h, key)
Definition: hash.h:249
ethernet_header_t
Definition: packet.h:52
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:213
interface_punt
vlib_node_registration_t interface_punt
(constructor) VLIB_REGISTER_NODE (interface_punt)
Definition: interface_output.c:1049
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
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN
@ VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN
Definition: interface_funcs.h:503
VLIB_NODE_FLAG_TRACE_SUPPORTED
#define VLIB_NODE_FLAG_TRACE_SUPPORTED
Definition: node.h:295
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:591
vnet_main_t::vlib_main
vlib_main_t * vlib_main
Definition: vnet.h:111
clib_count_equal_u32
static_always_inline uword clib_count_equal_u32(u32 *data, uword max_count)
Definition: string.h:535
vnet_pcap_t
Definition: vnet.h:60
from
u32 * from
Definition: interface_output.c:409
clib_min
#define clib_min(x, y)
Definition: clib.h:342
vlib_set_trace_count
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
Definition: trace_funcs.h:226
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_interface_main_t::combined_sw_if_counters
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:1023
vnet_interface_main_t::sw_interfaces
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:1014
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
vlib_frame_scalar_args
static void * vlib_frame_scalar_args(vlib_frame_t *f)
Get pointer to frame scalar data.
Definition: node_funcs.h:315
vnet_hw_interface_t::output_node_next_index
u32 output_node_next_index
Definition: interface.h:685
vnet_pcap_t::max_bytes_per_pkt
u32 max_bytes_per_pkt
Definition: vnet.h:69
vnet_interface_main_t::if_out_arc_end_next_index_by_sw_if_index
u16 * if_out_arc_end_next_index_by_sw_if_index
Definition: interface.h:1046
vnet_interface_output_handle_offload
static_always_inline void vnet_interface_output_handle_offload(vlib_main_t *vm, vlib_buffer_t *b)
Definition: interface_output.c:167
data
u8 data[128]
Definition: ipsec_types.api:92
tf
vnet_hw_if_tx_frame_t * tf
Definition: interface_output.c:1073
vnet_interface_output_arc_end_node
vlib_node_registration_t vnet_interface_output_arc_end_node
(constructor) VLIB_REGISTER_NODE (vnet_interface_output_arc_end_node)
Definition: interface_output.c:1202
vnet_pcap_t::pcap_tx_enable
u8 pcap_tx_enable
Definition: vnet.h:65
vlib_buffer_t::current_config_index
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:156
arc
u8 arc
Definition: interface_output.c:406
hash_elts
static uword hash_elts(void *v)
Definition: hash.h:118
vnet_per_buffer_interface_output_node
vlib_node_registration_t vnet_per_buffer_interface_output_node
(constructor) VLIB_REGISTER_NODE (vnet_per_buffer_interface_output_node)
Definition: interface_output.c:1061
clib_strnlen
#define clib_strnlen(s, m)
Definition: string.h:782
vlib_get_buffers
vlib_get_buffers(vm, from, bufs, n_buffers)
VNET_INTERFACE_COUNTER_PUNT
@ VNET_INTERFACE_COUNTER_PUNT
Definition: interface.h:904
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
VNET_FEATURE_INIT
VNET_FEATURE_INIT(span_tx, static)
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
vnet_sw_interface_t::sup_sw_if_index
u32 sup_sw_if_index
Definition: interface.h:880
vnet_hw_if_output_node_runtime_t::frame
vnet_hw_if_tx_frame_t frame
Definition: interface.h:632
vnet_error_trace_t_::mactype
u16 mactype
Definition: interface_output.c:595
vnet_error_trace_t_
Definition: interface_output.c:589
vnet_pcap_t::pcap_drop_enable
u8 pcap_drop_enable
Definition: vnet.h:67
u64
unsigned long u64
Definition: types.h:89
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:455
i8
signed char i8
Definition: types.h:45
VNET_INTERFACE_COUNTER_TX_ERROR
@ VNET_INTERFACE_COUNTER_TX_ERROR
Definition: interface.h:910
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
n_free
u32 n_free
Definition: interface_output.c:1078
config_index
u32 config_index
Definition: interface_output.c:402
vlib_combined_counter_main_t
A collection of combined counters.
Definition: counter.h:203
format_get_indent
static u32 format_get_indent(u8 *s)
Definition: format.h:72
off
u32 off
Definition: interface_output.c:1078
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
u32
unsigned int u32
Definition: types.h:88
vnet_is_packet_pcaped
static_always_inline int vnet_is_packet_pcaped(vnet_pcap_t *pp, vlib_buffer_t *b, u32 sw_if_index)
vnet_is_packet_pcaped
Definition: pcap_classify.h:32
vnet_get_sup_hw_interface
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:92
vnet_main_t::pcap
vnet_pcap_t pcap
Definition: vnet.h:103
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
n_bytes
u32 n_bytes
Definition: interface_output.c:401
mask
u64 mask[VLIB_FRAME_SIZE/64]
Definition: interface_output.c:1077
vnet_interface_output_trace
static void vnet_interface_output_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, uword n_buffers)
Definition: interface_output.c:98
pcap_classify.h
vnet_error_trace_t
struct vnet_error_trace_t_ vnet_error_trace_t
si
vnet_sw_interface_t * si
Definition: interface_output.c:398
vnet_interface_main_t::pcap_drop_filter_hash
uword * pcap_drop_filter_hash
Definition: interface.h:1032
n_left
u32 n_left
Definition: interface_output.c:1078
sw_if_index
u32 sw_if_index
Definition: interface_output.c:403
interface_output_trace_t::data
u8 data[128 - 2 *sizeof(u32)]
Definition: interface_output.c:56
vnet_get_feature_config_index
static_always_inline u32 vnet_get_feature_config_index(u8 arc, u32 sw_if_index)
Definition: feature.h:258
ip6_header_t
Definition: ip6_packet.h:294
ip4.h
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
vnet_main
vnet_main_t vnet_main
Definition: misc.c:43
node
vlib_main_t vlib_node_runtime_t * node
Definition: interface_output.c:392
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
vnet_feature_get_config_main
static_always_inline vnet_feature_config_main_t * vnet_feature_get_config_main(u16 arc)
Definition: feature.h:244
vlib_node_t
Definition: node.h:247
vlib_simple_counter_main_t
A collection of simple counters.
Definition: counter.h:57
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
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
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
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:399
vnet_hw_interface_t::output_node_index
u32 output_node_index
Definition: interface.h:653
icmp46_packet.h
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
vnet_get_config_data
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:123
vnet_set_interface_output_node
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 ...
Definition: interface_output.c:1260
vnet_error_trace_t_::details_valid
i8 details_valid
Definition: interface_output.c:592
word
i64 word
Definition: types.h:111
nexts
u16 nexts[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:718
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
pad
u8 pad[3]
log2 (size of the packing page block)
Definition: bihash_doc.h:61
clib_mask_compare_u32
clib_mask_compare_u32(swif, sw_if_indices, mask, frame->n_vectors)
vnet.h
vlib_node_runtime_t
Definition: node.h:454
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM
#define VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM
Definition: interface.h:559
vlib_trace_buffer
static __clib_warn_unused_result int vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
Definition: trace_funcs.h:153
vnet_error_trace_t_::is_ip6
u8 is_ip6
Definition: interface_output.c:593
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
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
vnet_interface_main_t::output_feature_arc_index
u8 output_feature_arc_index
Definition: interface.h:1042
sw_if_indices
u32 sw_if_indices[VLIB_FRAME_SIZE]
Definition: interface_output.c:1075
ip6.h
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
vnet_interface_pcap_tx_trace
static_always_inline void vnet_interface_pcap_tx_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int sw_if_index_from_buffer)
Definition: interface_output.c:288
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED
node VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED
Definition: interface_output.c:420
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
VNET_INTERFACE_COUNTER_DROP
@ VNET_INTERFACE_COUNTER_DROP
Definition: interface.h:903
used_elts
u64 used_elts[VLIB_FRAME_SIZE/64]
Definition: interface_output.c:1076
vlib_node_t::name
u8 * name
Definition: node.h:253
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
format_white_space
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
vlib_get_next_frame_internal
vlib_frame_t * vlib_get_next_frame_internal(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 allocate_new_next_frame)
Definition: main.c:384
vnet_hw_if_tx_frame_t
Definition: interface.h:622
clib_compress_u32
static_always_inline u32 clib_compress_u32(u32 *dst, u32 *src, u64 *mask, u32 n_elts)
Compare array of 32-bit elemments into destination array based on mask.
Definition: vector_funcs.h:210
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
format_vnet_sw_interface_name
format_function_t format_vnet_sw_interface_name
Definition: interface_funcs.h:453
VNET_ERROR_N_DISPOSITION
@ VNET_ERROR_N_DISPOSITION
Definition: interface_output.c:701
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
vnet_interface_output_runtime_t
Definition: interface_funcs.h:472
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
swif
u32 swif
Definition: interface_output.c:1078
arc_or_subif
int arc_or_subif
Definition: interface_output.c:407
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105