FD.io VPP  v21.10.1-2-g0a485f517
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>
52 
53 typedef struct
54 {
57  u8 data[128 - 2 * sizeof (u32)];
58 }
60 
61 #ifndef CLIB_MARCH_VARIANT
62 u8 *
64 {
65  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
66  vlib_node_t *node = va_arg (*va, vlib_node_t *);
68  vnet_main_t *vnm = vnet_get_main ();
70  u32 indent;
71 
72  if (t->sw_if_index != (u32) ~ 0)
73  {
74  indent = format_get_indent (s);
75 
78  {
79  /* the interface may have been deleted by the time the trace is printed */
80  s = format (s, "sw_if_index: %d ", t->sw_if_index);
81  }
82  else
83  {
85  s =
86  format (s, "%U ", format_vnet_sw_interface_name, vnm, si,
87  t->flags);
88  }
89  s =
90  format (s, "\n%U%U", format_white_space, indent,
91  node->format_buffer ? node->format_buffer : format_hex_bytes,
92  t->data, sizeof (t->data));
93  }
94  return s;
95 }
96 #endif /* CLIB_MARCH_VARIANT */
97 
98 static void
102 {
103  u32 n_left, *from;
104 
105  n_left = n_buffers;
107 
108  while (n_left >= 4)
109  {
110  u32 bi0, bi1;
111  vlib_buffer_t *b0, *b1;
112  interface_output_trace_t *t0, *t1;
113 
114  /* Prefetch next iteration. */
117 
118  bi0 = from[0];
119  bi1 = from[1];
120 
121  b0 = vlib_get_buffer (vm, bi0);
122  b1 = vlib_get_buffer (vm, bi1);
123 
124  if (b0->flags & VLIB_BUFFER_IS_TRACED)
125  {
126  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
127  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
128  t0->flags = b0->flags;
130  sizeof (t0->data));
131  }
132  if (b1->flags & VLIB_BUFFER_IS_TRACED)
133  {
134  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
135  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX];
136  t1->flags = b1->flags;
138  sizeof (t1->data));
139  }
140  from += 2;
141  n_left -= 2;
142  }
143 
144  while (n_left >= 1)
145  {
146  u32 bi0;
147  vlib_buffer_t *b0;
149 
150  bi0 = from[0];
151 
152  b0 = vlib_get_buffer (vm, bi0);
153 
154  if (b0->flags & VLIB_BUFFER_IS_TRACED)
155  {
156  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
157  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
158  t0->flags = b0->flags;
160  sizeof (t0->data));
161  }
162  from += 1;
163  n_left -= 1;
164  }
165 }
166 
169 {
170  vnet_calc_checksums_inline (vm, b, b->flags & VNET_BUFFER_F_IS_IP4,
171  b->flags & VNET_BUFFER_F_IS_IP6);
172 }
173 
179  int arc_or_subif)
180 {
181  u32 n_bytes = 0;
182  u32 n_bytes0, n_bytes1, n_bytes2, n_bytes3;
183  u32 ti = vm->thread_index;
184 
185  while (n_left >= 8)
186  {
187  u32 or_flags;
188 
189  /* Prefetch next iteration. */
190  vlib_prefetch_buffer_header (b[4], LOAD);
191  vlib_prefetch_buffer_header (b[5], LOAD);
192  vlib_prefetch_buffer_header (b[6], LOAD);
193  vlib_prefetch_buffer_header (b[7], LOAD);
194 
195  if (do_tx_offloads)
196  or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags;
197 
198  /* Be grumpy about zero length buffers for benefit of
199  driver tx function. */
200  ASSERT (b[0]->current_length > 0);
201  ASSERT (b[1]->current_length > 0);
202  ASSERT (b[2]->current_length > 0);
203  ASSERT (b[3]->current_length > 0);
204 
205  n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);
206  n_bytes += n_bytes1 = vlib_buffer_length_in_chain (vm, b[1]);
207  n_bytes += n_bytes2 = vlib_buffer_length_in_chain (vm, b[2]);
208  n_bytes += n_bytes3 = vlib_buffer_length_in_chain (vm, b[3]);
209 
210  if (arc_or_subif)
211  {
212  u32 tx_swif0, tx_swif1, tx_swif2, tx_swif3;
213  tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
214  tx_swif1 = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
215  tx_swif2 = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
216  tx_swif3 = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
217 
218  /* update vlan subif tx counts, if required */
219  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
220  vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
221 
222  if (PREDICT_FALSE (tx_swif1 != sw_if_index))
223  vlib_increment_combined_counter (ccm, ti, tx_swif1, 1, n_bytes1);
224 
225  if (PREDICT_FALSE (tx_swif2 != sw_if_index))
226  vlib_increment_combined_counter (ccm, ti, tx_swif2, 1, n_bytes2);
227 
228  if (PREDICT_FALSE (tx_swif3 != sw_if_index))
229  vlib_increment_combined_counter (ccm, ti, tx_swif3, 1, n_bytes3);
230 
231  if (PREDICT_FALSE (config_index != ~0))
232  {
233  vnet_buffer (b[0])->feature_arc_index = arc;
235  vnet_buffer (b[1])->feature_arc_index = arc;
237  vnet_buffer (b[2])->feature_arc_index = arc;
239  vnet_buffer (b[3])->feature_arc_index = arc;
241  }
242  }
243 
244  if (do_tx_offloads && (or_flags & VNET_BUFFER_F_OFFLOAD))
245  {
250  }
251 
252  n_left -= 4;
253  b += 4;
254  }
255 
256  while (n_left)
257  {
258  /* Be grumpy about zero length buffers for benefit of
259  driver tx function. */
260  ASSERT (b[0]->current_length > 0);
261 
262  n_bytes += n_bytes0 = vlib_buffer_length_in_chain (vm, b[0]);
263 
264  if (arc_or_subif)
265  {
266  u32 tx_swif0 = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
267 
268  if (PREDICT_FALSE (config_index != ~0))
269  {
270  vnet_buffer (b[0])->feature_arc_index = arc;
272  }
273 
274  if (PREDICT_FALSE (tx_swif0 != sw_if_index))
275  vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
276  }
277 
278  if (do_tx_offloads)
280 
281  n_left -= 1;
282  b += 1;
283  }
284 
285  return n_bytes;
286 }
287 
290  vlib_frame_t *frame, int in_interface_ouput)
291 {
292  vnet_main_t *vnm = vnet_get_main ();
293  u32 n_left_from, *from;
294  u32 sw_if_index = ~0, hw_if_index = ~0;
295  vnet_pcap_t *pp = &vnm->pcap;
296 
297  if (PREDICT_TRUE (pp->pcap_tx_enable == 0))
298  return;
299 
300  if (in_interface_ouput)
301  {
302  /* interface-output is called right before interface-output-template.
303  * We only want to capture packets here if there is a per-interface
304  * filter, in case it matches the sub-interface sw_if_index.
305  * If there is no per-interface filter configured, let the
306  * interface-output-template node deal with it */
307  if (pp->pcap_sw_if_index == 0)
308  return;
309  }
310  else
311  {
312  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
314  }
315 
316  n_left_from = frame->n_vectors;
318 
319  while (n_left_from > 0)
320  {
321  u32 bi0 = from[0];
322  vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
323  from++;
324  n_left_from--;
325 
326  if (in_interface_ouput)
327  {
328  const u32 sii = vnet_buffer (b0)->sw_if_index[VLIB_TX];
329  if (PREDICT_FALSE (sii != sw_if_index))
330  {
331  const vnet_hw_interface_t *hi =
332  vnet_get_sup_hw_interface (vnm, sii);
333  hw_if_index = hi->sw_if_index;
334  sw_if_index = sii;
335  }
336  if (hw_if_index == sw_if_index)
337  continue; /* defer to interface-output-template */
338  }
339 
340  if (vnet_is_packet_pcaped (pp, b0, sw_if_index))
341  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
342  }
343 }
344 
348 {
349  if (r)
351 }
352 
356 {
359  u32 n_free, n_copy, *to;
361  vlib_frame_t *f;
362 
364 
367 
370 
371  if (f->n_vectors > 0 && (r == 0 || tf->queue_id == r->frame.queue_id))
372  {
373  /* append current next frame */
375  n_copy = clib_min (n_vectors, n_free);
376  n_vectors -= n_copy;
378  to += f->n_vectors;
379  }
380  else
381  {
382  if (f->n_vectors > 0)
383  {
384  /* current frame doesn't fit - grab empty one */
387  }
388 
389  /* empty frame - store scalar data */
393  n_copy = n_vectors;
394  n_vectors = 0;
395  }
396 
397  vlib_buffer_copy_indices (to, from, n_copy);
399 
400  if (n_vectors == 0)
401  return;
402 
403  /* we have more indices to store, take empty frame */
404  from += n_copy;
409 }
410 
413 {
414  vnet_main_t *vnm = vnet_get_main ();
419  vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
421  u32 n_bytes, n_buffers = frame->n_vectors;
427  int arc_or_subif = 0;
428  int do_tx_offloads = 0;
430 
431  if (node->flags & VLIB_NODE_FLAG_TRACE)
433 
435 
436  if (rt->is_deleted)
437  return vlib_error_drop_buffers (
438  vm, node, from,
441 
442  vnet_interface_pcap_tx_trace (vm, node, frame, 0 /* in_interface_ouput */);
443 
445 
448 
451  {
453 
457 
458  return vlib_error_drop_buffers (
459  vm, node, from,
460  /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP,
462  }
463 
464  /* interface-output feature arc handling */
466  {
471  arc_or_subif = 1;
472  }
474  arc_or_subif = 1;
475 
477 
479  do_tx_offloads = 1;
480 
481  if (do_tx_offloads == 0 && arc_or_subif == 0)
484  else if (do_tx_offloads == 0 && arc_or_subif == 1)
487  else if (do_tx_offloads == 1 && arc_or_subif == 0)
490  else
493 
496  {
497  enqueu_to_tx_node (vm, node, hi, from, frame->n_vectors);
498  }
499  else
500  {
502  frame->n_vectors);
503  }
504 
505  /* Update main interface stats. */
507  return n_buffers;
508 }
509 
511  .name = "interface-output-template",
512  .vector_size = sizeof (u32),
513 };
514 
515 /* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
518  node,
520 {
521  vnet_main_t *vnm = vnet_get_main ();
522  u32 n_left_to_next, *from, *to_next;
524 
525  vnet_interface_pcap_tx_trace (vm, node, frame, 1 /* in_interface_ouput */);
526 
527  n_left_from = frame->n_vectors;
528 
530  next_index = node->cached_next_index;
531 
532  while (n_left_from > 0)
533  {
534  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
535 
536  while (n_left_from >= 4 && n_left_to_next >= 2)
537  {
538  u32 bi0, bi1, next0, next1;
539  vlib_buffer_t *b0, *b1;
540  vnet_hw_interface_t *hi0, *hi1;
541 
542  /* Prefetch next iteration. */
545 
546  bi0 = from[0];
547  bi1 = from[1];
548  to_next[0] = bi0;
549  to_next[1] = bi1;
550  from += 2;
551  to_next += 2;
552  n_left_to_next -= 2;
553  n_left_from -= 2;
554 
555  b0 = vlib_get_buffer (vm, bi0);
556  b1 = vlib_get_buffer (vm, bi1);
557 
558  hi0 =
561  [VLIB_TX]);
562  hi1 =
565  [VLIB_TX]);
566 
567  next0 = hi0->output_node_next_index;
568  next1 = hi1->output_node_next_index;
569 
571  n_left_to_next, bi0, bi1, next0,
572  next1);
573  }
574 
575  while (n_left_from > 0 && n_left_to_next > 0)
576  {
577  u32 bi0, next0;
578  vlib_buffer_t *b0;
579  vnet_hw_interface_t *hi0;
580 
581  bi0 = from[0];
582  to_next[0] = bi0;
583  from += 1;
584  to_next += 1;
585  n_left_to_next -= 1;
586  n_left_from -= 1;
587 
588  b0 = vlib_get_buffer (vm, bi0);
589 
590  hi0 =
593  [VLIB_TX]);
594 
595  next0 = hi0->output_node_next_index;
596 
598  n_left_to_next, bi0, next0);
599  }
600 
601  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
602  }
603 
604  return frame->n_vectors;
605 }
606 
607 typedef struct vnet_error_trace_t_
608 {
612  u8 pad[2];
614  ip46_address_t src, dst;
616 
617 static u8 *
618 format_vnet_error_trace (u8 * s, va_list * va)
619 {
620  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
621  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
622  vnet_error_trace_t *t = va_arg (*va, vnet_error_trace_t *);
623 
624  /* Normal, non-catchup trace */
625  if (t->details_valid == 0)
626  {
627  s = format (s, "rx:%U", format_vnet_sw_if_index_name,
628  vnet_get_main (), t->sw_if_index);
629  }
630  else if (t->details_valid == 1)
631  {
632  /* The trace capture code didn't understant the mactype */
633  s = format (s, "mactype 0x%4x (not decoded)", t->mactype);
634  }
635  else if (t->details_valid == 2)
636  {
637  /* Dump the src/dst addresses */
638  if (t->is_ip6 == 0)
639  s = format (s, "IP4: %U -> %U",
640  format_ip4_address, &t->src.ip4,
641  format_ip4_address, &t->dst.ip4);
642  else
643  s = format (s, "IP6: %U -> %U",
644  format_ip6_address, &t->src.ip6,
645  format_ip6_address, &t->dst.ip6);
646  }
647  return s;
648 }
649 
650 static void
653 {
654  u32 n_left, *buffers;
655 
656  buffers = vlib_frame_vector_args (frame);
657  n_left = frame->n_vectors;
658 
659  while (n_left >= 4)
660  {
661  u32 bi0, bi1;
662  vlib_buffer_t *b0, *b1;
663  vnet_error_trace_t *t0, *t1;
664 
665  /* Prefetch next iteration. */
666  vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
667  vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);
668 
669  bi0 = buffers[0];
670  bi1 = buffers[1];
671 
672  b0 = vlib_get_buffer (vm, bi0);
673  b1 = vlib_get_buffer (vm, bi1);
674 
675  if (b0->flags & VLIB_BUFFER_IS_TRACED)
676  {
677  t0 = vlib_add_trace (vm, node, b0,
679  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
680  t0->details_valid = 0;
681  }
682  if (b1->flags & VLIB_BUFFER_IS_TRACED)
683  {
684  t1 = vlib_add_trace (vm, node, b1,
686  t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX];
687  t1->details_valid = 0;
688  }
689  buffers += 2;
690  n_left -= 2;
691  }
692 
693  while (n_left >= 1)
694  {
695  u32 bi0;
696  vlib_buffer_t *b0;
697  vnet_error_trace_t *t0;
698 
699  bi0 = buffers[0];
700 
701  b0 = vlib_get_buffer (vm, bi0);
702 
703  if (b0->flags & VLIB_BUFFER_IS_TRACED)
704  {
705  t0 = vlib_add_trace (vm, node, b0,
707  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
708  t0->details_valid = 0;
709  }
710  buffers += 1;
711  n_left -= 1;
712  }
713 }
714 
715 typedef enum
716 {
721 
722 static void
725 {
726  /* Can we safely rewind the buffer? If not, fagedaboudit */
727  if (b->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
728  {
730  ip4_header_t *ip4;
731  ip6_header_t *ip6;
732  ethernet_header_t *eh;
733  i16 delta;
734 
735  t = vlib_add_trace (vm, node, b, sizeof (*t));
736  delta = vnet_buffer (b)->l2_hdr_offset - b->current_data;
737  vlib_buffer_advance (b, delta);
738 
739  eh = vlib_buffer_get_current (b);
740  /* Save mactype */
741  t->mactype = clib_net_to_host_u16 (eh->type);
742  t->details_valid = 1;
743  switch (t->mactype)
744  {
745  case ETHERNET_TYPE_IP4:
746  ip4 = (void *) (eh + 1);
747  t->details_valid = 2;
748  t->is_ip6 = 0;
749  t->src.ip4.as_u32 = ip4->src_address.as_u32;
750  t->dst.ip4.as_u32 = ip4->dst_address.as_u32;
751  break;
752 
753  case ETHERNET_TYPE_IP6:
754  ip6 = (void *) (eh + 1);
755  t->details_valid = 2;
756  t->is_ip6 = 1;
757  clib_memcpy_fast (t->src.as_u8, ip6->src_address.as_u8,
758  sizeof (ip6_address_t));
759  clib_memcpy_fast (t->dst.as_u8, ip6->dst_address.as_u8,
760  sizeof (ip6_address_t));
761  break;
762 
763  default:
764  /* Dunno, do nothing, leave details_valid alone */
765  break;
766  }
767  /* Restore current data (probably unnecessary) */
768  vlib_buffer_advance (b, -delta);
769  }
770 }
771 
776  vnet_error_disposition_t disposition)
777 {
783  u32 n_trace;
784  vnet_main_t *vnm;
785 
786  vnm = vnet_get_main ();
789  n_left = frame->n_vectors;
790  b = bufs;
792 
794 
795  /* "trace add error-drop NNN?" */
796  if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node))))
797  {
798  /* If pkts aren't otherwise traced... */
799  if ((node->flags & VLIB_NODE_FLAG_TRACE) == 0)
800  {
801  /* Trace them from here */
802  node->flags |= VLIB_NODE_FLAG_TRACE;
803  while (n_trace && n_left)
804  {
805  if (PREDICT_TRUE
806  (vlib_trace_buffer (vm, node, 0 /* next_index */ , b[0],
807  0 /* follow chain */ )))
808  {
809  /*
810  * Here we have a wireshark dissector problem.
811  * Packets may be well-formed, or not. We
812  * must not blow chunks in any case.
813  *
814  * Try to produce trace records which will help
815  * folks understand what's going on.
816  */
817  drop_catchup_trace (vm, node, b[0]);
818  n_trace--;
819  }
820  n_left--;
821  b++;
822  }
823  }
824 
825  vlib_set_trace_count (vm, node, n_trace);
826  b = bufs;
827  n_left = frame->n_vectors;
828  }
829 
830  if (node->flags & VLIB_NODE_FLAG_TRACE)
832 
833  /* All going to drop regardless, this is just a counting exercise */
834  clib_memset (nexts, 0, sizeof (nexts));
835 
837  (disposition == VNET_ERROR_DISPOSITION_PUNT
840 
841  /* collect the array of interfaces first ... */
842  while (n_left >= 4)
843  {
844  if (n_left >= 12)
845  {
846  /* Prefetch 8 ahead - there's not much going on in each iteration */
847  vlib_prefetch_buffer_header (b[4], LOAD);
848  vlib_prefetch_buffer_header (b[5], LOAD);
849  vlib_prefetch_buffer_header (b[6], LOAD);
850  vlib_prefetch_buffer_header (b[7], LOAD);
851  }
852  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
853  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
854  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
855  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
856 
857  sw_if_index += 4;
858  n_left -= 4;
859  b += 4;
860  }
861  while (n_left)
862  {
863  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
864 
865  sw_if_index += 1;
866  n_left -= 1;
867  b += 1;
868  }
869 
870  /* ... then count against them in blocks */
871  n_left = frame->n_vectors;
872 
873  while (n_left)
874  {
875  vnet_sw_interface_t *sw_if0;
876  u16 off, count;
877 
878  off = frame->n_vectors - n_left;
879 
881 
883  n_left -= count;
884 
886 
887  /* Increment super-interface drop/punt counters for
888  sub-interfaces. */
889  sw_if0 = vnet_get_sw_interface (vnm, sw_if_index[0]);
890  if (sw_if0->sup_sw_if_index != sw_if_index[0])
892  (cm, thread_index, sw_if0->sup_sw_if_index, count);
893  }
894 
896 
897  return frame->n_vectors;
898 }
899 
900 static inline void
903  vnet_pcap_t * pp, vlib_frame_t * f)
904 {
905  u32 *from;
906  u32 n_left = f->n_vectors;
907  vlib_buffer_t *b0, *p1;
908  u32 bi0;
909  i16 save_current_data;
910  u16 save_current_length;
912 
914 
915  while (n_left > 0)
916  {
917  if (PREDICT_TRUE (n_left > 1))
918  {
919  p1 = vlib_get_buffer (vm, from[1]);
920  vlib_prefetch_buffer_header (p1, LOAD);
921  }
922 
923  bi0 = from[0];
924  b0 = vlib_get_buffer (vm, bi0);
925  from++;
926  n_left--;
927 
928  /* See if we're pointedly ignoring this specific error */
931  continue;
932 
933  if (!vnet_is_packet_pcaped (pp, b0, ~0))
934  continue; /* not matching, skip */
935 
936  /* Trace all drops, or drops received on a specific interface */
937  save_current_data = b0->current_data;
938  save_current_length = b0->current_length;
939 
940  /*
941  * Typically, we'll need to rewind the buffer
942  * if l2_hdr_offset is valid, make sure to rewind to the start of
943  * the L2 header. This may not be the buffer start in case we pop-ed
944  * vlan tags.
945  * Otherwise, rewind to buffer start and hope for the best.
946  */
947  if (b0->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
948  {
949  if (b0->current_data > vnet_buffer (b0)->l2_hdr_offset)
950  vlib_buffer_advance (b0, vnet_buffer (b0)->l2_hdr_offset -
951  b0->current_data);
952  }
953  else if (b0->current_data > 0)
954  {
956  }
957 
958  {
959  vlib_buffer_t *last = b0;
960  u32 error_node_index;
961  int drop_string_len;
962  vlib_node_t *n;
963  /* Length of the error string */
964  int error_string_len =
965  clib_strnlen (em->counters_heap[b0->error].name, 128);
966 
967  /* Dig up the drop node */
968  error_node_index = vm->node_main.node_by_error[b0->error];
969  n = vlib_get_node (vm, error_node_index);
970 
971  /* Length of full drop string, w/ "nodename: " prepended */
972  drop_string_len = error_string_len + vec_len (n->name) + 2;
973 
974  /* Find the last buffer in the chain */
975  while (last->flags & VLIB_BUFFER_NEXT_PRESENT)
976  last = vlib_get_buffer (vm, last->next_buffer);
977 
978  /*
979  * Append <nodename>: <error-string> to the capture,
980  * only if we can do that without allocating a new buffer.
981  */
982  if (PREDICT_TRUE ((last->current_data + last->current_length) <
983  (VLIB_BUFFER_DEFAULT_DATA_SIZE - drop_string_len)))
984  {
985  clib_memcpy_fast (last->data + last->current_data +
986  last->current_length,
987  n->name, vec_len (n->name));
988  clib_memcpy_fast (last->data + last->current_data +
989  last->current_length + vec_len (n->name),
990  ": ", 2);
991  clib_memcpy_fast (last->data + last->current_data +
992  last->current_length + vec_len (n->name) + 2,
993  em->counters_heap[b0->error].name,
994  error_string_len);
995  last->current_length += drop_string_len;
996  b0->flags &= ~(VLIB_BUFFER_TOTAL_LENGTH_VALID);
997  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
998  last->current_length -= drop_string_len;
999  b0->current_data = save_current_data;
1000  b0->current_length = save_current_length;
1001  continue;
1002  }
1003  }
1004 
1005  /*
1006  * Didn't have space in the last buffer, here's the dropped
1007  * packet as-is
1008  */
1009  pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt);
1010 
1011  b0->current_data = save_current_data;
1012  b0->current_length = save_current_length;
1013  }
1014 }
1015 
1016 #ifndef CLIB_MARCH_VARIANT
1017 void
1018 vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add)
1019 {
1021 
1022  if (im->pcap_drop_filter_hash == 0)
1023  im->pcap_drop_filter_hash = hash_create (0, sizeof (uword));
1024 
1025  if (is_add)
1026  hash_set (im->pcap_drop_filter_hash, error_index, 1);
1027  else
1028  hash_unset (im->pcap_drop_filter_hash, error_index);
1029 }
1030 #endif /* CLIB_MARCH_VARIANT */
1031 
1034  vlib_frame_t * frame)
1035 {
1036  vnet_main_t *vnm = vnet_get_main ();
1038  vnet_pcap_t *pp = &vnm->pcap;
1039 
1040  if (PREDICT_FALSE (pp->pcap_drop_enable))
1041  pcap_drop_trace (vm, im, pp, frame);
1042 
1044 }
1045 
1048  vlib_frame_t * frame)
1049 {
1051 }
1052 
1053 /* *INDENT-OFF* */
1055  .name = "error-drop",
1056  .vector_size = sizeof (u32),
1057  .format_trace = format_vnet_error_trace,
1059  .n_next_nodes = 1,
1060  .next_nodes = {
1061  [0] = "drop",
1062  },
1063 };
1064 /* *INDENT-ON* */
1065 
1066 /* *INDENT-OFF* */
1068  .name = "error-punt",
1069  .vector_size = sizeof (u32),
1070  .format_trace = format_vnet_error_trace,
1072  .n_next_nodes = 1,
1073  .next_nodes = {
1074  [0] = "punt",
1075  },
1076 };
1077 /* *INDENT-ON* */
1078 
1080  .name = "interface-output",
1081  .vector_size = sizeof (u32),
1082 };
1083 
1086 {
1087  vnet_main_t *vnm = vnet_get_main ();
1097  u16 next_index;
1099 
1101  n_left = frame->n_vectors;
1103 
1104  while (n_left >= 8)
1105  {
1106  vlib_prefetch_buffer_header (b[4], LOAD);
1107  vlib_prefetch_buffer_header (b[5], LOAD);
1108  vlib_prefetch_buffer_header (b[6], LOAD);
1109  vlib_prefetch_buffer_header (b[7], LOAD);
1110  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
1111  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
1112  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
1113  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
1114 
1115  b += 4;
1116  sw_if_index += 4;
1117  n_left -= 4;
1118  }
1119 
1120  while (n_left)
1121  {
1122  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
1123  b++;
1124  sw_if_index++;
1125  n_left--;
1126  }
1127 
1128  n_left = frame->n_vectors;
1129  swif = sw_if_indices[0];
1130  off = 0;
1131 
1132  /* a bit ugly but it allows us to reuse stack space for temporary store
1133  * which may also improve memory latency */
1134  tmp = (u32 *) bufs;
1135 
1136 more:
1143 
1144  if (f->n_vectors > 0 && (r == 0 || r->frame.queue_id == tf->queue_id))
1145  {
1146  /* append frame */
1148  if (n_free >= f->n_vectors)
1150  else
1151  to = tmp;
1152  }
1153  else
1154  {
1155  if (f->n_vectors > 0)
1156  {
1157  /* current frame doesn't fit - grab empty one */
1160  }
1161 
1162  /* empty frame - store scalar data */
1166  }
1167 
1168  /* compare and compress based on comparison mask */
1170  n_comp = clib_compress_u32 (to, from, mask, frame->n_vectors);
1171 
1172  if (tmp != to)
1173  {
1174  /* indices already written to frame, just close it */
1176  }
1177  else if (n_free >= n_comp)
1178  {
1179  /* enough space in the existing frame */
1183  }
1184  else
1185  {
1186  /* full frame */
1190 
1191  /* second frame */
1199  }
1200 
1201  n_left -= n_comp;
1202  if (n_left)
1203  {
1204  /* store comparison mask so we can find next unused element */
1205  for (int i = 0; i < ARRAY_LEN (used_elts); i++)
1206  used_elts[i] |= mask[i];
1207 
1208  /* fine first unused sw_if_index by scanning trough used_elts bitmap */
1209  while (PREDICT_FALSE (used_elts[off] == ~0))
1210  off++;
1211 
1212  swif =
1214  goto more;
1215  }
1216 
1217  return frame->n_vectors;
1218 }
1219 
1221  .name = "interface-output-arc-end",
1222  .vector_size = sizeof (u32),
1223  .n_next_nodes = 1,
1224  .next_nodes = {
1225  [0] = "error-drop",
1226  },
1227 };
1228 
1229 VNET_FEATURE_ARC_INIT (interface_output, static) = {
1230  .arc_name = "interface-output",
1231  .start_nodes = VNET_FEATURES (0),
1232  .last_in_arc = "interface-output-arc-end",
1234 };
1235 
1236 VNET_FEATURE_INIT (span_tx, static) = {
1237  .arc_name = "interface-output",
1238  .node_name = "span-output",
1239  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
1240 };
1241 
1242 VNET_FEATURE_INIT (ipsec_if_tx, static) = {
1243  .arc_name = "interface-output",
1244  .node_name = "ipsec-if-output",
1245  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
1246 };
1247 
1248 VNET_FEATURE_INIT (interface_output_arc_end, static) = {
1249  .arc_name = "interface-output",
1250  .node_name = "interface-output-arc-end",
1251  .runs_before = 0,
1252 };
1253 
1254 #ifndef CLIB_MARCH_VARIANT
1255 clib_error_t *
1257  u32 hw_if_index,
1258  u32 is_create)
1259 {
1260  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1261  u32 next_index;
1262 
1263  if (hi->output_node_index == 0)
1264  return 0;
1265 
1270 
1271  return 0;
1272 }
1273 
1276 
1277 void
1279  u32 hw_if_index, u32 node_index)
1280 {
1281  ASSERT (node_index);
1282  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1287 }
1288 #endif /* CLIB_MARCH_VARIANT */
1289 
1290 /*
1291  * fd.io coding-style-patch-verification: ON
1292  *
1293  * Local Variables:
1294  * eval: (c-set-style "gnu")
1295  * End:
1296  */
to
u32 * to
Definition: interface_output.c:1096
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:1018
tmp
u32 * tmp
Definition: interface_output.c:1096
vlib_error_main_t
Definition: error.h:61
vnet_error_trace_t_::src
ip46_address_t src
Definition: interface_output.c:614
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:618
VNET_ERROR_DISPOSITION_PUNT
@ VNET_ERROR_DISPOSITION_PUNT
Definition: interface_output.c:718
vnet_feature_config_main_t_
Definition: feature.h:80
im
vnet_interface_main_t * im
Definition: interface_output.c:415
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:1217
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:63
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
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
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:1192
count_trailing_zeros
#define count_trailing_zeros(x)
Definition: clib.h:161
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
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:723
compress.h
vnet_sw_interface_t
Definition: interface.h:869
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:1096
interface_output_trace_t::flags
u32 flags
Definition: interface_output.c:56
vnet_error_disposition_t
vnet_error_disposition_t
Definition: interface_output.c:715
vnet_hw_interface_t::caps
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
n_buffers
u32 n_buffers
Definition: interface_output.c:421
vnet_error_trace_t_::dst
ip46_address_t dst
Definition: interface_output.c:614
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:919
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:1098
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:773
vnet_hw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:670
VNET_INTERFACE_OUTPUT_NEXT_DROP
VNET_INTERFACE_OUTPUT_NEXT_DROP
Definition: interface_output.c:439
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:417
vm
vlib_main_t * vm
Definition: interface_output.c:412
VNET_INTERFACE_OUTPUT_NEXT_TX
@ VNET_INTERFACE_OUTPUT_NEXT_TX
Definition: interface_funcs.h:492
vnet_interface_main_t
Definition: interface.h:990
vnet_interface_output_node
vlib_node_registration_t vnet_interface_output_node
(constructor) VLIB_REGISTER_NODE (vnet_interface_output_node)
Definition: interface_output.c:510
vlib_main_t::error_main
vlib_error_main_t error_main
Definition: main.h:179
hash_elts
static uword hash_elts(void *v)
Definition: hash.h:118
u16
unsigned short u16
Definition: types.h:57
vnet_interface_output_runtime_t::sw_if_index
u32 sw_if_index
Definition: interface_funcs.h:478
vlib_main_t::node_main
vlib_node_main_t node_main
Definition: main.h:173
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:844
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:413
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:175
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:440
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:1023
vnet_error_trace_t_::pad
u8 pad[2]
Definition: interface_output.c:612
b
vlib_buffer_t ** b
Definition: interface_output.c:1092
vnet_pcap_t::pcap_sw_if_index
u32 pcap_sw_if_index
Definition: vnet.h:70
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:420
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:416
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:526
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:1089
vlib_frame_t
Definition: node.h:372
do_tx_offloads
int do_tx_offloads
Definition: interface_output.c:428
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:651
ip4_header_t
Definition: ip4_packet.h:87
vlib_error_desc_t::name
char * name
Definition: error.h:56
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
vnet_sw_interface_t::flags
vnet_sw_interface_flags_t flags
Definition: interface.h:873
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
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:354
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:425
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:373
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
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 in_interface_ouput)
Definition: interface_output.c:289
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:717
next_index
u32 next_index
Definition: interface_output.c:424
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
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:1256
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:1054
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:55
hash_get
#define hash_get(h, key)
Definition: hash.h:249
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:53
vnet_error_trace_t_::sw_if_index
u32 sw_if_index
Definition: interface_output.c:609
vnet_interface_output_runtime_t::is_deleted
u32 is_deleted
Definition: interface_funcs.h:480
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:346
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:901
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
ethernet_header_t
Definition: packet.h:52
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:215
interface_punt
vlib_node_registration_t interface_punt
(constructor) VLIB_REGISTER_NODE (interface_punt)
Definition: interface_output.c:1067
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
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN
@ VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN
Definition: interface_funcs.h:506
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:594
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:429
clib_min
#define clib_min(x, y)
Definition: clib.h:342
clib_compress_u32
static_always_inline u32 clib_compress_u32(u32 *dst, u32 *src, u64 *mask, u32 n_elts)
Compress array of 32-bit elemments into destination array based on mask.
Definition: compress.h:117
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:1024
vnet_interface_main_t::sw_interfaces
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:1015
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:1047
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:168
data
u8 data[128]
Definition: ipsec_types.api:95
tf
vnet_hw_if_tx_frame_t * tf
Definition: interface_output.c:1091
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:1220
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:426
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:1079
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:905
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:881
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:613
vnet_error_trace_t_
Definition: interface_output.c:607
mask_compare.h
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:458
i8
signed char i8
Definition: types.h:45
VNET_INTERFACE_COUNTER_TX_ERROR
@ VNET_INTERFACE_COUNTER_TX_ERROR
Definition: interface.h:911
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:1096
config_index
u32 config_index
Definition: interface_output.c:422
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:1096
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:421
mask
u64 mask[VLIB_FRAME_SIZE/64]
Definition: interface_output.c:1095
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:99
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:418
vnet_interface_main_t::pcap_drop_filter_hash
uword * pcap_drop_filter_hash
Definition: interface.h:1033
n_left
u32 n_left
Definition: interface_output.c:1096
sw_if_index
u32 sw_if_index
Definition: interface_output.c:423
interface_output_trace_t::data
u8 data[128 - 2 *sizeof(u32)]
Definition: interface_output.c:57
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
vnet_main
vnet_main_t vnet_main
Definition: misc.c:43
node
vlib_main_t vlib_node_runtime_t * node
Definition: interface_output.c:412
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:419
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:1278
i
int i
Definition: flowhash_template.h:376
vnet_error_trace_t_::details_valid
i8 details_valid
Definition: interface_output.c:610
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:611
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
hash_create
#define hash_create(elts, value_bytes)
Definition: hash.h:695
vnet_interface_main_t::output_feature_arc_index
u8 output_feature_arc_index
Definition: interface.h:1043
sw_if_indices
u32 sw_if_indices[VLIB_FRAME_SIZE]
Definition: interface_output.c:1093
ip6.h
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED
node VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED
Definition: interface_output.c:440
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
VNET_INTERFACE_COUNTER_DROP
@ VNET_INTERFACE_COUNTER_DROP
Definition: interface.h:904
used_elts
u64 used_elts[VLIB_FRAME_SIZE/64]
Definition: interface_output.c:1094
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
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:456
VNET_ERROR_N_DISPOSITION
@ VNET_ERROR_N_DISPOSITION
Definition: interface_output.c:719
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
vnet_interface_output_runtime_t
Definition: interface_funcs.h:475
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
swif
u32 swif
Definition: interface_output.c:1096
arc_or_subif
int arc_or_subif
Definition: interface_output.c:427
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105