FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
mpls_disposition.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/ip/ip4_input.h>
17 #include <vnet/ip/ip6_input.h>
19 #include <vnet/mpls/mpls.h>
20 
21 #ifndef CLIB_MARCH_VARIANT
22 /*
23  * pool of all MPLS Label DPOs
24  */
26 
27 static mpls_disp_dpo_t *
29 {
30  mpls_disp_dpo_t *mdd;
31 
32  pool_get_aligned(mpls_disp_dpo_pool, mdd, CLIB_CACHE_LINE_BYTES);
33  clib_memset(mdd, 0, sizeof(*mdd));
34 
35  dpo_reset(&mdd->mdd_dpo);
36 
37  return (mdd);
38 }
39 
40 static index_t
42 {
43  return (mdd - mpls_disp_dpo_pool);
44 }
45 
46 void
48  fib_rpf_id_t rpf_id,
50  const dpo_id_t *parent,
51  dpo_id_t *dpo)
52 {
53  mpls_disp_dpo_t *mdd;
54  dpo_type_t dtype;
55 
56  mdd = mpls_disp_dpo_alloc();
57 
58  mdd->mdd_payload_proto = payload_proto;
59  mdd->mdd_rpf_id = rpf_id;
60  mdd->mdd_mode = mode;
61  dtype = (FIB_MPLS_LSP_MODE_PIPE == mode ?
64 
65  /*
66  * stack this disposition object on the parent given
67  */
68  dpo_stack(dtype,
69  mdd->mdd_payload_proto,
70  &mdd->mdd_dpo,
71  parent);
72 
73  /*
74  * set up the return DPO to refer to this object
75  */
76  dpo_set(dpo,
77  dtype,
78  payload_proto,
80 }
81 
82 u8*
83 format_mpls_disp_dpo (u8 *s, va_list *args)
84 {
85  index_t index = va_arg(*args, index_t);
86  u32 indent = va_arg(*args, u32);
87  mpls_disp_dpo_t *mdd;
88 
89  mdd = mpls_disp_dpo_get(index);
90 
91  s = format(s, "mpls-disposition:[%d]:[%U, %U]",
92  index,
95 
96  s = format(s, "\n%U", format_white_space, indent);
97  s = format(s, "%U", format_dpo_id, &mdd->mdd_dpo, indent+2);
98 
99  return (s);
100 }
101 
102 static void
104 {
105  mpls_disp_dpo_t *mdd;
106 
107  mdd = mpls_disp_dpo_get(dpo->dpoi_index);
108 
109  mdd->mdd_locks++;
110 }
111 
112 static void
114 {
115  mpls_disp_dpo_t *mdd;
116 
117  mdd = mpls_disp_dpo_get(dpo->dpoi_index);
118 
119  mdd->mdd_locks--;
120 
121  if (0 == mdd->mdd_locks)
122  {
123  dpo_reset(&mdd->mdd_dpo);
124  pool_put(mpls_disp_dpo_pool, mdd);
125  }
126 }
127 #endif /* CLIB_MARCH_VARIANT */
128 
129 /**
130  * @brief A struct to hold tracing information for the MPLS label disposition
131  * node.
132  */
134 {
137 
142 
145  vlib_node_runtime_t * node,
146  vlib_frame_t * from_frame,
147  u8 payload_is_ip4,
148  u8 payload_is_ip6,
150 {
151  u32 n_left_from, next_index, * from, * to_next;
152  vlib_node_runtime_t *error_node;
153 
154  if (payload_is_ip4)
155  {
156  if (FIB_MPLS_LSP_MODE_PIPE == mode)
157  error_node =
159  else
160  error_node =
162  }
163  else
164  {
165  if (FIB_MPLS_LSP_MODE_PIPE == mode)
166  error_node =
168  else
169  error_node =
171  }
172  from = vlib_frame_vector_args(from_frame);
173  n_left_from = from_frame->n_vectors;
174 
175  next_index = node->cached_next_index;
176 
177  while (n_left_from > 0)
178  {
179  u32 n_left_to_next;
180 
181  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
182 
183  while (n_left_from >= 4 && n_left_to_next >= 2)
184  {
185  mpls_disp_dpo_t *mdd0, *mdd1;
186  u32 bi0, mddi0, bi1, mddi1;
187  vlib_buffer_t * b0, *b1;
188  u32 next0, next1;
189 
190  bi0 = to_next[0] = from[0];
191  bi1 = to_next[1] = from[1];
192 
193  /* Prefetch next iteration. */
194  {
195  vlib_buffer_t * p2, * p3;
196 
197  p2 = vlib_get_buffer(vm, from[2]);
198  p3 = vlib_get_buffer(vm, from[3]);
199 
200  vlib_prefetch_buffer_header(p2, STORE);
201  vlib_prefetch_buffer_header(p3, STORE);
202 
203  CLIB_PREFETCH(p2->data, sizeof(ip6_header_t), STORE);
204  CLIB_PREFETCH(p3->data, sizeof(ip6_header_t), STORE);
205  }
206 
207  from += 2;
208  to_next += 2;
209  n_left_from -= 2;
210  n_left_to_next -= 2;
211 
212  b0 = vlib_get_buffer(vm, bi0);
213  b1 = vlib_get_buffer(vm, bi1);
214 
215  /* dst lookup was done by ip4 lookup */
216  mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
217  mddi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
218  mdd0 = mpls_disp_dpo_get(mddi0);
219  mdd1 = mpls_disp_dpo_get(mddi1);
220 
221  next0 = mdd0->mdd_dpo.dpoi_next_node;
222  next1 = mdd1->mdd_dpo.dpoi_next_node;
223 
224  if (payload_is_ip4)
225  {
226  ip4_header_t *ip0, *ip1;
227 
228  ip0 = vlib_buffer_get_current(b0);
229  ip1 = vlib_buffer_get_current(b1);
230 
231  /*
232  * IPv4 input checks on the exposed IP header
233  * including checksum
234  */
235  ip4_input_check_x2(vm, error_node,
236  b0, b1, ip0, ip1,
237  &next0, &next1, 1);
238 
239  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
240  {
241  /*
242  * Copy the TTL from the MPLS packet into the
243  * exposed IP. recalc the chksum
244  */
245  ip0->ttl = vnet_buffer(b0)->mpls.ttl;
246  ip1->ttl = vnet_buffer(b1)->mpls.ttl;
247  ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp);
248  ip1->tos = mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp);
249 
250  ip0->checksum = ip4_header_checksum(ip0);
251  ip1->checksum = ip4_header_checksum(ip1);
252  }
253  }
254  else if (payload_is_ip6)
255  {
256  ip6_header_t *ip0, *ip1;
257 
258  ip0 = vlib_buffer_get_current(b0);
259  ip1 = vlib_buffer_get_current(b1);
260 
261  /*
262  * IPv6 input checks on the exposed IP header
263  */
264  ip6_input_check_x2(vm, error_node,
265  b0, b1, ip0, ip1,
266  &next0, &next1);
267 
268  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
269  {
270  /*
271  * Copy the TTL from the MPLS packet into the
272  * exposed IP
273  */
274  ip0->hop_limit = vnet_buffer(b0)->mpls.ttl;
275  ip1->hop_limit = vnet_buffer(b1)->mpls.ttl;
276 
278  ip0,
279  mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp));
281  ip1,
282  mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp));
283  }
284  }
285 
286  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index;
287  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = mdd1->mdd_dpo.dpoi_index;
288  vnet_buffer(b0)->ip.rpf_id = mdd0->mdd_rpf_id;
289  vnet_buffer(b1)->ip.rpf_id = mdd1->mdd_rpf_id;
290 
291  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
292  {
294  vlib_add_trace(vm, node, b0, sizeof(*tr));
295 
296  tr->mdd = mddi0;
297  }
298  if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
299  {
301  vlib_add_trace(vm, node, b1, sizeof(*tr));
302  tr->mdd = mddi1;
303  }
304 
305  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
306  n_left_to_next,
307  bi0, bi1, next0, next1);
308  }
309 
310  while (n_left_from > 0 && n_left_to_next > 0)
311  {
312  mpls_disp_dpo_t *mdd0;
313  vlib_buffer_t * b0;
314  u32 bi0, mddi0;
315  u32 next0;
316 
317  bi0 = from[0];
318  to_next[0] = bi0;
319  from += 1;
320  to_next += 1;
321  n_left_from -= 1;
322  n_left_to_next -= 1;
323 
324  b0 = vlib_get_buffer(vm, bi0);
325 
326  /* dst lookup was done by ip4 lookup */
327  mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
328  mdd0 = mpls_disp_dpo_get(mddi0);
329  next0 = mdd0->mdd_dpo.dpoi_next_node;
330 
331  if (payload_is_ip4)
332  {
333  ip4_header_t *ip0;
334 
335  ip0 = vlib_buffer_get_current(b0);
336 
337  /*
338  * IPv4 input checks on the exposed IP header
339  * including checksum
340  */
341  ip4_input_check_x1(vm, error_node, b0, ip0, &next0, 1);
342 
343  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
344  {
345  /*
346  * Copy the TTL from the MPLS packet into the
347  * exposed IP. recalc the chksum
348  */
349  ip0->ttl = vnet_buffer(b0)->mpls.ttl;
350  ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp);
351  ip0->checksum = ip4_header_checksum(ip0);
352  }
353  }
354  else if (payload_is_ip6)
355  {
356  ip6_header_t *ip0;
357 
358  ip0 = vlib_buffer_get_current(b0);
359 
360  /*
361  * IPv6 input checks on the exposed IP header
362  */
363  ip6_input_check_x1(vm, error_node, b0, ip0, &next0);
364 
365  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
366  {
367  /*
368  * Copy the TTL from the MPLS packet into the
369  * exposed IP
370  */
371  ip0->hop_limit = vnet_buffer(b0)->mpls.ttl;
372 
374  ip0,
375  mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp));
376  }
377  }
378 
379  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index;
380  vnet_buffer(b0)->ip.rpf_id = mdd0->mdd_rpf_id;
381 
382  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
383  {
385  vlib_add_trace(vm, node, b0, sizeof(*tr));
386  tr->mdd = mddi0;
387  }
388 
389  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
390  n_left_to_next, bi0, next0);
391  }
392  vlib_put_next_frame(vm, node, next_index, n_left_to_next);
393  }
394  return from_frame->n_vectors;
395 }
396 
397 static u8 *
399 {
400  CLIB_UNUSED(vlib_main_t * vm) = va_arg(*args, vlib_main_t *);
401  CLIB_UNUSED(vlib_node_t * node) = va_arg(*args, vlib_node_t *);
403 
404  t = va_arg(*args, mpls_label_disposition_trace_t *);
405 
406  s = format(s, "disp:%d", t->mdd);
407  return (s);
408 }
409 
411  vlib_node_runtime_t * node,
412  vlib_frame_t * frame)
413 {
414  return (mpls_label_disposition_inline(vm, node, frame, 1, 0,
416 }
417 
419  .name = "ip4-mpls-label-disposition-pipe",
420  .vector_size = sizeof(u32),
421 
422  .format_trace = format_mpls_label_disposition_trace,
423  .sibling_of = "ip4-input",
424  .n_errors = IP4_N_ERROR,
425  .error_strings = ip4_error_strings,
426 };
427 
429  vlib_node_runtime_t * node,
430  vlib_frame_t * frame)
431 {
432  return (mpls_label_disposition_inline(vm, node, frame, 0, 1,
434 }
435 
437  .name = "ip6-mpls-label-disposition-pipe",
438  .vector_size = sizeof(u32),
439 
440  .format_trace = format_mpls_label_disposition_trace,
441  .sibling_of = "ip6-input",
442  .n_errors = IP6_N_ERROR,
443  .error_strings = ip6_error_strings,
444 };
445 
447  vlib_node_runtime_t * node,
448  vlib_frame_t * frame)
449 {
450  return (mpls_label_disposition_inline(vm, node, frame, 1, 0,
452 }
453 
455  .name = "ip4-mpls-label-disposition-uniform",
456  .vector_size = sizeof(u32),
457 
458  .format_trace = format_mpls_label_disposition_trace,
459  .sibling_of = "ip4-input",
460  .n_errors = IP4_N_ERROR,
461  .error_strings = ip4_error_strings,
462 };
463 
465  vlib_node_runtime_t * node,
466  vlib_frame_t * frame)
467 {
468  return (mpls_label_disposition_inline(vm, node, frame, 0, 1,
470 }
471 
473  .name = "ip6-mpls-label-disposition-uniform",
474  .vector_size = sizeof(u32),
475 
476  .format_trace = format_mpls_label_disposition_trace,
477  .sibling_of = "ip6-input",
478  .n_errors = IP6_N_ERROR,
479  .error_strings = ip6_error_strings,
480 };
481 
482 #ifndef CLIB_MARCH_VARIANT
483 static void
485 {
486  fib_show_memory_usage("MPLS label",
487  pool_elts(mpls_disp_dpo_pool),
488  pool_len(mpls_disp_dpo_pool),
489  sizeof(mpls_disp_dpo_t));
490 }
491 
492 const static dpo_vft_t mdd_vft = {
494  .dv_unlock = mpls_disp_dpo_unlock,
495  .dv_format = format_mpls_disp_dpo,
496  .dv_mem_show = mpls_disp_dpo_mem_show,
497 };
498 
499 const static char* const mpls_label_disp_pipe_ip4_nodes[] =
500 {
501  "ip4-mpls-label-disposition-pipe",
502  NULL,
503 };
504 const static char* const mpls_label_disp_pipe_ip6_nodes[] =
505 {
506  "ip6-mpls-label-disposition-pipe",
507  NULL,
508 };
509 const static char* const * const mpls_label_disp_pipe_nodes[DPO_PROTO_NUM] =
510 {
513 };
514 
515 const static char* const mpls_label_disp_uniform_ip4_nodes[] =
516 {
517  "ip4-mpls-label-disposition-uniform",
518  NULL,
519 };
520 const static char* const mpls_label_disp_uniform_ip6_nodes[] =
521 {
522  "ip6-mpls-label-disposition-uniform",
523  NULL,
524 };
525 const static char* const * const mpls_label_disp_uniform_nodes[DPO_PROTO_NUM] =
526 {
529 };
530 
531 
532 void
534 {
539 }
540 #endif /* CLIB_MARCH_VARIANT */
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
u16 mdd_locks
Number of locks/users of the label.
A struct to hold tracing information for the MPLS label disposition node.
void mpls_disp_dpo_create(dpo_proto_t payload_proto, fib_rpf_id_t rpf_id, fib_mpls_lsp_mode_t mode, const dpo_id_t *parent, dpo_id_t *dpo)
Create an MPLS label object.
Pipe Mode - the default.
Definition: fib_types.h:404
#define CLIB_UNUSED(x)
Definition: clib.h:82
A virtual function table regisitered for a DPO type.
Definition: dpo.h:399
static void mpls_disp_dpo_lock(dpo_id_t *dpo)
#define NULL
Definition: clib.h:58
u8 data[0]
Packet data.
Definition: buffer.h:181
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 const char *const *const mpls_label_disp_pipe_nodes[DPO_PROTO_NUM]
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static const char *const mpls_label_disp_pipe_ip6_nodes[]
#define VLIB_NODE_FN(node)
Definition: node.h:201
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
static index_t mpls_disp_dpo_get_index(mpls_disp_dpo_t *mdd)
static mpls_disp_dpo_t * mpls_disp_dpo_alloc(void)
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
enum dpo_type_t_ dpo_type_t
Common types of data-path objects New types can be dynamically added using dpo_register_new_type() ...
#define always_inline
Definition: clib.h:98
u8 * format_fib_mpls_lsp_mode(u8 *s, va_list *ap)
Format an LSP mode type.
Definition: fib_types.c:56
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static_always_inline void ip6_set_traffic_class_network_order(ip6_header_t *ip6, u8 dscp)
Definition: ip6_packet.h:402
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
char * ip4_error_strings[]
Definition: ip4_input.c:309
dpo_proto_t mdd_payload_proto
The protocol of the payload/packets that are being encapped.
static void ip4_input_check_x1(vlib_main_t *vm, vlib_node_runtime_t *error_node, vlib_buffer_t *p0, ip4_header_t *ip0, u32 *next0, int verify_checksum)
Definition: ip4_input.h:280
vlib_node_registration_t ip6_mpls_label_disposition_uniform_node
(constructor) VLIB_REGISTER_NODE (ip6_mpls_label_disposition_uniform_node)
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
fib_rpf_id_t mdd_rpf_id
RPF-ID (if this is an mcast disposition)
unsigned int u32
Definition: types.h:88
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
static void mpls_disp_dpo_unlock(dpo_id_t *dpo)
vlib_node_registration_t ip4_mpls_label_disposition_pipe_node
(constructor) VLIB_REGISTER_NODE (ip4_mpls_label_disposition_pipe_node)
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
static void mpls_disp_dpo_mem_show(void)
static uword mpls_label_disposition_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, u8 payload_is_ip4, u8 payload_is_ip6, fib_mpls_lsp_mode_t mode)
enum fib_mpls_lsp_mode_t_ fib_mpls_lsp_mode_t
MPLS LSP mode - only valid at the head and tail.
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
static const char *const mpls_label_disp_pipe_ip4_nodes[]
#define PREDICT_FALSE(x)
Definition: clib.h:111
static u8 mpls_exp_to_ip_dscp(u8 exp)
When in uniform mode convert an MPLS EXP value to an IPv[46] DSCP value.
Definition: packet.h:66
#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:368
static void ip6_input_check_x2(vlib_main_t *vm, vlib_node_runtime_t *error_node, vlib_buffer_t *p0, vlib_buffer_t *p1, ip6_header_t *ip0, ip6_header_t *ip1, u32 *next0, u32 *next1)
Definition: ip6_input.h:58
mpls_disp_dpo_t * mpls_disp_dpo_pool
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:230
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:395
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
vlib_main_t * vm
Definition: buffer.c:312
static void ip6_input_check_x1(vlib_main_t *vm, vlib_node_runtime_t *error_node, vlib_buffer_t *p0, ip6_header_t *ip0, u32 *next0)
Definition: ip6_input.h:122
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
struct mpls_label_disposition_trace_t_ mpls_label_disposition_trace_t
A struct to hold tracing information for the MPLS label disposition node.
u8 * format_mpls_disp_dpo(u8 *s, va_list *args)
char * ip6_error_strings[]
Definition: ip6_input.c:222
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:465
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
vl_api_vxlan_gbp_api_tunnel_mode_t mode
Definition: vxlan_gbp.api:44
void mpls_disp_dpo_module_init(void)
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:391
A representation of an MPLS label for imposition in the data-path.
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:514
static const char *const mpls_label_disp_uniform_ip4_nodes[]
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:147
static const char *const *const mpls_label_disp_uniform_nodes[DPO_PROTO_NUM]
dpo_id_t mdd_dpo
Next DPO in the graph.
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
struct _vlib_node_registration vlib_node_registration_t
Definition: defs.h:47
static mpls_disp_dpo_t * mpls_disp_dpo_get(index_t index)
#define DPO_PROTO_NUM
Definition: dpo.h:70
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
static void ip4_input_check_x2(vlib_main_t *vm, vlib_node_runtime_t *error_node, vlib_buffer_t *p0, vlib_buffer_t *p1, ip4_header_t *ip0, ip4_header_t *ip1, u32 *next0, u32 *next1, int verify_checksum)
Definition: ip4_input.h:205
fib_mpls_lsp_mode_t mdd_mode
LSP mode.
VLIB buffer representation.
Definition: buffer.h:102
static const char *const mpls_label_disp_uniform_ip6_nodes[]
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:274
vlib_node_registration_t ip6_mpls_label_disposition_pipe_node
(constructor) VLIB_REGISTER_NODE (ip6_mpls_label_disposition_pipe_node)
u8 * format_dpo_proto(u8 *s, va_list *args)
format a DPO protocol
Definition: dpo.c:177
#define vnet_buffer(b)
Definition: buffer.h:369
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:231
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:180
vlib_node_registration_t ip4_mpls_label_disposition_uniform_node
(constructor) VLIB_REGISTER_NODE (ip4_mpls_label_disposition_uniform_node)
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
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
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
static u8 * format_mpls_label_disposition_trace(u8 *s, va_list *args)
void dpo_stack(dpo_type_t child_type, dpo_proto_t child_proto, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child-parent relationship.
Definition: dpo.c:515
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128