FD.io VPP  v17.01-9-ge7dcee4
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * node.c - skeleton vpp engine plug-in dual-loop node skeleton
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vnet/pg/pg.h>
20 #include <vppinfra/error.h>
21 #include <flowperpkt/flowperpkt.h>
22 
23 /**
24  * @file flow record generator graph node
25  */
26 
27 typedef struct
28 {
29  /** interface handle */
34  /** ToS bits */
36  /** packet timestamp */
38  /** size of the buffer */
41 
42 /* packet trace format function */
43 static u8 *
44 format_flowperpkt_trace (u8 * s, va_list * args)
45 {
46  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
47  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
48  flowperpkt_trace_t *t = va_arg (*args, flowperpkt_trace_t *);
49 
50  s = format (s,
51  "FLOWPERPKT: rx_sw_if_index %d, tx_sw_if_index %d, src %U dst %U tos %0x2, timestamp %lld, size %d",
55  t->tos, t->timestamp, t->buffer_size);
56  return s;
57 }
58 
60 
61 #define foreach_flowperpkt_error \
62 _(SWAPPED, "Mac swap packets processed")
63 
64 typedef enum
65 {
66 #define _(sym,str) FLOWPERPKT_ERROR_##sym,
68 #undef _
71 
72 static char *flowperpkt_error_strings[] = {
73 #define _(sym,string) string,
75 #undef _
76 };
77 
78 typedef enum
79 {
83 
84 /**
85  * @brief add an entry to the flow record under construction
86  * @param vm vlib_main_t * current worker thread main structure pointer
87  * @param fm flowperpkt_main_t * flow-per-packet main structure pointer
88  * @param sw_if_index u32 interface handle
89  * @param tos u8 ToS bits from the packet
90  * @param timestamp u64 timestamp, nanoseconds since 1/1/70
91  * @param length u16 ip length of the packet
92  * @param do_flush int 1 = flush all cached records, 0 = construct a record
93  */
94 
95 static inline void
97  flowperpkt_main_t * fm,
98  u32 rx_sw_if_index, u32 tx_sw_if_index,
99  u32 src_address, u32 dst_address,
100  u8 tos, u64 timestamp, u16 length, int do_flush)
101 {
102  u32 my_cpu_number = vm->cpu_index;
104  ip4_header_t *ip;
105  udp_header_t *udp;
109  vlib_frame_t *f;
110  vlib_buffer_t *b0;
111  u16 offset;
112  u32 bi0;
114 
115  /* Find or allocate a buffer */
116  b0 = fm->buffers_per_worker[my_cpu_number];
117 
118  /* Need to allocate a buffer? */
119  if (PREDICT_FALSE (b0 == 0))
120  {
121  /* Nothing to flush */
122  if (do_flush)
123  return;
124 
125  /* $$$$ drop counter? */
126  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
127  return;
128 
129  /* Initialize the buffer */
130  b0 = fm->buffers_per_worker[my_cpu_number] = vlib_get_buffer (vm, bi0);
131  fl =
135  offset = 0;
136  }
137  else
138  {
139  /* use the current buffer */
140  bi0 = vlib_get_buffer_index (vm, b0);
141  offset = fm->next_record_offset_per_worker[my_cpu_number];
142  }
143 
144  /* Find or allocate a frame */
145  f = fm->frames_per_worker[my_cpu_number];
146  if (PREDICT_FALSE (f == 0))
147  {
148  u32 *to_next;
149  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
150  fm->frames_per_worker[my_cpu_number] = f;
151 
152  /* Enqueue the buffer */
153  to_next = vlib_frame_vector_args (f);
154  to_next[0] = bi0;
155  f->n_vectors = 1;
156  }
157 
158  /* Fresh packet, construct header */
159  if (PREDICT_FALSE (offset == 0))
160  {
161  flow_report_stream_t *stream;
162 
163  stream = &frm->streams[0];
164 
165  b0->current_data = 0;
166  b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
167  sizeof (*s);
169  vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
170  vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
171 
172  tp = vlib_buffer_get_current (b0);
173  ip = (ip4_header_t *) & tp->ip4;
174  udp = (udp_header_t *) (ip + 1);
175  h = (ipfix_message_header_t *) (udp + 1);
176  s = (ipfix_set_header_t *) (h + 1);
177 
178  ip->ip_version_and_header_length = 0x45;
179  ip->ttl = 254;
180  ip->protocol = IP_PROTOCOL_UDP;
184  udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix);
185  udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix);
186  udp->checksum = 0;
187 
188  /* FIXUP: message header export_time */
189  h->export_time = (u32)
190  (((f64) frm->unix_time_0) +
191  (vlib_time_now (frm->vlib_main) - frm->vlib_time_0));
192  h->export_time = clib_host_to_net_u32 (h->export_time);
193  h->domain_id = clib_host_to_net_u32 (stream->domain_id);
194 
195  /* FIXUP: message header sequence_number */
196  h->sequence_number = stream->sequence_number++;
197  h->sequence_number = clib_host_to_net_u32 (h->sequence_number);
198 
199  offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
200  }
201 
202  /* Add data, unless we're flushing stale data */
203  if (PREDICT_TRUE (do_flush == 0))
204  {
205 
206  /* Add data */
207  /* Ingress interface */
208  {
209  u32 ingress_interface = clib_host_to_net_u32 (rx_sw_if_index);
210  clib_memcpy (b0->data + offset, &ingress_interface,
211  sizeof (ingress_interface));
212  offset += sizeof (ingress_interface);
213  }
214  /* Egress interface */
215  {
216  u32 egress_interface = clib_host_to_net_u32 (tx_sw_if_index);
217  clib_memcpy (b0->data + offset, &egress_interface,
218  sizeof (egress_interface));
219  offset += sizeof (egress_interface);
220  }
221  /* ip4 src address */
222  {
223  clib_memcpy (b0->data + offset, &src_address, sizeof (src_address));
224  offset += sizeof (src_address);
225  }
226  /* ip4 dst address */
227  {
228  clib_memcpy (b0->data + offset, &dst_address, sizeof (dst_address));
229  offset += sizeof (dst_address);
230  }
231 
232  /* ToS */
233  b0->data[offset++] = tos;
234 
235  /* Timestamp */
236  clib_memcpy (b0->data + offset, &timestamp, sizeof (f64));
237  offset += sizeof (f64);
238 
239  /* pkt size */
240  {
241  u16 pkt_size = clib_host_to_net_u16 (length);
242  clib_memcpy (b0->data + offset, &pkt_size, sizeof (pkt_size));
243  offset += sizeof (pkt_size);
244  }
245 
246  b0->current_length +=
247  /* sw_if_index + tos + timestamp + length = 15 */
248  4 * sizeof (u32) + sizeof (u8) + sizeof (f64) + sizeof (u16);
249 
250  }
251  /* Time to flush the buffer? */
252  if (PREDICT_FALSE
253  (do_flush || (offset + sizeof (u32) + sizeof (u8)
254  + sizeof (f64)) > frm->path_mtu))
255  {
256  tp = vlib_buffer_get_current (b0);
257  ip = (ip4_header_t *) & tp->ip4;
258  udp = (udp_header_t *) (ip + 1);
259  h = (ipfix_message_header_t *) (udp + 1);
260  s = (ipfix_set_header_t *) (h + 1);
261 
263  b0->current_length -
264  (sizeof (*ip) + sizeof (*udp) +
265  sizeof (*h)));
267  (sizeof (*ip) + sizeof (*udp)));
268 
269  ip->length = clib_host_to_net_u16 (b0->current_length);
270 
271  ip->checksum = ip4_header_checksum (ip);
272  udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
273 
274  if (frm->udp_checksum)
275  {
276  /* RFC 7011 section 10.3.2. */
277  udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
278  if (udp->checksum == 0)
279  udp->checksum = 0xffff;
280  }
281 
282  ASSERT (ip->checksum == ip4_header_checksum (ip));
283 
285  fm->frames_per_worker[my_cpu_number]);
286  fm->frames_per_worker[my_cpu_number] = 0;
287  fm->buffers_per_worker[my_cpu_number] = 0;
288  offset = 0;
289  }
290 
291  fm->next_record_offset_per_worker[my_cpu_number] = offset;
292 }
293 
294 void
296 {
297  vlib_main_t *vm = vlib_get_main ();
299 
300  add_to_flow_record (vm, fm, 0 /* rx_sw_if_index */ ,
301  0 /* tx_sw_if_index */ ,
302  0 /* src_address */ ,
303  0 /* dst_address */ ,
304  0 /* ToS */ ,
305  0ULL /* timestamp */ ,
306  0 /* length */ ,
307  1 /* do_flush */ );
308 }
309 
310 
311 static uword
313  vlib_node_runtime_t * node, vlib_frame_t * frame)
314 {
315  u32 n_left_from, *from, *to_next;
316  flowperpkt_next_t next_index;
318  u64 now;
319 
320  now = (u64) ((vlib_time_now (vm) - fm->vlib_time_0) * 1e9);
321  now += fm->nanosecond_time_0;
322 
323  from = vlib_frame_vector_args (frame);
324  n_left_from = frame->n_vectors;
325  next_index = node->cached_next_index;
326 
327  while (n_left_from > 0)
328  {
329  u32 n_left_to_next;
330 
331  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
332 
333  while (n_left_from >= 4 && n_left_to_next >= 2)
334  {
335  u32 next0 = FLOWPERPKT_NEXT_DROP;
336  u32 next1 = FLOWPERPKT_NEXT_DROP;
337  ip4_header_t *ip0, *ip1;
338  u16 len0, len1;
339  u32 bi0, bi1;
340  vlib_buffer_t *b0, *b1;
341 
342  /* Prefetch next iteration. */
343  {
344  vlib_buffer_t *p2, *p3;
345 
346  p2 = vlib_get_buffer (vm, from[2]);
347  p3 = vlib_get_buffer (vm, from[3]);
348 
349  vlib_prefetch_buffer_header (p2, LOAD);
350  vlib_prefetch_buffer_header (p3, LOAD);
351 
354  }
355 
356  /* speculatively enqueue b0 and b1 to the current next frame */
357  to_next[0] = bi0 = from[0];
358  to_next[1] = bi1 = from[1];
359  from += 2;
360  to_next += 2;
361  n_left_from -= 2;
362  n_left_to_next -= 2;
363 
364  b0 = vlib_get_buffer (vm, bi0);
365  b1 = vlib_get_buffer (vm, bi1);
366 
367  vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX],
368  &next0, b0);
369  vnet_feature_next (vnet_buffer (b1)->sw_if_index[VLIB_TX],
370  &next1, b1);
371 
372  ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) +
373  vnet_buffer (b0)->ip.save_rewrite_length);
374 
375  len0 = vlib_buffer_length_in_chain (vm, b0);
376 
377  if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0))
378  add_to_flow_record (vm, fm,
379  vnet_buffer (b0)->sw_if_index[VLIB_RX],
380  vnet_buffer (b0)->sw_if_index[VLIB_TX],
381  ip0->src_address.as_u32,
382  ip0->dst_address.as_u32,
383  ip0->tos, now, len0, 0 /* flush */ );
384 
385  ip1 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b1) +
386  vnet_buffer (b1)->ip.save_rewrite_length);
387  len1 = vlib_buffer_length_in_chain (vm, b1);
388 
389  if (PREDICT_TRUE ((b1->flags & VLIB_BUFFER_FLOW_REPORT) == 0))
390  add_to_flow_record (vm, fm,
391  vnet_buffer (b1)->sw_if_index[VLIB_RX],
392  vnet_buffer (b1)->sw_if_index[VLIB_TX],
393  ip1->src_address.as_u32,
394  ip1->dst_address.as_u32,
395  ip1->tos, now, len1, 0 /* flush */ );
396 
397  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
398  {
399  if (b0->flags & VLIB_BUFFER_IS_TRACED)
400  {
401  flowperpkt_trace_t *t =
402  vlib_add_trace (vm, node, b0, sizeof (*t));
403  t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
404  t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
405  t->src_address = ip0->src_address.as_u32;
406  t->dst_address = ip0->dst_address.as_u32;
407  t->tos = ip0->tos;
408  t->timestamp = now;
409  t->buffer_size = len0;
410  }
411  if (b1->flags & VLIB_BUFFER_IS_TRACED)
412  {
413  flowperpkt_trace_t *t =
414  vlib_add_trace (vm, node, b1, sizeof (*t));
415  t->rx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX];
416  t->tx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX];
417  t->src_address = ip1->src_address.as_u32;
418  t->dst_address = ip1->dst_address.as_u32;
419  t->tos = ip1->tos;
420  t->timestamp = now;
421  t->buffer_size = len1;
422  }
423  }
424 
425  /* verify speculative enqueues, maybe switch current next frame */
426  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
427  to_next, n_left_to_next,
428  bi0, bi1, next0, next1);
429  }
430 
431  while (n_left_from > 0 && n_left_to_next > 0)
432  {
433  u32 bi0;
434  vlib_buffer_t *b0;
435  u32 next0 = FLOWPERPKT_NEXT_DROP;
436  ip4_header_t *ip0;
437  u16 len0;
438 
439  /* speculatively enqueue b0 to the current next frame */
440  bi0 = from[0];
441  to_next[0] = bi0;
442  from += 1;
443  to_next += 1;
444  n_left_from -= 1;
445  n_left_to_next -= 1;
446 
447  b0 = vlib_get_buffer (vm, bi0);
448 
449  vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX],
450  &next0, b0);
451 
452  ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) +
453  vnet_buffer (b0)->ip.save_rewrite_length);
454  /*
455  * egressInterface, TLV type 14, u32
456  * ipClassOfService, TLV type 5, u8
457  * flowStartNanoseconds, TLV type 156, dateTimeNanoseconds (f64)
458  * Implementation: f64 nanoseconds since VPP started
459  * dataLinkFrameSize, TLV type 312, u16
460  */
461  len0 = vlib_buffer_length_in_chain (vm, b0);
462 
463  if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0))
464  add_to_flow_record (vm, fm,
465  vnet_buffer (b0)->sw_if_index[VLIB_RX],
466  vnet_buffer (b0)->sw_if_index[VLIB_TX],
467  ip0->src_address.as_u32,
468  ip0->dst_address.as_u32,
469  ip0->tos, now, len0, 0 /* flush */ );
470 
472  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
473  {
474  flowperpkt_trace_t *t =
475  vlib_add_trace (vm, node, b0, sizeof (*t));
476  t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
477  t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
478  t->src_address = ip0->src_address.as_u32;
479  t->dst_address = ip0->dst_address.as_u32;
480  t->tos = ip0->tos;
481  t->timestamp = now;
482  t->buffer_size = len0;
483  }
484 
485  /* verify speculative enqueue, maybe switch current next frame */
486  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
487  to_next, n_left_to_next,
488  bi0, next0);
489  }
490 
491  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
492  }
493  return frame->n_vectors;
494 }
495 
496 /**
497  * @brief IPFIX flow-per-packet graph node
498  * @node flowperpkt
499  *
500  * This is the IPFIX flow-record-per-packet node.
501  *
502  * @param vm vlib_main_t corresponding to the current thread.
503  * @param node vlib_node_runtime_t data for this node.
504  * @param frame vlib_frame_t whose contents should be dispatched.
505  *
506  * @par Graph mechanics: buffer metadata, next index usage
507  *
508  * <em>Uses:</em>
509  * - <code>vnet_buffer(b)->ip.save_rewrite_length</code>
510  * - tells the node the length of the rewrite which was applied in
511  * ip4/6_rewrite_inline, allows the code to find the IP header without
512  * having to parse L2 headers, or make stupid assumptions about their
513  * length.
514  * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code>
515  * - Used to suppress flow record generation for flow record packets.
516  *
517  * <em>Sets:</em>
518  * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code>
519  * - To suppress flow record generation for flow record packets
520  *
521  * <em>Next Index:</em>
522  * - Next configured output feature on the interface, usually
523  * "interface-output." Generated flow records head for ip4-lookup
524  */
525 
526 /* *INDENT-OFF* */
528  .function = flowperpkt_node_fn,
529  .name = "flowperpkt",
530  .vector_size = sizeof (u32),
531  .format_trace = format_flowperpkt_trace,
533 
534  .n_errors = ARRAY_LEN(flowperpkt_error_strings),
535  .error_strings = flowperpkt_error_strings,
536 
537  .n_next_nodes = FLOWPERPKT_N_NEXT,
538 
539  /* edit / add dispositions here */
540  .next_nodes = {
541  [FLOWPERPKT_NEXT_DROP] = "error-drop",
542  },
543 };
544 /* *INDENT-ON* */
545 
546 /*
547  * fd.io coding-style-patch-verification: ON
548  *
549  * Local Variables:
550  * eval: (c-set-style "gnu")
551  * End:
552  */
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:459
#define CLIB_UNUSED(x)
Definition: clib.h:79
u8 tos
ToS bits.
Definition: node.c:35
ip4_address_t src_address
Definition: ip4_packet.h:163
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
Definition: buffer.h:406
#define PREDICT_TRUE(x)
Definition: clib.h:98
u64 nanosecond_time_0
Time reference pair.
Definition: flowperpkt.h:49
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
flowperpkt_error_t
Definition: node.c:64
struct _vlib_node_registration vlib_node_registration_t
ip4_address_t src_address
Definition: flow_report.h:96
u16 flags_and_fragment_offset
Definition: ip4_packet.h:144
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:100
u16 buffer_size
size of the buffer
Definition: node.c:39
format_function_t format_ip4_address
Definition: format.h:79
ip4_address_t ipfix_collector
Definition: flow_report.h:94
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:511
static u8 * format_flowperpkt_trace(u8 *s, va_list *args)
Definition: node.c:44
flow_report_stream_t * streams
Definition: flow_report.h:91
flow-per-packet plugin header file
static void vlib_buffer_init_for_free_list(vlib_buffer_t *_dst, vlib_buffer_free_list_t *fl)
Definition: buffer_funcs.h:613
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:78
static char * flowperpkt_error_strings[]
Definition: node.c:72
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:194
ip4_address_t dst_address
Definition: ip4_packet.h:163
u32 cpu_index
Definition: main.h:159
unsigned long u64
Definition: types.h:89
vlib_buffer_t ** buffers_per_worker
ipfix buffers under construction, per-worker thread
Definition: flowperpkt.h:42
static uword flowperpkt_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: node.c:312
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
Definition: buffer_funcs.h:70
flow_report_main_t flow_report_main
Definition: flow_report.c:21
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:82
u64 timestamp
packet timestamp
Definition: node.c:37
vlib_node_registration_t flowperpkt_node
IPFIX flow-per-packet graph node.
Definition: node.c:59
#define PREDICT_FALSE(x)
Definition: clib.h:97
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:196
#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
static_always_inline void vnet_feature_next(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:223
#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:216
#define foreach_flowperpkt_error
Definition: node.c:61
#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:350
static u32 version_length(u16 length)
Definition: ipfix_packet.h:31
u16 n_vectors
Definition: node.h:344
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
#define clib_memcpy(a, b, c)
Definition: string.h:69
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
Definition: buffer.h:99
#define ARRAY_LEN(x)
Definition: clib.h:59
#define VLIB_BUFFER_FLOW_REPORT
Definition: buffer.h:102
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
Definition: buffer.h:310
static void add_to_flow_record(vlib_main_t *vm, flowperpkt_main_t *fm, u32 rx_sw_if_index, u32 tx_sw_if_index, u32 src_address, u32 dst_address, u8 tos, u64 timestamp, u16 length, int do_flush)
add an entry to the flow record under construction
Definition: node.c:96
u16 cached_next_index
Definition: node.h:463
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
vlib_main_t * vlib_main
Definition: flow_report.h:113
#define vnet_buffer(b)
Definition: buffer.h:361
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
Definition: ip4_forward.c:1368
flowperpkt_main_t flowperpkt_main
Definition: flowperpkt.c:53
u16 * next_record_offset_per_worker
next record offset, per worker thread
Definition: flowperpkt.h:46
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:95
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
static u32 ipfix_set_id_length(u16 set_id, u16 length)
Definition: ipfix_packet.h:114
Definition: defs.h:47
unsigned short u16
Definition: types.h:57
u32 tx_sw_if_index
Definition: node.c:31
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:253
struct clib_bihash_value offset
template key/value backing page structure
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:170
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
u8 data[0]
Packet data.
Definition: buffer.h:158
u32 src_address
Definition: node.c:32
u8 ip_version_and_header_length
Definition: ip4_packet.h:131
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, u32 free_list_index)
Definition: buffer_funcs.h:317
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:187
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:85
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:238
u32 rx_sw_if_index
interface handle
Definition: node.c:30
flowperpkt_next_t
Definition: node.c:78
Definition: defs.h:46
u32 dst_address
Definition: node.c:33
vlib_frame_t ** frames_per_worker
frames containing ipfix buffers, per-worker thread
Definition: flowperpkt.h:44
void flowperpkt_flush_callback(void)
Definition: node.c:295