FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
lookup_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/ip/ip.h>
17 #include <vnet/dpo/lookup_dpo.h>
19 #include <vnet/mpls/mpls_lookup.h>
20 #include <vnet/fib/fib_table.h>
21 #include <vnet/fib/ip4_fib.h>
22 #include <vnet/fib/ip6_fib.h>
23 #include <vnet/fib/mpls_fib.h>
24 
25 static const char *const lookup_input_names[] = LOOKUP_INPUTS;
26 
27 /**
28  * @brief Enumeration of the lookup subtypes
29  */
30 typedef enum lookup_sub_type_t_
31 {
36 #define LOOKUP_SUB_TYPE_NUM (LOOKUP_SUB_TYPE_DST_TABLE_FROM_INTERFACE+1)
37 
38 #define FOR_EACH_LOOKUP_SUB_TYPE(_st) \
39  for (_st = LOOKUP_SUB_TYPE_IP4_SRC; _st < LOOKUP_SUB_TYPE_NUM; _st++)
40 
41 /**
42  * @brief pool of all MPLS Label DPOs
43  */
45 
46 /**
47  * @brief An array of registered DPO type values for the sub-types
48  */
50 
51 static lookup_dpo_t *
53 {
54  lookup_dpo_t *lkd;
55 
56  pool_get_aligned(lookup_dpo_pool, lkd, CLIB_CACHE_LINE_BYTES);
57 
58  return (lkd);
59 }
60 
61 static index_t
63 {
64  return (lkd - lookup_dpo_pool);
65 }
66 
67 static void
69  dpo_proto_t proto,
70  lookup_input_t input,
71  lookup_table_t table_config,
72  dpo_id_t *dpo)
73 {
74  lookup_dpo_t *lkd;
75  dpo_type_t type;
76 
77  lkd = lookup_dpo_alloc();
78  lkd->lkd_fib_index = fib_index;
79  lkd->lkd_proto = proto;
80  lkd->lkd_input = input;
81  lkd->lkd_table = table_config;
82 
83  /*
84  * use the input type to select the lookup sub-type
85  */
86  type = 0;
87 
88  switch (input)
89  {
92  break;
94  switch (table_config)
95  {
98  break;
101  break;
102  }
103  }
104 
105  if (0 == type)
106  {
107  dpo_reset(dpo);
108  }
109  else
110  {
111  dpo_set(dpo, type, proto, lookup_dpo_get_index(lkd));
112  }
113 }
114 
115 void
117  dpo_proto_t proto,
118  lookup_input_t input,
119  lookup_table_t table_config,
120  dpo_id_t *dpo)
121 {
122  if (LOOKUP_TABLE_FROM_CONFIG == table_config)
123  {
124  fib_table_lock(fib_index, dpo_proto_to_fib(proto));
125  }
126  lookup_dpo_add_or_lock_i(fib_index, proto, input, table_config, dpo);
127 }
128 
129 void
131  dpo_proto_t proto,
132  lookup_input_t input,
133  lookup_table_t table_config,
134  dpo_id_t *dpo)
135 {
137 
138  if (LOOKUP_TABLE_FROM_CONFIG == table_config)
139  {
140  fib_index =
142  table_id);
143  }
144 
145  ASSERT(FIB_NODE_INDEX_INVALID != fib_index);
146  lookup_dpo_add_or_lock_i(fib_index, proto, input, table_config, dpo);
147 }
148 
149 u8*
150 format_lookup_dpo (u8 *s, va_list *args)
151 {
152  index_t index = va_arg (*args, index_t);
153  lookup_dpo_t *lkd;
154 
155  lkd = lookup_dpo_get(index);
156 
158  {
159  s = format(s, "%s lookup in interface's %U table",
162  }
163  else
164  {
165  s = format(s, "%s lookup in %U",
169  }
170  return (s);
171 }
172 
173 static void
175 {
176  lookup_dpo_t *lkd;
177 
178  lkd = lookup_dpo_get(dpo->dpoi_index);
179 
180  lkd->lkd_locks++;
181 }
182 
183 static void
185 {
186  lookup_dpo_t *lkd;
187 
188  lkd = lookup_dpo_get(dpo->dpoi_index);
189 
190  lkd->lkd_locks--;
191 
192  if (0 == lkd->lkd_locks)
193  {
195  {
198  }
199  pool_put(lookup_dpo_pool, lkd);
200  }
201 }
202 
203 always_inline void
204 ip4_src_fib_lookup_one (u32 src_fib_index0,
205  const ip4_address_t * addr0,
206  u32 * src_adj_index0)
207 {
208  ip4_fib_mtrie_leaf_t leaf0, leaf1;
209  ip4_fib_mtrie_t * mtrie0;
210 
211  mtrie0 = &ip4_fib_get (src_fib_index0)->mtrie;
212 
213  leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
214  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
215  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
216  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
217  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
218 
219  /* Handle default route. */
220  leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie0->default_leaf : leaf0);
221  src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
222 }
223 
224 always_inline void
225 ip4_src_fib_lookup_two (u32 src_fib_index0,
226  u32 src_fib_index1,
227  const ip4_address_t * addr0,
228  const ip4_address_t * addr1,
229  u32 * src_adj_index0,
230  u32 * src_adj_index1)
231 {
232  ip4_fib_mtrie_leaf_t leaf0, leaf1;
233  ip4_fib_mtrie_t * mtrie0, * mtrie1;
234 
235  mtrie0 = &ip4_fib_get (src_fib_index0)->mtrie;
236  mtrie1 = &ip4_fib_get (src_fib_index1)->mtrie;
237 
238  leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
239 
240  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
241  leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 0);
242 
243  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
244  leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 1);
245 
246  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
247  leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 2);
248 
249  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
250  leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 3);
251 
252  /* Handle default route. */
253  leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie0->default_leaf : leaf0);
254  leaf1 = (leaf1 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie1->default_leaf : leaf1);
255  src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
256  src_adj_index1[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf1);
257 }
258 
259 /**
260  * @brief Lookup trace data
261  */
262 typedef struct lookup_trace_t_
263 {
264  union {
265  ip46_address_t addr;
267  };
271 
272 
275  vlib_node_runtime_t * node,
276  vlib_frame_t * from_frame,
277  int input_src_addr,
278  int table_from_interface)
279 {
280  u32 n_left_from, next_index, * from, * to_next;
281  u32 cpu_index = os_get_cpu_number();
283 
284  from = vlib_frame_vector_args (from_frame);
285  n_left_from = from_frame->n_vectors;
286 
287  next_index = node->cached_next_index;
288 
289  while (n_left_from > 0)
290  {
291  u32 n_left_to_next;
292 
293  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
294 
295  while (n_left_from >= 4 && n_left_to_next > 2)
296  {
297  u32 bi0, lkdi0, lbi0, fib_index0, next0, hash_c0;
298  flow_hash_config_t flow_hash_config0;
299  const ip4_address_t *input_addr0;
300  const load_balance_t *lb0;
301  const lookup_dpo_t * lkd0;
302  const ip4_header_t * ip0;
303  const dpo_id_t *dpo0;
304  vlib_buffer_t * b0;
305  u32 bi1, lkdi1, lbi1, fib_index1, next1, hash_c1;
306  flow_hash_config_t flow_hash_config1;
307  const ip4_address_t *input_addr1;
308  const load_balance_t *lb1;
309  const lookup_dpo_t * lkd1;
310  const ip4_header_t * ip1;
311  const dpo_id_t *dpo1;
312  vlib_buffer_t * b1;
313 
314  /* Prefetch next iteration. */
315  {
316  vlib_buffer_t * p2, * p3;
317 
318  p2 = vlib_get_buffer (vm, from[2]);
319  p3 = vlib_get_buffer (vm, from[3]);
320 
321  vlib_prefetch_buffer_header (p2, LOAD);
322  vlib_prefetch_buffer_header (p3, LOAD);
323 
326  }
327 
328  bi0 = from[0];
329  to_next[0] = bi0;
330  bi1 = from[1];
331  to_next[1] = bi1;
332  from += 2;
333  to_next += 2;
334  n_left_from -= 2;
335  n_left_to_next -= 2;
336 
337  b0 = vlib_get_buffer (vm, bi0);
338  ip0 = vlib_buffer_get_current (b0);
339  b1 = vlib_get_buffer (vm, bi1);
340  ip1 = vlib_buffer_get_current (b1);
341 
342  /* dst lookup was done by ip4 lookup */
343  lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
344  lkdi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
345  lkd0 = lookup_dpo_get(lkdi0);
346  lkd1 = lookup_dpo_get(lkdi1);
347 
348  /*
349  * choose between a lookup using the fib index in the DPO
350  * or getting the FIB index from the interface.
351  */
352  if (table_from_interface)
353  {
354  fib_index0 =
356  vnet_buffer(b0)->sw_if_index[VLIB_RX]);
357  fib_index1 =
359  vnet_buffer(b1)->sw_if_index[VLIB_RX]);
360  }
361  else
362  {
363  fib_index0 = lkd0->lkd_fib_index;
364  fib_index1 = lkd1->lkd_fib_index;
365  }
366 
367  /*
368  * choose between a source or destination address lookup in the table
369  */
370  if (input_src_addr)
371  {
372  input_addr0 = &ip0->src_address;
373  input_addr1 = &ip1->src_address;
374  }
375  else
376  {
377  input_addr0 = &ip0->dst_address;
378  input_addr1 = &ip1->dst_address;
379  }
380 
381  /* do lookup */
382  ip4_src_fib_lookup_two (fib_index0, fib_index1,
383  input_addr0, input_addr1,
384  &lbi0, &lbi1);
385  lb0 = load_balance_get(lbi0);
386  lb1 = load_balance_get(lbi1);
387 
388  vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
389  vnet_buffer(b1)->sw_if_index[VLIB_TX] = fib_index1;
390 
391  /* Use flow hash to compute multipath adjacency. */
392  hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
393  hash_c1 = vnet_buffer (b1)->ip.flow_hash = 0;
394 
395  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
396  {
397  flow_hash_config0 = lb0->lb_hash_config;
398  hash_c0 = vnet_buffer (b0)->ip.flow_hash =
399  ip4_compute_flow_hash (ip0, flow_hash_config0);
400  }
401 
402  if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
403  {
404  flow_hash_config1 = lb1->lb_hash_config;
405  hash_c1 = vnet_buffer (b1)->ip.flow_hash =
406  ip4_compute_flow_hash (ip1, flow_hash_config1);
407  }
408 
409  dpo0 = load_balance_get_bucket_i(lb0,
410  (hash_c0 &
411  (lb0->lb_n_buckets_minus_1)));
412  dpo1 = load_balance_get_bucket_i(lb1,
413  (hash_c1 &
414  (lb1->lb_n_buckets_minus_1)));
415 
416  next0 = dpo0->dpoi_next_node;
417  next1 = dpo1->dpoi_next_node;
418  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
419  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
420 
422  (cm, cpu_index, lbi0, 1,
423  vlib_buffer_length_in_chain (vm, b0));
425  (cm, cpu_index, lbi1, 1,
426  vlib_buffer_length_in_chain (vm, b1));
427 
429  {
430  lookup_trace_t *tr = vlib_add_trace (vm, node,
431  b0, sizeof (*tr));
432  tr->fib_index = fib_index0;
433  tr->lbi = lbi0;
434  tr->addr.ip4 = *input_addr0;
435  }
437  {
438  lookup_trace_t *tr = vlib_add_trace (vm, node,
439  b1, sizeof (*tr));
440  tr->fib_index = fib_index1;
441  tr->lbi = lbi1;
442  tr->addr.ip4 = *input_addr1;
443  }
444 
445  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
446  to_next, n_left_to_next,
447  bi0, bi1, next0, next1);
448  }
449 
450  while (n_left_from > 0 && n_left_to_next > 0)
451  {
452  u32 bi0, lkdi0, lbi0, fib_index0, next0, hash_c0;
453  flow_hash_config_t flow_hash_config0;
454  const ip4_address_t *input_addr;
455  const load_balance_t *lb0;
456  const lookup_dpo_t * lkd0;
457  const ip4_header_t * ip0;
458  const dpo_id_t *dpo0;
459  vlib_buffer_t * b0;
460 
461  bi0 = from[0];
462  to_next[0] = bi0;
463  from += 1;
464  to_next += 1;
465  n_left_from -= 1;
466  n_left_to_next -= 1;
467 
468  b0 = vlib_get_buffer (vm, bi0);
469  ip0 = vlib_buffer_get_current (b0);
470 
471  /* dst lookup was done by ip4 lookup */
472  lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
473  lkd0 = lookup_dpo_get(lkdi0);
474 
475  /*
476  * choose between a lookup using the fib index in the DPO
477  * or getting the FIB index from the interface.
478  */
479  if (table_from_interface)
480  {
481  fib_index0 =
483  vnet_buffer(b0)->sw_if_index[VLIB_RX]);
484  }
485  else
486  {
487  fib_index0 = lkd0->lkd_fib_index;
488  }
489 
490  /*
491  * choose between a source or destination address lookup in the table
492  */
493  if (input_src_addr)
494  {
495  input_addr = &ip0->src_address;
496  }
497  else
498  {
499  input_addr = &ip0->dst_address;
500  }
501 
502  /* do lookup */
503  ip4_src_fib_lookup_one (fib_index0, input_addr, &lbi0);
504  lb0 = load_balance_get(lbi0);
505 
506  vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
507 
508  /* Use flow hash to compute multipath adjacency. */
509  hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
510 
511  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
512  {
513  flow_hash_config0 = lb0->lb_hash_config;
514  hash_c0 = vnet_buffer (b0)->ip.flow_hash =
515  ip4_compute_flow_hash (ip0, flow_hash_config0);
516  }
517 
518  dpo0 = load_balance_get_bucket_i(lb0,
519  (hash_c0 &
520  (lb0->lb_n_buckets_minus_1)));
521 
522  next0 = dpo0->dpoi_next_node;
523  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
524 
526  (cm, cpu_index, lbi0, 1,
527  vlib_buffer_length_in_chain (vm, b0));
528 
530  {
531  lookup_trace_t *tr = vlib_add_trace (vm, node,
532  b0, sizeof (*tr));
533  tr->fib_index = fib_index0;
534  tr->lbi = lbi0;
535  tr->addr.ip4 = *input_addr;
536  }
537 
538  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
539  n_left_to_next, bi0, next0);
540  }
541  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
542  }
543  return from_frame->n_vectors;
544 }
545 
546 static u8 *
547 format_lookup_trace (u8 * s, va_list * args)
548 {
549  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
550  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
551  lookup_trace_t * t = va_arg (*args, lookup_trace_t *);
552  uword indent = format_get_indent (s);
553  s = format (s, "%U fib-index:%d addr:%U load-balance:%d",
554  format_white_space, indent,
555  t->fib_index,
557  t->lbi);
558  return s;
559 }
560 
563  vlib_node_runtime_t * node,
564  vlib_frame_t * from_frame)
565 {
566  return (lookup_dpo_ip4_inline(vm, node, from_frame, 0, 0));
567 }
568 
570  .function = lookup_ip4_dst,
571  .name = "lookup-ip4-dst",
572  .vector_size = sizeof (u32),
573  .sibling_of = "ip4-lookup",
574  .format_trace = format_lookup_trace,
575 };
577 
580  vlib_node_runtime_t * node,
581  vlib_frame_t * from_frame)
582 {
583  return (lookup_dpo_ip4_inline(vm, node, from_frame, 0, 1));
584 }
585 
587  .function = lookup_ip4_dst_itf,
588  .name = "lookup-ip4-dst-itf",
589  .vector_size = sizeof (u32),
590  .sibling_of = "ip4-lookup",
591  .format_trace = format_lookup_trace,
592 };
594 
597  vlib_node_runtime_t * node,
598  vlib_frame_t * from_frame)
599 {
600  return (lookup_dpo_ip4_inline(vm, node, from_frame, 1, 0));
601 }
602 
604  .function = lookup_ip4_src,
605  .name = "lookup-ip4-src",
606  .vector_size = sizeof (u32),
607  .format_trace = format_lookup_trace,
608  .sibling_of = "ip4-lookup",
609 };
611 
614  vlib_node_runtime_t * node,
615  vlib_frame_t * from_frame,
616  int input_src_addr,
617  int table_from_interface)
618 {
620  u32 n_left_from, next_index, * from, * to_next;
621  u32 cpu_index = os_get_cpu_number();
622 
623  from = vlib_frame_vector_args (from_frame);
624  n_left_from = from_frame->n_vectors;
625 
626  next_index = node->cached_next_index;
627 
628  while (n_left_from > 0)
629  {
630  u32 n_left_to_next;
631 
632  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
633 
634  while (n_left_from >= 4 && n_left_to_next > 2)
635  {
636  u32 bi0, lkdi0, lbi0, fib_index0, next0, hash_c0;
637  flow_hash_config_t flow_hash_config0;
638  const ip6_address_t *input_addr0;
639  const load_balance_t *lb0;
640  const lookup_dpo_t * lkd0;
641  const ip6_header_t * ip0;
642  const dpo_id_t *dpo0;
643  vlib_buffer_t * b0;
644  u32 bi1, lkdi1, lbi1, fib_index1, next1, hash_c1;
645  flow_hash_config_t flow_hash_config1;
646  const ip6_address_t *input_addr1;
647  const load_balance_t *lb1;
648  const lookup_dpo_t * lkd1;
649  const ip6_header_t * ip1;
650  const dpo_id_t *dpo1;
651  vlib_buffer_t * b1;
652 
653  /* Prefetch next iteration. */
654  {
655  vlib_buffer_t * p2, * p3;
656 
657  p2 = vlib_get_buffer (vm, from[2]);
658  p3 = vlib_get_buffer (vm, from[3]);
659 
660  vlib_prefetch_buffer_header (p2, LOAD);
661  vlib_prefetch_buffer_header (p3, LOAD);
662 
665  }
666 
667  bi0 = from[0];
668  to_next[0] = bi0;
669  bi1 = from[1];
670  to_next[1] = bi1;
671  from += 2;
672  to_next += 2;
673  n_left_from -= 2;
674  n_left_to_next -= 2;
675 
676  b0 = vlib_get_buffer (vm, bi0);
677  ip0 = vlib_buffer_get_current (b0);
678  b1 = vlib_get_buffer (vm, bi1);
679  ip1 = vlib_buffer_get_current (b1);
680 
681  /* dst lookup was done by ip6 lookup */
682  lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
683  lkdi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
684  lkd0 = lookup_dpo_get(lkdi0);
685  lkd1 = lookup_dpo_get(lkdi1);
686 
687  /*
688  * choose between a lookup using the fib index in the DPO
689  * or getting the FIB index from the interface.
690  */
691  if (table_from_interface)
692  {
693  fib_index0 =
695  vnet_buffer(b0)->sw_if_index[VLIB_RX]);
696  fib_index1 =
698  vnet_buffer(b1)->sw_if_index[VLIB_RX]);
699  }
700  else
701  {
702  fib_index0 = lkd0->lkd_fib_index;
703  fib_index1 = lkd1->lkd_fib_index;
704  }
705 
706  /*
707  * choose between a source or destination address lookup in the table
708  */
709  if (input_src_addr)
710  {
711  input_addr0 = &ip0->src_address;
712  input_addr1 = &ip1->src_address;
713  }
714  else
715  {
716  input_addr0 = &ip0->dst_address;
717  input_addr1 = &ip1->dst_address;
718  }
719 
720  /* do src lookup */
722  fib_index0,
723  input_addr0);
725  fib_index1,
726  input_addr1);
727  lb0 = load_balance_get(lbi0);
728  lb1 = load_balance_get(lbi1);
729 
730  vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
731  vnet_buffer(b1)->sw_if_index[VLIB_TX] = fib_index1;
732 
733  /* Use flow hash to compute multipath adjacency. */
734  hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
735  hash_c1 = vnet_buffer (b1)->ip.flow_hash = 0;
736 
737  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
738  {
739  flow_hash_config0 = lb0->lb_hash_config;
740  hash_c0 = vnet_buffer (b0)->ip.flow_hash =
741  ip6_compute_flow_hash (ip0, flow_hash_config0);
742  }
743 
744  if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
745  {
746  flow_hash_config1 = lb1->lb_hash_config;
747  hash_c1 = vnet_buffer (b1)->ip.flow_hash =
748  ip6_compute_flow_hash (ip1, flow_hash_config1);
749  }
750 
751  dpo0 = load_balance_get_bucket_i(lb0,
752  (hash_c0 &
753  (lb0->lb_n_buckets_minus_1)));
754  dpo1 = load_balance_get_bucket_i(lb1,
755  (hash_c1 &
756  (lb1->lb_n_buckets_minus_1)));
757 
758  next0 = dpo0->dpoi_next_node;
759  next1 = dpo1->dpoi_next_node;
760  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
761  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
762 
764  (cm, cpu_index, lbi0, 1,
765  vlib_buffer_length_in_chain (vm, b0));
767  (cm, cpu_index, lbi1, 1,
768  vlib_buffer_length_in_chain (vm, b1));
769 
771  {
772  lookup_trace_t *tr = vlib_add_trace (vm, node,
773  b0, sizeof (*tr));
774  tr->fib_index = fib_index0;
775  tr->lbi = lbi0;
776  tr->addr.ip6 = *input_addr0;
777  }
779  {
780  lookup_trace_t *tr = vlib_add_trace (vm, node,
781  b1, sizeof (*tr));
782  tr->fib_index = fib_index1;
783  tr->lbi = lbi1;
784  tr->addr.ip6 = *input_addr1;
785  }
786  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
787  n_left_to_next, bi0, bi1,
788  next0, next1);
789  }
790  while (n_left_from > 0 && n_left_to_next > 0)
791  {
792  u32 bi0, lkdi0, lbi0, fib_index0, next0, hash_c0;
793  flow_hash_config_t flow_hash_config0;
794  const ip6_address_t *input_addr0;
795  const load_balance_t *lb0;
796  const lookup_dpo_t * lkd0;
797  const ip6_header_t * ip0;
798  const dpo_id_t *dpo0;
799  vlib_buffer_t * b0;
800 
801  bi0 = from[0];
802  to_next[0] = bi0;
803  from += 1;
804  to_next += 1;
805  n_left_from -= 1;
806  n_left_to_next -= 1;
807 
808  b0 = vlib_get_buffer (vm, bi0);
809  ip0 = vlib_buffer_get_current (b0);
810 
811  /* dst lookup was done by ip6 lookup */
812  lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
813  lkd0 = lookup_dpo_get(lkdi0);
814 
815  /*
816  * choose between a lookup using the fib index in the DPO
817  * or getting the FIB index from the interface.
818  */
819  if (table_from_interface)
820  {
821  fib_index0 =
823  vnet_buffer(b0)->sw_if_index[VLIB_RX]);
824  }
825  else
826  {
827  fib_index0 = lkd0->lkd_fib_index;
828  }
829 
830  /*
831  * choose between a source or destination address lookup in the table
832  */
833  if (input_src_addr)
834  {
835  input_addr0 = &ip0->src_address;
836  }
837  else
838  {
839  input_addr0 = &ip0->dst_address;
840  }
841 
842  /* do src lookup */
844  fib_index0,
845  input_addr0);
846  lb0 = load_balance_get(lbi0);
847 
848  vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
849 
850  /* Use flow hash to compute multipath adjacency. */
851  hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
852 
853  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
854  {
855  flow_hash_config0 = lb0->lb_hash_config;
856  hash_c0 = vnet_buffer (b0)->ip.flow_hash =
857  ip6_compute_flow_hash (ip0, flow_hash_config0);
858  }
859 
860  dpo0 = load_balance_get_bucket_i(lb0,
861  (hash_c0 &
862  (lb0->lb_n_buckets_minus_1)));
863 
864  next0 = dpo0->dpoi_next_node;
865  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
866 
868  (cm, cpu_index, lbi0, 1,
869  vlib_buffer_length_in_chain (vm, b0));
870 
872  {
873  lookup_trace_t *tr = vlib_add_trace (vm, node,
874  b0, sizeof (*tr));
875  tr->fib_index = fib_index0;
876  tr->lbi = lbi0;
877  tr->addr.ip6 = *input_addr0;
878  }
879  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
880  n_left_to_next, bi0, next0);
881  }
882  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
883  }
884  return from_frame->n_vectors;
885 }
886 
889  vlib_node_runtime_t * node,
890  vlib_frame_t * from_frame)
891 {
892  return (lookup_dpo_ip6_inline(vm, node, from_frame, 0 /*use src*/, 0));
893 }
894 
896  .function = lookup_ip6_dst,
897  .name = "lookup-ip6-dst",
898  .vector_size = sizeof (u32),
899  .format_trace = format_lookup_trace,
900  .sibling_of = "ip6-lookup",
901 };
903 
906  vlib_node_runtime_t * node,
907  vlib_frame_t * from_frame)
908 {
909  return (lookup_dpo_ip6_inline(vm, node, from_frame, 0 /*use src*/, 1));
910 }
911 
913  .function = lookup_ip6_dst_itf,
914  .name = "lookup-ip6-dst-itf",
915  .vector_size = sizeof (u32),
916  .format_trace = format_lookup_trace,
917  .sibling_of = "ip6-lookup",
918 };
920 
923  vlib_node_runtime_t * node,
924  vlib_frame_t * from_frame)
925 {
926  return (lookup_dpo_ip6_inline(vm, node, from_frame, 1, 0));
927 }
928 
930  .function = lookup_ip6_src,
931  .name = "lookup-ip6-src",
932  .vector_size = sizeof (u32),
933  .format_trace = format_lookup_trace,
934  .sibling_of = "ip6-lookup",
935 };
937 
940  vlib_node_runtime_t * node,
941  vlib_frame_t * from_frame,
942  int table_from_interface)
943 {
944  u32 n_left_from, next_index, * from, * to_next;
945  u32 cpu_index = os_get_cpu_number();
947 
948  from = vlib_frame_vector_args (from_frame);
949  n_left_from = from_frame->n_vectors;
950 
951  next_index = node->cached_next_index;
952 
953  while (n_left_from > 0)
954  {
955  u32 n_left_to_next;
956 
957  vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);
958 
959  /* while (n_left_from >= 4 && n_left_to_next >= 2) */
960  /* } */
961 
962  while (n_left_from > 0 && n_left_to_next > 0)
963  {
964  u32 bi0, lkdi0, lbi0, fib_index0, next0, hash0;
965  const mpls_unicast_header_t * hdr0;
966  const load_balance_t *lb0;
967  const lookup_dpo_t * lkd0;
968  const dpo_id_t *dpo0;
969  vlib_buffer_t * b0;
970 
971  bi0 = from[0];
972  to_next[0] = bi0;
973  from += 1;
974  to_next += 1;
975  n_left_from -= 1;
976  n_left_to_next -= 1;
977 
978  b0 = vlib_get_buffer (vm, bi0);
979  hdr0 = vlib_buffer_get_current (b0);
980 
981  /* dst lookup was done by mpls lookup */
982  lkdi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
983  lkd0 = lookup_dpo_get(lkdi0);
984 
985  /*
986  * choose between a lookup using the fib index in the DPO
987  * or getting the FIB index from the interface.
988  */
989  if (table_from_interface)
990  {
991  fib_index0 =
993  vnet_buffer(b0)->sw_if_index[VLIB_RX]);
994  }
995  else
996  {
997  fib_index0 = lkd0->lkd_fib_index;
998  }
999 
1000  /* do lookup */
1001  lbi0 = mpls_fib_table_forwarding_lookup (fib_index0, hdr0);
1002  lb0 = load_balance_get(lbi0);
1003 
1004  if (PREDICT_FALSE(lb0->lb_n_buckets > 1))
1005  {
1006  hash0 = vnet_buffer (b0)->ip.flow_hash =
1009  (lb0,
1010  (hash0 & (lb0->lb_n_buckets_minus_1)));
1011  }
1012  else
1013  {
1014  dpo0 = load_balance_get_bucket_i (lb0, 0);
1015  }
1016  next0 = dpo0->dpoi_next_node;
1017 
1018  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
1019 
1021  (cm, cpu_index, lbi0, 1,
1022  vlib_buffer_length_in_chain (vm, b0));
1023 
1024  vnet_buffer (b0)->mpls.ttl = ((char*)hdr0)[3];
1025  vnet_buffer (b0)->mpls.exp = (((char*)hdr0)[2] & 0xe) >> 1;
1026  vnet_buffer (b0)->mpls.first = 1;
1027  vlib_buffer_advance(b0, sizeof(*hdr0));
1028 
1030  {
1031  lookup_trace_t *tr = vlib_add_trace (vm, node,
1032  b0, sizeof (*tr));
1033  tr->fib_index = fib_index0;
1034  tr->lbi = lbi0;
1035  tr->hdr = *hdr0;
1036  }
1037 
1038  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
1039  n_left_to_next, bi0, next0);
1040  }
1041  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1042  }
1043  return from_frame->n_vectors;
1044 }
1045 
1046 static u8 *
1047 format_lookup_mpls_trace (u8 * s, va_list * args)
1048 {
1049  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1050  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1051  lookup_trace_t * t = va_arg (*args, lookup_trace_t *);
1052  uword indent = format_get_indent (s);
1054 
1055  hdr.label_exp_s_ttl = clib_net_to_host_u32(t->hdr.label_exp_s_ttl);
1056 
1057  s = format (s, "%U fib-index:%d hdr:%U load-balance:%d",
1058  format_white_space, indent,
1059  t->fib_index,
1060  format_mpls_header, hdr,
1061  t->lbi);
1062  return s;
1063 }
1064 
1067  vlib_node_runtime_t * node,
1068  vlib_frame_t * from_frame)
1069 {
1070  return (lookup_dpo_mpls_inline(vm, node, from_frame, 0));
1071 }
1072 
1074  .function = lookup_mpls_dst,
1075  .name = "lookup-mpls-dst",
1076  .vector_size = sizeof (u32),
1077  .sibling_of = "mpls-lookup",
1078  .format_trace = format_lookup_mpls_trace,
1079  .n_next_nodes = 0,
1080 };
1082 
1085  vlib_node_runtime_t * node,
1086  vlib_frame_t * from_frame)
1087 {
1088  return (lookup_dpo_mpls_inline(vm, node, from_frame, 1));
1089 }
1090 
1092  .function = lookup_mpls_dst_itf,
1093  .name = "lookup-mpls-dst-itf",
1094  .vector_size = sizeof (u32),
1095  .sibling_of = "mpls-lookup",
1096  .format_trace = format_lookup_mpls_trace,
1097  .n_next_nodes = 0,
1098 };
1100 
1101 static void
1103 {
1104  fib_show_memory_usage("Lookup",
1105  pool_elts(lookup_dpo_pool),
1106  pool_len(lookup_dpo_pool),
1107  sizeof(lookup_dpo_t));
1108 }
1109 
1110 const static dpo_vft_t lkd_vft = {
1112  .dv_unlock = lookup_dpo_unlock,
1113  .dv_format = format_lookup_dpo,
1114 };
1115 const static dpo_vft_t lkd_vft_w_mem_show = {
1117  .dv_unlock = lookup_dpo_unlock,
1118  .dv_format = format_lookup_dpo,
1119  .dv_mem_show = lookup_dpo_mem_show,
1120 };
1121 
1122 const static char* const lookup_src_ip4_nodes[] =
1123 {
1124  "lookup-ip4-src",
1125  NULL,
1126 };
1127 const static char* const lookup_src_ip6_nodes[] =
1128 {
1129  "lookup-ip6-src",
1130  NULL,
1131 };
1132 const static char* const * const lookup_src_nodes[DPO_PROTO_NUM] =
1133 {
1136  [DPO_PROTO_MPLS] = NULL,
1137 };
1138 
1139 const static char* const lookup_dst_ip4_nodes[] =
1140 {
1141  "lookup-ip4-dst",
1142  NULL,
1143 };
1144 const static char* const lookup_dst_ip6_nodes[] =
1145 {
1146  "lookup-ip6-dst",
1147  NULL,
1148 };
1149 const static char* const lookup_dst_mpls_nodes[] =
1150 {
1151  "lookup-mpls-dst",
1152  NULL,
1153 };
1154 const static char* const * const lookup_dst_nodes[DPO_PROTO_NUM] =
1155 {
1159 };
1160 
1161 const static char* const lookup_dst_from_interface_ip4_nodes[] =
1162 {
1163  "lookup-ip4-dst-itf",
1164  NULL,
1165 };
1166 const static char* const lookup_dst_from_interface_ip6_nodes[] =
1167 {
1168  "lookup-ip6-dst-itf",
1169  NULL,
1170 };
1171 const static char* const lookup_dst_from_interface_mpls_nodes[] =
1172 {
1173  "lookup-mpls-dst-itf",
1174  NULL,
1175 };
1176 const static char* const * const lookup_dst_from_interface_nodes[DPO_PROTO_NUM] =
1177 {
1181 };
1182 
1183 
1184 void
1186 {
1187  dpo_register(DPO_LOOKUP, &lkd_vft_w_mem_show, NULL);
1188 
1189  /*
1190  * There are various sorts of lookup; src or dst addr v4 /v6 etc.
1191  * there isn't an object type for each (there is only the lookup_dpo_t),
1192  * but, for performance reasons, there is a data plane function, and hence
1193  * VLIB node for each. VLIB graph node construction is based on DPO types
1194  * so we create sub-types.
1195  */
1202 }
static uword lookup_ip6_dst_itf(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:905
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:88
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:335
lookup_input_t lkd_input
Switch to use src or dst address.
Definition: lookup_dpo.h:69
lookup_dpo_t * lookup_dpo_pool
pool of all MPLS Label DPOs
Definition: lookup_dpo.c:44
vlib_combined_counter_main_t lbm_to_counters
Definition: load_balance.h:46
A representation of an MPLS label for imposition in the data-path.
Definition: lookup_dpo.h:52
static uword lookup_ip4_src(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:596
#define CLIB_UNUSED(x)
Definition: clib.h:79
A virtual function table regisitered for a DPO type.
Definition: dpo.h:330
struct lookup_trace_t_ lookup_trace_t
Lookup trace data.
static uword lookup_dpo_mpls_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int table_from_interface)
Definition: lookup_dpo.c:939
enum lookup_sub_type_t_ lookup_sub_type_t
Enumeration of the lookup subtypes.
fib_node_index_t fib_index
Definition: lookup_dpo.c:268
format_function_t format_mpls_header
Definition: mpls.h:92
lookup_sub_type_t_
Enumeration of the lookup subtypes.
Definition: lookup_dpo.c:30
ip4_address_t src_address
Definition: ip4_packet.h:163
void fib_table_lock(u32 fib_index, fib_protocol_t proto)
Release a reference counting lock on the table.
Definition: fib_table.c:1072
void lookup_dpo_add_or_lock_w_table_id(u32 table_id, dpo_proto_t proto, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:130
static const char *const *const lookup_dst_nodes[DPO_PROTO_NUM]
Definition: lookup_dpo.c:1154
static dpo_type_t lookup_dpo_sub_types[LOOKUP_SUB_TYPE_NUM]
An array of registered DPO type values for the sub-types.
Definition: lookup_dpo.c:49
#define NULL
Definition: clib.h:55
static u32 ip4_compute_flow_hash(const ip4_header_t *ip, flow_hash_config_t flow_hash_config)
Definition: ip4.h:295
static uword lookup_mpls_dst(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:1066
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
flow_hash_config_t lb_hash_config
the hash config to use when selecting a bucket.
Definition: load_balance.h:128
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 uword lookup_dpo_ip6_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int input_src_addr, int table_from_interface)
Definition: lookup_dpo.c:613
void lookup_dpo_add_or_lock_w_fib_index(fib_node_index_t fib_index, dpo_proto_t proto, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:116
format_function_t format_ip46_address
Definition: format.h:61
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
#define LOOKUP_SUB_TYPE_NUM
Definition: lookup_dpo.c:36
vlib_node_registration_t lookup_mpls_dst_itf_node
(constructor) VLIB_REGISTER_NODE (lookup_mpls_dst_itf_node)
Definition: lookup_dpo.c:1091
u8 * format_lookup_dpo(u8 *s, va_list *args)
Definition: lookup_dpo.c:150
u16 lkd_locks
Number of locks.
Definition: lookup_dpo.h:79
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
ip6_address_t src_address
Definition: ip6_packet.h:341
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:121
#define IP4_FIB_MTRIE_LEAF_EMPTY
Definition: ip4_mtrie.h:54
static ip4_fib_mtrie_leaf_t ip4_fib_mtrie_lookup_step(ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t current_leaf, const ip4_address_t *dst_address, u32 dst_address_byte_index)
Definition: ip4_mtrie.h:164
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip4_fib.c:211
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:249
enum dpo_type_t_ dpo_type_t
Common types of data-path objects New types can be dynamically added using dpo_register_new_type() ...
static const char *const lookup_dst_from_interface_ip6_nodes[]
Definition: lookup_dpo.c:1166
static lookup_dpo_t * lookup_dpo_alloc(void)
Definition: lookup_dpo.c:52
#define always_inline
Definition: clib.h:84
static uword format_get_indent(u8 *s)
Definition: format.h:72
u16 lb_n_buckets_minus_1
number of buckets in the load-balance - 1.
Definition: load_balance.h:93
ip4_address_t dst_address
Definition: ip4_packet.h:163
static uword lookup_ip6_src(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:922
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static const char *const *const lookup_src_nodes[DPO_PROTO_NUM]
Definition: lookup_dpo.c:1132
dpo_proto_t lkd_proto
The protocol of the FIB for the lookup, and hence the protocol of the packet.
Definition: lookup_dpo.h:64
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:164
u32 ip4_fib_mtrie_leaf_t
Definition: ip4_mtrie.h:52
static void lookup_dpo_unlock(dpo_id_t *dpo)
Definition: lookup_dpo.c:184
ip46_address_t addr
Definition: lookup_dpo.c:265
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:221
static uword lookup_ip4_dst_itf(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:579
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:236
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:392
dpo_type_t dpo_register_new_type(const dpo_vft_t *vft, const char *const *const *nodes)
Create and register a new DPO type.
Definition: dpo.c:261
static u32 ip4_fib_mtrie_leaf_get_adj_index(ip4_fib_mtrie_leaf_t n)
Definition: ip4_mtrie.h:76
vlib_node_registration_t lookup_ip4_dst_node
(constructor) VLIB_REGISTER_NODE (lookup_ip4_dst_node)
Definition: lookup_dpo.c:569
static u32 mpls_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: mpls_fib.h:102
vlib_node_registration_t lookup_ip6_src_node
(constructor) VLIB_REGISTER_NODE (lookup_ip6_src_node)
Definition: lookup_dpo.c:929
static void lookup_dpo_lock(dpo_id_t *dpo)
Definition: lookup_dpo.c:174
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:146
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
Definition: fib_table.c:1058
static lookup_dpo_t * lookup_dpo_get(index_t index)
Definition: lookup_dpo.h:101
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:202
static u32 mpls_compute_flow_hash(const mpls_unicast_header_t *hdr, flow_hash_config_t flow_hash_config)
Definition: mpls_lookup.h:27
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:188
static u32 ip6_compute_flow_hash(const ip6_header_t *ip, flow_hash_config_t flow_hash_config)
Definition: ip6.h:389
mpls_unicast_header_t hdr
Definition: lookup_dpo.c:266
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
The FIB DPO provieds;.
Definition: load_balance.h:84
#define PREDICT_FALSE(x)
Definition: clib.h:97
load_balance_main_t load_balance_main
The one instance of load-balance main.
Definition: load_balance.c:55
#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
void lookup_dpo_module_init(void)
Definition: lookup_dpo.c:1185
#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 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 const char *const lookup_src_ip6_nodes[]
Definition: lookup_dpo.c:1127
static const char *const lookup_dst_mpls_nodes[]
Definition: lookup_dpo.c:1149
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:169
vlib_node_registration_t lookup_ip6_dst_itf_node
(constructor) VLIB_REGISTER_NODE (lookup_ip6_dst_itf_node)
Definition: lookup_dpo.c:912
u32 ip6_fib_table_fwding_lookup(ip6_main_t *im, u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.c:339
static void ip4_src_fib_lookup_two(u32 src_fib_index0, u32 src_fib_index1, const ip4_address_t *addr0, const ip4_address_t *addr1, u32 *src_adj_index0, u32 *src_adj_index1)
Definition: lookup_dpo.c:225
static const char *const lookup_dst_from_interface_mpls_nodes[]
Definition: lookup_dpo.c:1171
Lookup trace data.
Definition: lookup_dpo.c:262
u16 n_vectors
Definition: node.h:344
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
vlib_main_t * vm
Definition: buffer.c:276
static uword lookup_mpls_dst_itf(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:1084
enum lookup_table_t_ lookup_table_t
Switch to use the packet&#39;s source or destination address for lookup.
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:80
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:85
static const char *const lookup_input_names[]
Definition: lookup_dpo.c:25
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
static const char *const lookup_dst_ip6_nodes[]
Definition: lookup_dpo.c:1144
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:157
vlib_node_registration_t lookup_mpls_dst_node
(constructor) VLIB_REGISTER_NODE (lookup_mpls_dst_node)
Definition: lookup_dpo.c:1073
enum lookup_input_t_ lookup_input_t
Switch to use the packet&#39;s source or destination address for lookup.
static const char *const lookup_dst_from_interface_ip4_nodes[]
Definition: lookup_dpo.c:1161
static uword lookup_ip6_dst(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:888
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:455
vlib_node_registration_t lookup_ip6_dst_node
(constructor) VLIB_REGISTER_NODE (lookup_ip6_dst_node)
Definition: lookup_dpo.c:895
#define ASSERT(truth)
#define IP4_FIB_MTRIE_LEAF_ROOT
Definition: ip4_mtrie.h:55
static void lookup_dpo_mem_show(void)
Definition: lookup_dpo.c:1102
unsigned int u32
Definition: types.h:88
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 cpu_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:211
ip6_main_t ip6_main
Definition: ip6_forward.c:2846
static const char *const lookup_src_ip4_nodes[]
Definition: lookup_dpo.c:1122
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:193
static const char *const lookup_dst_ip4_nodes[]
Definition: lookup_dpo.c:1139
static uword lookup_dpo_ip4_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int input_src_addr, int table_from_interface)
Definition: lookup_dpo.c:274
mpls_label_t label_exp_s_ttl
Definition: packet.h:31
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:954
static const char *const *const lookup_dst_from_interface_nodes[DPO_PROTO_NUM]
Definition: lookup_dpo.c:1176
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:201
static void lookup_dpo_add_or_lock_i(fib_node_index_t fib_index, dpo_proto_t proto, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:68
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:165
u64 uword
Definition: types.h:112
lookup_table_t lkd_table
Switch to use the table index passed, or the table of the input interface.
Definition: lookup_dpo.h:74
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
Definition: defs.h:47
#define DPO_PROTO_NUM
Definition: dpo.h:73
u8 * format_fib_table_name(u8 *s, va_list ap)
Format the description/name of the table.
Definition: fib_table.c:1094
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:162
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
static u8 * format_lookup_mpls_trace(u8 *s, va_list *args)
Definition: lookup_dpo.c:1047
#define LOOKUP_INPUTS
Definition: lookup_dpo.h:31
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
ip4_fib_mtrie_t mtrie
Definition: ip4.h:54
A collection of combined counters.
Definition: counter.h:180
static index_t mpls_fib_table_forwarding_lookup(u32 mpls_fib_index, const mpls_unicast_header_t *hdr)
Lookup a label and EOS bit in the MPLS_FIB table to retrieve the load-balance index to be used for pa...
Definition: mpls_fib.h:86
u8 * format_dpo_proto(u8 *s, va_list *args)
format a DPO protocol
Definition: dpo.c:149
vlib_node_registration_t lookup_ip4_dst_itf_node
(constructor) VLIB_REGISTER_NODE (lookup_ip4_dst_itf_node)
Definition: lookup_dpo.c:586
#define vnet_buffer(b)
Definition: buffer.h:294
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
Definition: node.h:158
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
u8 data[0]
Packet data.
Definition: buffer.h:152
static void ip4_src_fib_lookup_one(u32 src_fib_index0, const ip4_address_t *addr0, u32 *src_adj_index0)
Definition: lookup_dpo.c:204
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:194
vlib_node_registration_t lookup_ip4_src_node
(constructor) VLIB_REGISTER_NODE (lookup_ip4_src_node)
Definition: lookup_dpo.c:603
static index_t lookup_dpo_get_index(lookup_dpo_t *lkd)
Definition: lookup_dpo.c:62
static uword lookup_ip4_dst(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: lookup_dpo.c:562
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:158
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:74
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
fib_node_index_t lkd_fib_index
The FIB, or interface from which to get a FIB, in which to perform the next lookup;.
Definition: lookup_dpo.h:58
Definition: defs.h:46
static u8 * format_lookup_trace(u8 *s, va_list *args)
Definition: lookup_dpo.c:547
ip6_address_t dst_address
Definition: ip6_packet.h:341
ip4_fib_mtrie_leaf_t default_leaf
Definition: ip4_mtrie.h:145
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109