FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
dvr_dpo.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 #include <vnet/dpo/dvr_dpo.h>
17 #include <vnet/fib/fib_node.h>
18 #include <vnet/ip/ip.h>
19 #include <vnet/ethernet/ethernet.h>
20 
21 #ifndef CLIB_MARCH_VARIANT
23 
24 /**
25  * The 'DB' of DVR DPOs.
26  * There is one per-interface per-L3 proto, so this is a per-interface vector
27  */
29 
30 static dvr_dpo_t *
32 {
33  dvr_dpo_t *dd;
34 
35  pool_get(dvr_dpo_pool, dd);
36 
37  return (dd);
38 }
39 
40 static inline dvr_dpo_t *
42 {
43  ASSERT(DPO_DVR == dpo->dpoi_type);
44 
45  return (dvr_dpo_get(dpo->dpoi_index));
46 }
47 
48 static inline index_t
50 {
51  return (dd - dvr_dpo_pool);
52 }
53 
54 static void
56 {
57  dvr_dpo_t *dd;
58 
59  dd = dvr_dpo_get_from_dpo(dpo);
60  dd->dd_locks++;
61 }
62 
63 static void
65 {
66  dvr_dpo_t *dd;
67 
68  dd = dvr_dpo_get_from_dpo(dpo);
69  dd->dd_locks--;
70 
71  if (0 == dd->dd_locks)
72  {
73  if (DPO_PROTO_IP4 == dd->dd_proto)
74  {
75  vnet_feature_enable_disable ("ip4-output", "ip4-dvr-reinject",
76  dd->dd_sw_if_index, 0, 0, 0);
77  }
78  else
79  {
80  vnet_feature_enable_disable ("ip6-output", "ip6-dvr-reinject",
81  dd->dd_sw_if_index, 0, 0, 0);
82  }
83 
85  pool_put(dvr_dpo_pool, dd);
86  }
87 }
88 
89 void
91  dpo_proto_t dproto,
92  dpo_id_t *dpo)
93 {
94  dvr_dpo_t *dd;
95 
97  sw_if_index,
99 
100  if (INDEX_INVALID == dvr_dpo_db[dproto][sw_if_index])
101  {
102  dd = dvr_dpo_alloc();
103 
105  dd->dd_proto = dproto;
106 
108 
109  /*
110  * enable the reinject into L2 path feature on the interface
111  */
112  if (DPO_PROTO_IP4 == dproto)
113  vnet_feature_enable_disable ("ip4-output", "ip4-dvr-reinject",
114  dd->dd_sw_if_index, 1, 0, 0);
115  else if (DPO_PROTO_IP6 == dproto)
116  vnet_feature_enable_disable ("ip6-output", "ip6-dvr-reinject",
117  dd->dd_sw_if_index, 1, 0, 0);
118  else
119  ASSERT(0);
120  }
121  else
122  {
123  dd = dvr_dpo_get(dvr_dpo_db[dproto][sw_if_index]);
124  }
125 
126  dpo_set(dpo, DPO_DVR, dproto, dvr_dpo_get_index(dd));
127 }
128 #endif /* CLIB_MARCH_VARIANT */
129 
130 
131 static clib_error_t *
134  u32 flags)
135 {
136  /*
137  */
138  return (NULL);
139 }
140 
143 
144 /**
145  * @brief Registered callback for HW interface state changes
146  */
147 static clib_error_t *
149  u32 hw_if_index,
150  u32 flags)
151 {
152  return (NULL);
153 }
154 
157 
158 static clib_error_t *
161  u32 is_add)
162 {
163  return (NULL);
164 }
165 
168 
169 #ifndef CLIB_MARCH_VARIANT
170 static u8*
171 format_dvr_dpo (u8* s, va_list *ap)
172 {
173  index_t index = va_arg(*ap, index_t);
174  CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
175  vnet_main_t * vnm = vnet_get_main();
176  dvr_dpo_t *dd = dvr_dpo_get(index);
177 
178  return (format(s, "dvr-%U-dpo",
180  vnm,
182 }
183 
184 static void
186 {
187  fib_show_memory_usage("DVR",
188  pool_elts(dvr_dpo_pool),
189  pool_len(dvr_dpo_pool),
190  sizeof(dvr_dpo_t));
191 }
192 
193 
194 const static dpo_vft_t dvr_dpo_vft = {
196  .dv_unlock = dvr_dpo_unlock,
197  .dv_format = format_dvr_dpo,
198  .dv_mem_show = dvr_dpo_mem_show,
199 };
200 
201 /**
202  * @brief The per-protocol VLIB graph nodes that are assigned to a glean
203  * object.
204  *
205  * this means that these graph nodes are ones from which a glean is the
206  * parent object in the DPO-graph.
207  */
208 const static char* const dvr_dpo_ip4_nodes[] =
209 {
210  "ip4-dvr-dpo",
211  NULL,
212 };
213 const static char* const dvr_dpo_ip6_nodes[] =
214 {
215  "ip6-dvr-dpo",
216  NULL,
217 };
218 
219 const static char* const * const dvr_dpo_nodes[DPO_PROTO_NUM] =
220 {
223 };
224 
225 void
227 {
229  &dvr_dpo_vft,
230  dvr_dpo_nodes);
231 }
232 #endif /* CLIB_MARCH_VARIANT */
233 
234 /**
235  * @brief Interface DPO trace data
236  */
237 typedef struct dvr_dpo_trace_t_
238 {
241 
244  vlib_node_runtime_t * node,
245  vlib_frame_t * from_frame,
246  u8 is_ip6)
247 {
248  u32 n_left_from, next_index, * from, * to_next;
249  ip_lookup_main_t *lm = (is_ip6?
252 
253  from = vlib_frame_vector_args (from_frame);
254  n_left_from = from_frame->n_vectors;
255 
256  next_index = node->cached_next_index;
257 
258  while (n_left_from > 0)
259  {
260  u32 n_left_to_next;
261 
262  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
263 
264  while (n_left_from >= 4 && n_left_to_next > 2)
265  {
266  const dvr_dpo_t *dd0, *dd1;
267  u32 bi0, ddi0, bi1, ddi1;
268  vlib_buffer_t *b0, *b1;
269  u32 next0, next1;
270  u8 len0, len1;
271 
272  bi0 = from[0];
273  to_next[0] = bi0;
274  bi1 = from[1];
275  to_next[1] = bi1;
276  from += 2;
277  to_next += 2;
278  n_left_from -= 2;
279  n_left_to_next -= 2;
280  next0 = next1 = 0;
281 
282  b0 = vlib_get_buffer (vm, bi0);
283  b1 = vlib_get_buffer (vm, bi1);
284 
285  ddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
286  ddi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
287  dd0 = dvr_dpo_get(ddi0);
288  dd1 = dvr_dpo_get(ddi1);
289 
290  vnet_buffer(b0)->sw_if_index[VLIB_TX] = dd0->dd_sw_if_index;
291  vnet_buffer(b1)->sw_if_index[VLIB_TX] = dd1->dd_sw_if_index;
292 
293  len0 = ((u8*)vlib_buffer_get_current(b0) -
295  len1 = ((u8*)vlib_buffer_get_current(b1) -
297  vnet_buffer(b0)->l2.l2_len =
298  vnet_buffer(b0)->ip.save_rewrite_length =
299  len0;
300  vnet_buffer(b1)->l2.l2_len =
301  vnet_buffer(b1)->ip.save_rewrite_length =
302  len1;
303  b0->flags |= VNET_BUFFER_F_IS_DVR;
304  b1->flags |= VNET_BUFFER_F_IS_DVR;
305 
306  vlib_buffer_advance(b0, -len0);
307  vlib_buffer_advance(b1, -len1);
308 
310  dd0->dd_sw_if_index, &next0, b0);
312  dd1->dd_sw_if_index, &next1, b1);
313 
314  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
315  {
316  dvr_dpo_trace_t *tr0;
317 
318  tr0 = vlib_add_trace (vm, node, b0, sizeof (*tr0));
319  tr0->sw_if_index = dd0->dd_sw_if_index;
320  }
321  if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
322  {
323  dvr_dpo_trace_t *tr1;
324 
325  tr1 = vlib_add_trace (vm, node, b1, sizeof (*tr1));
326  tr1->sw_if_index = dd1->dd_sw_if_index;
327  }
328 
329  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
330  n_left_to_next, bi0, bi1,
331  next0, next1);
332  }
333 
334  while (n_left_from > 0 && n_left_to_next > 0)
335  {
336  const dvr_dpo_t * dd0;
337  vlib_buffer_t * b0;
338  u32 bi0, ddi0;
339  u32 next0;
340  u8 len0;
341 
342  bi0 = from[0];
343  to_next[0] = bi0;
344  from += 1;
345  to_next += 1;
346  n_left_from -= 1;
347  n_left_to_next -= 1;
348  next0 = 0;
349 
350  b0 = vlib_get_buffer (vm, bi0);
351 
352  ddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
353  dd0 = dvr_dpo_get(ddi0);
354 
355  vnet_buffer(b0)->sw_if_index[VLIB_TX] = dd0->dd_sw_if_index;
356 
357  /*
358  * take that, rewind it back...
359  */
360  len0 = ((u8*)vlib_buffer_get_current(b0) -
362  vnet_buffer(b0)->l2.l2_len =
363  vnet_buffer(b0)->ip.save_rewrite_length =
364  len0;
365  b0->flags |= VNET_BUFFER_F_IS_DVR;
366  vlib_buffer_advance(b0, -len0);
367 
368  /*
369  * start processing the ipX output features
370  */
372  dd0->dd_sw_if_index, &next0, b0);
373 
374  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
375  {
376  dvr_dpo_trace_t *tr;
377 
378  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
379  tr->sw_if_index = dd0->dd_sw_if_index;
380  }
381 
382  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
383  n_left_to_next, bi0,
384  next0);
385  }
386  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
387  }
388  return from_frame->n_vectors;
389 }
390 
391 static u8 *
392 format_dvr_dpo_trace (u8 * s, va_list * args)
393 {
394  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
395  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
396  dvr_dpo_trace_t * t = va_arg (*args, dvr_dpo_trace_t *);
397  u32 indent = format_get_indent (s);
398  s = format (s, "%U sw_if_index:%d",
399  format_white_space, indent,
400  t->sw_if_index);
401  return s;
402 }
403 
405  vlib_node_runtime_t * node,
406  vlib_frame_t * from_frame)
407 {
408  return (dvr_dpo_inline(vm, node, from_frame, 0));
409 }
410 
412  vlib_node_runtime_t * node,
413  vlib_frame_t * from_frame)
414 {
415  return (dvr_dpo_inline(vm, node, from_frame, 1));
416 }
417 
419  .name = "ip4-dvr-dpo",
420  .vector_size = sizeof (u32),
421  .format_trace = format_dvr_dpo_trace,
422  .sibling_of = "ip4-rewrite",
423 };
425  .name = "ip6-dvr-dpo",
426  .vector_size = sizeof (u32),
427  .format_trace = format_dvr_dpo_trace,
428  .sibling_of = "ip6-rewrite",
429 };
430 
432 {
435 
438  vlib_node_runtime_t * node,
439  vlib_frame_t * from_frame)
440 {
441  u32 n_left_from, next_index, * from, * to_next;
442 
443  from = vlib_frame_vector_args (from_frame);
444  n_left_from = from_frame->n_vectors;
445 
446  next_index = node->cached_next_index;
447 
448  while (n_left_from > 0)
449  {
450  u32 n_left_to_next;
451 
452  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
453 
454  while (n_left_from >= 4 && n_left_to_next > 2)
455  {
456  dvr_reinject_next_t next0, next1;
457  vlib_buffer_t *b0, *b1;
458  u32 bi0, bi1;
459 
460  bi0 = from[0];
461  to_next[0] = bi0;
462  bi1 = from[1];
463  to_next[1] = bi1;
464  from += 2;
465  to_next += 2;
466  n_left_from -= 2;
467  n_left_to_next -= 2;
468 
469  b0 = vlib_get_buffer (vm, bi0);
470  b1 = vlib_get_buffer (vm, bi1);
471 
472  if (b0->flags & VNET_BUFFER_F_IS_DVR)
473  next0 = DVR_REINJECT_OUTPUT;
474  else
475  vnet_feature_next( &next0, b0);
476 
477  if (b1->flags & VNET_BUFFER_F_IS_DVR)
478  next1 = DVR_REINJECT_OUTPUT;
479  else
480  vnet_feature_next( &next1, b1);
481 
482  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
483  {
484  dvr_dpo_trace_t *tr0;
485 
486  tr0 = vlib_add_trace (vm, node, b0, sizeof (*tr0));
487  tr0->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_TX];
488  }
489  if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
490  {
491  dvr_dpo_trace_t *tr1;
492 
493  tr1 = vlib_add_trace (vm, node, b1, sizeof (*tr1));
494  tr1->sw_if_index = vnet_buffer(b1)->sw_if_index[VLIB_TX];
495  }
496 
497  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
498  n_left_to_next, bi0, bi1,
499  next0, next1);
500  }
501 
502  while (n_left_from > 0 && n_left_to_next > 0)
503  {
504  dvr_reinject_next_t next0;
505  vlib_buffer_t * b0;
506  u32 bi0;
507 
508  bi0 = from[0];
509  to_next[0] = bi0;
510  from += 1;
511  to_next += 1;
512  n_left_from -= 1;
513  n_left_to_next -= 1;
514 
515  b0 = vlib_get_buffer (vm, bi0);
516 
517  if (b0->flags & VNET_BUFFER_F_IS_DVR)
518  next0 = DVR_REINJECT_OUTPUT;
519  else
520  vnet_feature_next( &next0, b0);
521 
522  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
523  {
524  dvr_dpo_trace_t *tr;
525 
526  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
527  tr->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_TX];
528  }
529 
530  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
531  n_left_to_next, bi0, next0);
532  }
533  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
534  }
535  return from_frame->n_vectors;
536 }
537 
539  vlib_node_runtime_t * node,
540  vlib_frame_t * from_frame)
541 {
542  return (dvr_reinject_inline(vm, node, from_frame));
543 }
544 
546  vlib_node_runtime_t * node,
547  vlib_frame_t * from_frame)
548 {
549  return (dvr_reinject_inline(vm, node, from_frame));
550 }
551 
553  .name = "ip4-dvr-reinject",
554  .vector_size = sizeof (u32),
555  .format_trace = format_dvr_dpo_trace,
556 
557  .n_next_nodes = 1,
558  .next_nodes = {
559  [DVR_REINJECT_OUTPUT] = "l2-output",
560  },
561 };
562 
564  .name = "ip6-dvr-reinject",
565  .vector_size = sizeof (u32),
566  .format_trace = format_dvr_dpo_trace,
567 
568  .n_next_nodes = 1,
569  .next_nodes = {
570  [DVR_REINJECT_OUTPUT] = "l2-output",
571  },
572 };
573 
574 VNET_FEATURE_INIT (ip4_dvr_reinject_feat_node, static) =
575 {
576  .arc_name = "ip4-output",
577  .node_name = "ip4-dvr-reinject",
578  .runs_after = VNET_FEATURES ("nat44-in2out-output",
579  "acl-plugin-out-ip4-fa"),
580 };
581 VNET_FEATURE_INIT (ip6_dvr_reinject_feat_node, static) =
582 {
583  .arc_name = "ip6-output",
584  .node_name = "ip6-dvr-reinject",
585  .runs_after = VNET_FEATURES ("acl-plugin-out-ip6-fa"),
586 };
587 
static clib_error_t * dvr_dpo_interface_delete(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: dvr_dpo.c:159
u32 sw_if_index
Definition: ipsec_gre.api:37
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:404
vlib_node_registration_t ip6_dvr_dpo_node
(constructor) VLIB_REGISTER_NODE (ip6_dvr_dpo_node)
Definition: dvr_dpo.c:424
static clib_error_t * dvr_dpo_hw_interface_state_change(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Registered callback for HW interface state changes.
Definition: dvr_dpo.c:148
u32 flags
Definition: vhost_user.h:115
#define CLIB_UNUSED(x)
Definition: clib.h:82
A virtual function table regisitered for a DPO type.
Definition: dpo.h:399
static uword dvr_reinject_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: dvr_dpo.c:437
static u8 * format_dvr_dpo_trace(u8 *s, va_list *args)
Definition: dvr_dpo.c:392
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
Interface DPO trace data.
Definition: dvr_dpo.c:237
#define NULL
Definition: clib.h:58
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
static u32 format_get_indent(u8 *s)
Definition: format.h:72
ip_lookup_main_t lookup_main
Definition: ip4.h:98
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(dvr_dpo_interface_delete)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:201
static dvr_dpo_t * dvr_dpo_get(index_t index)
Definition: dvr_dpo.h:60
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
u16 dd_locks
number of locks.
Definition: dvr_dpo.h:45
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
static clib_error_t * dvr_dpo_interface_state_change(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: dvr_dpo.c:132
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(dvr_dpo_hw_interface_state_change)
u8 output_feature_arc_index
Definition: lookup.h:140
static index_t * dvr_dpo_db[DPO_PROTO_NUM]
The &#39;DB&#39; of DVR DPOs.
Definition: dvr_dpo.c:28
void dpo_register(dpo_type_t type, const dpo_vft_t *vft, const char *const *const *nodes)
For a given DPO type Register:
Definition: dpo.c:321
vlib_node_registration_t ip6_dvr_reinject_node
(constructor) VLIB_REGISTER_NODE (ip6_dvr_reinject_node)
Definition: dvr_dpo.c:563
#define always_inline
Definition: clib.h:98
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
enum dvr_reinject_next_t_ dvr_reinject_next_t
static index_t dvr_dpo_get_index(dvr_dpo_t *dd)
Definition: dvr_dpo.c:49
void fib_show_memory_usage(const char *name, u32 in_use_elts, u32 allocd_elts, size_t size_elt)
Show the memory usage for a type.
Definition: fib_node.c:220
unsigned int u32
Definition: types.h:88
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(dvr_dpo_interface_state_change)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
format_function_t format_vnet_sw_interface_name
static ethernet_header_t * ethernet_buffer_get_header(vlib_buffer_t *b)
Definition: ethernet.h:376
dpo_type_t dpoi_type
the type
Definition: dpo.h:172
struct dvr_dpo_trace_t_ dvr_dpo_trace_t
Interface DPO trace data.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
VNET_FEATURE_INIT(ip4_dvr_reinject_feat_node, static)
#define PREDICT_FALSE(x)
Definition: clib.h:111
void dvr_dpo_module_init(void)
Definition: dvr_dpo.c:226
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
void dvr_dpo_add_or_lock(u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo)
Definition: dvr_dpo.c:90
static void dvr_dpo_lock(dpo_id_t *dpo)
Definition: dvr_dpo.c:55
dpo_proto_t dd_proto
The protocol of packets using this DPO.
Definition: dvr_dpo.h:40
static void dvr_dpo_unlock(dpo_id_t *dpo)
Definition: dvr_dpo.c:64
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:395
vlib_main_t * vm
Definition: buffer.c:312
u32 dd_sw_if_index
The Software interface index that the packets will output on.
Definition: dvr_dpo.h:35
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:295
static const char *const dvr_dpo_ip6_nodes[]
Definition: dvr_dpo.c:213
static dvr_dpo_t * dvr_dpo_get_from_dpo(const dpo_id_t *dpo)
Definition: dvr_dpo.c:41
vlib_node_registration_t ip4_dvr_reinject_node
(constructor) VLIB_REGISTER_NODE (ip4_dvr_reinject_node)
Definition: dvr_dpo.c: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:458
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:185
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:513
#define ASSERT(truth)
ip6_main_t ip6_main
Definition: ip6_forward.c:2688
ip_lookup_main_t lookup_main
Definition: ip6.h:179
u8 is_add
Definition: ipsec_gre.api:36
static const char *const dvr_dpo_ip4_nodes[]
The per-protocol VLIB graph nodes that are assigned to a glean object.
Definition: dvr_dpo.c:208
static u8 * format_dvr_dpo(u8 *s, va_list *ap)
Definition: dvr_dpo.c:171
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
#define VNET_FEATURES(...)
Definition: feature.h:435
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:57
Definition: defs.h:47
#define DPO_PROTO_NUM
Definition: dpo.h:70
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
VLIB buffer representation.
Definition: buffer.h:102
The DVR DPO.
Definition: dvr_dpo.h:30
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
vlib_node_registration_t ip4_dvr_dpo_node
(constructor) VLIB_REGISTER_NODE (ip4_dvr_dpo_node)
Definition: dvr_dpo.c:418
static const char *const *const dvr_dpo_nodes[DPO_PROTO_NUM]
Definition: dvr_dpo.c:219
#define vnet_buffer(b)
Definition: buffer.h:369
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:905
Definition: dpo.h:119
dvr_dpo_t * dvr_dpo_pool
pool of all interface DPOs
Definition: dvr_dpo.c:22
dvr_reinject_next_t_
Definition: dvr_dpo.c:431
static void dvr_dpo_mem_show(void)
Definition: dvr_dpo.c:185
static uword dvr_dpo_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, u8 is_ip6)
Definition: dvr_dpo.c:243
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
static dvr_dpo_t * dvr_dpo_alloc(void)
Definition: dvr_dpo.c:31
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:274
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:275
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128