FD.io VPP  v18.10-34-gcce845e
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 /*
22  * pool of all MPLS Label DPOs
23  */
25 
26 static mpls_disp_dpo_t *
28 {
29  mpls_disp_dpo_t *mdd;
30 
31  pool_get_aligned(mpls_disp_dpo_pool, mdd, CLIB_CACHE_LINE_BYTES);
32  memset(mdd, 0, sizeof(*mdd));
33 
34  dpo_reset(&mdd->mdd_dpo);
35 
36  return (mdd);
37 }
38 
39 static index_t
41 {
42  return (mdd - mpls_disp_dpo_pool);
43 }
44 
45 void
47  fib_rpf_id_t rpf_id,
49  const dpo_id_t *parent,
50  dpo_id_t *dpo)
51 {
52  mpls_disp_dpo_t *mdd;
53  dpo_type_t dtype;
54 
55  mdd = mpls_disp_dpo_alloc();
56 
57  mdd->mdd_payload_proto = payload_proto;
58  mdd->mdd_rpf_id = rpf_id;
59  mdd->mdd_mode = mode;
60  dtype = (FIB_MPLS_LSP_MODE_PIPE == mode ?
63 
64  /*
65  * stack this disposition object on the parent given
66  */
67  dpo_stack(dtype,
68  mdd->mdd_payload_proto,
69  &mdd->mdd_dpo,
70  parent);
71 
72  /*
73  * set up the return DPO to refer to this object
74  */
75  dpo_set(dpo,
76  dtype,
77  payload_proto,
79 }
80 
81 u8*
82 format_mpls_disp_dpo (u8 *s, va_list *args)
83 {
84  index_t index = va_arg(*args, index_t);
85  u32 indent = va_arg(*args, u32);
86  mpls_disp_dpo_t *mdd;
87 
88  mdd = mpls_disp_dpo_get(index);
89 
90  s = format(s, "mpls-disposition:[%d]:[%U, %U]",
91  index,
94 
95  s = format(s, "\n%U", format_white_space, indent);
96  s = format(s, "%U", format_dpo_id, &mdd->mdd_dpo, indent+2);
97 
98  return (s);
99 }
100 
101 static void
103 {
104  mpls_disp_dpo_t *mdd;
105 
106  mdd = mpls_disp_dpo_get(dpo->dpoi_index);
107 
108  mdd->mdd_locks++;
109 }
110 
111 static void
113 {
114  mpls_disp_dpo_t *mdd;
115 
116  mdd = mpls_disp_dpo_get(dpo->dpoi_index);
117 
118  mdd->mdd_locks--;
119 
120  if (0 == mdd->mdd_locks)
121  {
122  dpo_reset(&mdd->mdd_dpo);
123  pool_put(mpls_disp_dpo_pool, mdd);
124  }
125 }
126 
127 /**
128  * @brief A struct to hold tracing information for the MPLS label disposition
129  * node.
130  */
132 {
135 
140 
143  vlib_node_runtime_t * node,
144  vlib_frame_t * from_frame,
145  u8 payload_is_ip4,
146  u8 payload_is_ip6,
147  fib_mpls_lsp_mode_t mode)
148 {
149  u32 n_left_from, next_index, * from, * to_next;
150  vlib_node_runtime_t *error_node;
151 
152  if (payload_is_ip4)
153  {
154  if (FIB_MPLS_LSP_MODE_PIPE == mode)
155  error_node =
157  else
158  error_node =
160  }
161  else
162  {
163  if (FIB_MPLS_LSP_MODE_PIPE == mode)
164  error_node =
166  else
167  error_node =
169  }
170  from = vlib_frame_vector_args(from_frame);
171  n_left_from = from_frame->n_vectors;
172 
173  next_index = node->cached_next_index;
174 
175  while (n_left_from > 0)
176  {
177  u32 n_left_to_next;
178 
179  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
180 
181  while (n_left_from >= 4 && n_left_to_next >= 2)
182  {
183  mpls_disp_dpo_t *mdd0, *mdd1;
184  u32 bi0, mddi0, bi1, mddi1;
185  vlib_buffer_t * b0, *b1;
186  u32 next0, next1;
187 
188  bi0 = to_next[0] = from[0];
189  bi1 = to_next[1] = from[1];
190 
191  /* Prefetch next iteration. */
192  {
193  vlib_buffer_t * p2, * p3;
194 
195  p2 = vlib_get_buffer(vm, from[2]);
196  p3 = vlib_get_buffer(vm, from[3]);
197 
198  vlib_prefetch_buffer_header(p2, STORE);
199  vlib_prefetch_buffer_header(p3, STORE);
200 
201  CLIB_PREFETCH(p2->data, sizeof(ip6_header_t), STORE);
202  CLIB_PREFETCH(p3->data, sizeof(ip6_header_t), STORE);
203  }
204 
205  from += 2;
206  to_next += 2;
207  n_left_from -= 2;
208  n_left_to_next -= 2;
209 
210  b0 = vlib_get_buffer(vm, bi0);
211  b1 = vlib_get_buffer(vm, bi1);
212 
213  /* dst lookup was done by ip4 lookup */
214  mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
215  mddi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
216  mdd0 = mpls_disp_dpo_get(mddi0);
217  mdd1 = mpls_disp_dpo_get(mddi1);
218 
219  next0 = mdd0->mdd_dpo.dpoi_next_node;
220  next1 = mdd1->mdd_dpo.dpoi_next_node;
221 
222  if (payload_is_ip4)
223  {
224  ip4_header_t *ip0, *ip1;
225 
226  ip0 = vlib_buffer_get_current(b0);
227  ip1 = vlib_buffer_get_current(b1);
228 
229  /*
230  * IPv4 input checks on the exposed IP header
231  * including checksum
232  */
233  ip4_input_check_x2(vm, error_node,
234  b0, b1, ip0, ip1,
235  &next0, &next1, 1);
236 
237  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
238  {
239  /*
240  * Copy the TTL from the MPLS packet into the
241  * exposed IP. recalc the chksum
242  */
243  ip0->ttl = vnet_buffer(b0)->mpls.ttl;
244  ip1->ttl = vnet_buffer(b1)->mpls.ttl;
245  ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp);
246  ip1->tos = mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp);
247 
248  ip0->checksum = ip4_header_checksum(ip0);
249  ip1->checksum = ip4_header_checksum(ip1);
250  }
251  }
252  else if (payload_is_ip6)
253  {
254  ip6_header_t *ip0, *ip1;
255 
256  ip0 = vlib_buffer_get_current(b0);
257  ip1 = vlib_buffer_get_current(b1);
258 
259  /*
260  * IPv6 input checks on the exposed IP header
261  */
262  ip6_input_check_x2(vm, error_node,
263  b0, b1, ip0, ip1,
264  &next0, &next1);
265 
266  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
267  {
268  /*
269  * Copy the TTL from the MPLS packet into the
270  * exposed IP
271  */
272  ip0->hop_limit = vnet_buffer(b0)->mpls.ttl;
273  ip1->hop_limit = vnet_buffer(b1)->mpls.ttl;
274 
276  ip0,
277  mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp));
279  ip1,
280  mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp));
281  }
282  }
283 
284  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index;
285  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = mdd1->mdd_dpo.dpoi_index;
286  vnet_buffer(b0)->ip.rpf_id = mdd0->mdd_rpf_id;
287  vnet_buffer(b1)->ip.rpf_id = mdd1->mdd_rpf_id;
288 
289  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
290  {
292  vlib_add_trace(vm, node, b0, sizeof(*tr));
293 
294  tr->mdd = mddi0;
295  }
296  if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
297  {
299  vlib_add_trace(vm, node, b1, sizeof(*tr));
300  tr->mdd = mddi1;
301  }
302 
303  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
304  n_left_to_next,
305  bi0, bi1, next0, next1);
306  }
307 
308  while (n_left_from > 0 && n_left_to_next > 0)
309  {
310  mpls_disp_dpo_t *mdd0;
311  vlib_buffer_t * b0;
312  u32 bi0, mddi0;
313  u32 next0;
314 
315  bi0 = from[0];
316  to_next[0] = bi0;
317  from += 1;
318  to_next += 1;
319  n_left_from -= 1;
320  n_left_to_next -= 1;
321 
322  b0 = vlib_get_buffer(vm, bi0);
323 
324  /* dst lookup was done by ip4 lookup */
325  mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
326  mdd0 = mpls_disp_dpo_get(mddi0);
327  next0 = mdd0->mdd_dpo.dpoi_next_node;
328 
329  if (payload_is_ip4)
330  {
331  ip4_header_t *ip0;
332 
333  ip0 = vlib_buffer_get_current(b0);
334 
335  /*
336  * IPv4 input checks on the exposed IP header
337  * including checksum
338  */
339  ip4_input_check_x1(vm, error_node, b0, ip0, &next0, 1);
340 
341  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
342  {
343  /*
344  * Copy the TTL from the MPLS packet into the
345  * exposed IP. recalc the chksum
346  */
347  ip0->ttl = vnet_buffer(b0)->mpls.ttl;
348  ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp);
349  ip0->checksum = ip4_header_checksum(ip0);
350  }
351  }
352  else if (payload_is_ip6)
353  {
354  ip6_header_t *ip0;
355 
356  ip0 = vlib_buffer_get_current(b0);
357 
358  /*
359  * IPv6 input checks on the exposed IP header
360  */
361  ip6_input_check_x1(vm, error_node, b0, ip0, &next0);
362 
363  if (FIB_MPLS_LSP_MODE_UNIFORM == mode)
364  {
365  /*
366  * Copy the TTL from the MPLS packet into the
367  * exposed IP
368  */
369  ip0->hop_limit = vnet_buffer(b0)->mpls.ttl;
370 
372  ip0,
373  mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp));
374  }
375  }
376 
377  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index;
378  vnet_buffer(b0)->ip.rpf_id = mdd0->mdd_rpf_id;
379 
380  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
381  {
383  vlib_add_trace(vm, node, b0, sizeof(*tr));
384  tr->mdd = mddi0;
385  }
386 
387  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
388  n_left_to_next, bi0, next0);
389  }
390  vlib_put_next_frame(vm, node, next_index, n_left_to_next);
391  }
392  return from_frame->n_vectors;
393 }
394 
395 static u8 *
397 {
398  CLIB_UNUSED(vlib_main_t * vm) = va_arg(*args, vlib_main_t *);
399  CLIB_UNUSED(vlib_node_t * node) = va_arg(*args, vlib_node_t *);
401 
402  t = va_arg(*args, mpls_label_disposition_trace_t *);
403 
404  s = format(s, "disp:%d", t->mdd);
405  return (s);
406 }
407 
408 static uword
410  vlib_node_runtime_t * node,
411  vlib_frame_t * frame)
412 {
413  return (mpls_label_disposition_inline(vm, node, frame, 1, 0,
415 }
416 
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 };
429 
430 static uword
431 ip6_mpls_label_disposition_pipe (vlib_main_t * vm,
432  vlib_node_runtime_t * node,
433  vlib_frame_t * frame)
434 {
435  return (mpls_label_disposition_inline(vm, node, frame, 0, 1,
437 }
438 
440  .function = ip6_mpls_label_disposition_pipe,
441  .name = "ip6-mpls-label-disposition-pipe",
442  .vector_size = sizeof(u32),
443 
444  .format_trace = format_mpls_label_disposition_trace,
445  .sibling_of = "ip6-input",
446  .n_errors = IP6_N_ERROR,
447  .error_strings = ip6_error_strings,
448 };
450  ip6_mpls_label_disposition_pipe)
451 
452 static uword
453 ip4_mpls_label_disposition_uniform (vlib_main_t * vm,
454  vlib_node_runtime_t * node,
455  vlib_frame_t * frame)
456 {
457  return (mpls_label_disposition_inline(vm, node, frame, 1, 0,
459 }
460 
462  .function = ip4_mpls_label_disposition_uniform,
463  .name = "ip4-mpls-label-disposition-uniform",
464  .vector_size = sizeof(u32),
465 
466  .format_trace = format_mpls_label_disposition_trace,
467  .sibling_of = "ip4-input",
468  .n_errors = IP4_N_ERROR,
469  .error_strings = ip4_error_strings,
470 };
472  ip4_mpls_label_disposition_uniform)
473 
474 static uword
475 ip6_mpls_label_disposition_uniform (vlib_main_t * vm,
476  vlib_node_runtime_t * node,
477  vlib_frame_t * frame)
478 {
479  return (mpls_label_disposition_inline(vm, node, frame, 0, 1,
481 }
482 
484  .function = ip6_mpls_label_disposition_uniform,
485  .name = "ip6-mpls-label-disposition-uniform",
486  .vector_size = sizeof(u32),
487 
488  .format_trace = format_mpls_label_disposition_trace,
489  .sibling_of = "ip6-input",
490  .n_errors = IP6_N_ERROR,
491  .error_strings = ip6_error_strings,
492 };
494  ip6_mpls_label_disposition_uniform)
495 
496 static void
497 mpls_disp_dpo_mem_show (void)
498 {
499  fib_show_memory_usage("MPLS label",
500  pool_elts(mpls_disp_dpo_pool),
501  pool_len(mpls_disp_dpo_pool),
502  sizeof(mpls_disp_dpo_t));
503 }
504 
505 const static dpo_vft_t mdd_vft = {
507  .dv_unlock = mpls_disp_dpo_unlock,
508  .dv_format = format_mpls_disp_dpo,
509  .dv_mem_show = mpls_disp_dpo_mem_show,
510 };
511 
512 const static char* const mpls_label_disp_pipe_ip4_nodes[] =
513 {
514  "ip4-mpls-label-disposition-pipe",
515  NULL,
516 };
517 const static char* const mpls_label_disp_pipe_ip6_nodes[] =
518 {
519  "ip6-mpls-label-disposition-pipe",
520  NULL,
521 };
522 const static char* const * const mpls_label_disp_pipe_nodes[DPO_PROTO_NUM] =
523 {
526 };
527 
528 const static char* const mpls_label_disp_uniform_ip4_nodes[] =
529 {
530  "ip4-mpls-label-disposition-uniform",
531  NULL,
532 };
533 const static char* const mpls_label_disp_uniform_ip6_nodes[] =
534 {
535  "ip6-mpls-label-disposition-uniform",
536  NULL,
537 };
538 const static char* const * const mpls_label_disp_uniform_nodes[DPO_PROTO_NUM] =
539 {
542 };
543 
544 
545 void
547 {
552 }
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:81
A virtual function table regisitered for a DPO type.
Definition: dpo.h:399
static uword ip4_mpls_label_disposition_pipe(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void mpls_disp_dpo_lock(dpo_id_t *dpo)
#define NULL
Definition: clib.h:57
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]
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static const char *const mpls_label_disp_pipe_ip6_nodes[]
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)
VLIB_NODE_FUNCTION_MULTIARCH(ip4_mpls_label_disposition_pipe_node, ip4_mpls_label_disposition_pipe)
memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:94
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:395
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:187
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 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:205
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
static const char *const mpls_label_disp_pipe_ip4_nodes[]
#define PREDICT_FALSE(x)
Definition: clib.h:107
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:364
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 (general version).
Definition: pool.h:188
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:155
u16 n_vectors
Definition: node.h:401
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:79
vlib_main_t * vm
Definition: buffer.c:294
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:221
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:455
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
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:513
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.
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:267
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:344
u8 data[0]
Packet data.
Definition: buffer.h:175
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
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:116
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:58
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:246
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