FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
replicate_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/lookup.h>
17 #include <vnet/dpo/replicate_dpo.h>
18 #include <vnet/dpo/drop_dpo.h>
19 #include <vnet/dpo/receive_dpo.h>
20 #include <vnet/adj/adj.h>
21 #include <vnet/mpls/mpls_types.h>
22 
23 /**
24  * the logger
25  */
27 
28 #define REP_DBG(_rep, _fmt, _args...) \
29 { \
30  vlib_log_debug(replicate_logger, \
31  "rep:[%U]:" _fmt, \
32  format_replicate, \
33  replicate_get_index(_rep), \
34  REPLICATE_FORMAT_NONE, \
35  ##_args); \
36 }
37 
38 #define foreach_replicate_dpo_error \
39 _(BUFFER_ALLOCATION_FAILURE, "Buffer Allocation Failure")
40 
41 typedef enum {
42 #define _(sym,str) REPLICATE_DPO_ERROR_##sym,
44 #undef _
47 
48 static char * replicate_dpo_error_strings[] = {
49 #define _(sym,string) string,
51 #undef _
52 };
53 
54 /**
55  * Pool of all DPOs. It's not static so the DP can have fast access
56  */
58 
59 /**
60  * The one instance of replicate main
61  */
63  .repm_counters = {
64  .name = "mroutes",
65  .stat_segment_name = "/net/mroute",
66  },
67 };
68 
69 static inline index_t
71 {
72  return (rep - replicate_pool);
73 }
74 
75 static inline dpo_id_t*
77 {
78  if (REP_HAS_INLINE_BUCKETS(rep))
79  {
80  return (rep->rep_buckets_inline);
81  }
82  else
83  {
84  return (rep->rep_buckets);
85  }
86 }
87 
88 static replicate_t *
90 {
91  replicate_t *rep;
92 
94  clib_memset(rep, 0, sizeof(*rep));
95 
97  replicate_get_index(rep));
99  replicate_get_index(rep));
100 
101  return (rep);
102 }
103 
104 static u8*
105 format_replicate_flags (u8 *s, va_list *args)
106 {
107  int flags = va_arg (*args, int);
108 
110  {
111  s = format (s, "none");
112  }
113  else if (flags & REPLICATE_FLAGS_HAS_LOCAL)
114  {
115  s = format (s, "has-local ");
116  }
117 
118  return (s);
119 }
120 
121 static u8*
124  u32 indent,
125  u8 *s)
126 {
128  replicate_t *rep;
129  dpo_id_t *buckets;
130  u32 i;
131 
132  repi &= ~MPLS_IS_REPLICATE;
133  rep = replicate_get(repi);
135  buckets = replicate_get_buckets(rep);
136 
137  s = format(s, "%U: ", format_dpo_type, DPO_REPLICATE);
138  s = format(s, "[index:%d buckets:%d ", repi, rep->rep_n_buckets);
139  s = format(s, "flags:[%U] ", format_replicate_flags, rep->rep_flags);
140  s = format(s, "to:[%Ld:%Ld]]", to.packets, to.bytes);
141 
142  for (i = 0; i < rep->rep_n_buckets; i++)
143  {
144  s = format(s, "\n%U", format_white_space, indent+2);
145  s = format(s, "[%d]", i);
146  s = format(s, " %U", format_dpo_id, &buckets[i], indent+6);
147  }
148  return (s);
149 }
150 
151 u8*
152 format_replicate (u8 * s, va_list * args)
153 {
154  index_t repi = va_arg(*args, index_t);
156 
157  return (replicate_format(repi, flags, 0, s));
158 }
159 static u8*
160 format_replicate_dpo (u8 * s, va_list * args)
161 {
162  index_t repi = va_arg(*args, index_t);
163  u32 indent = va_arg(*args, u32);
164 
165  return (replicate_format(repi, REPLICATE_FORMAT_DETAIL, indent, s));
166 }
167 
168 
169 static replicate_t *
170 replicate_create_i (u32 num_buckets,
171  dpo_proto_t rep_proto)
172 {
173  replicate_t *rep;
174 
175  rep = replicate_alloc_i();
176  rep->rep_n_buckets = num_buckets;
177  rep->rep_proto = rep_proto;
178 
179  if (!REP_HAS_INLINE_BUCKETS(rep))
180  {
182  rep->rep_n_buckets - 1,
184  }
185 
186  REP_DBG(rep, "create");
187 
188  return (rep);
189 }
190 
191 index_t
193  dpo_proto_t rep_proto)
194 {
195  return (replicate_get_index(replicate_create_i(n_buckets, rep_proto)));
196 }
197 
198 static inline void
200  u32 bucket,
201  dpo_id_t *buckets,
202  const dpo_id_t *next)
203 {
204  if (dpo_is_receive(&buckets[bucket]))
205  {
207  }
208  if (dpo_is_receive(next))
209  {
211  }
212  dpo_stack(DPO_REPLICATE, rep->rep_proto, &buckets[bucket], next);
213 }
214 
215 void
217  u32 bucket,
218  const dpo_id_t *next)
219 {
220  replicate_t *rep;
221  dpo_id_t *buckets;
222 
223  repi &= ~MPLS_IS_REPLICATE;
224  rep = replicate_get(repi);
225  buckets = replicate_get_buckets(rep);
226 
227  ASSERT(bucket < rep->rep_n_buckets);
228 
229  replicate_set_bucket_i(rep, bucket, buckets, next);
230 }
231 
232 int
234 {
235  replicate_t *rep;
236  index_t repi;
237 
238  if (DPO_REPLICATE != dpo->dpoi_type)
239  return (0);
240 
241  repi = dpo->dpoi_index & ~MPLS_IS_REPLICATE;
242  rep = replicate_get(repi);
243 
244  if (1 == rep->rep_n_buckets)
245  {
246  return (dpo_is_drop(replicate_get_bucket_i(rep, 0)));
247  }
248  return (0);
249 }
250 
251 const dpo_id_t *
253  u32 bucket)
254 {
255  replicate_t *rep;
256 
257  repi &= ~MPLS_IS_REPLICATE;
258  rep = replicate_get(repi);
259 
260  return (replicate_get_bucket_i(rep, bucket));
261 }
262 
263 
264 static load_balance_path_t *
266  dpo_proto_t drop_proto)
267 {
268  if (0 == vec_len(nhs))
269  {
271 
272  /*
273  * we need something for the replicate. so use the drop
274  */
275  vec_add2(nhs, nh, 1);
276 
277  nh->path_weight = 1;
278  dpo_copy(&nh->path_dpo, drop_dpo_get(drop_proto));
279  }
280 
281  return (nhs);
282 }
283 
284 /*
285  * Fill in adjacencies in block based on corresponding
286  * next hop adjacencies.
287  */
288 static void
291  dpo_id_t *buckets,
292  u32 n_buckets)
293 {
295  u16 bucket;
296 
297  bucket = 0;
298 
299  /*
300  * the next-hops have normalised weights. that means their sum is the number
301  * of buckets we need to fill.
302  */
303  vec_foreach (nh, nhs)
304  {
305  ASSERT(bucket < n_buckets);
306  replicate_set_bucket_i(rep, bucket++, buckets, &nh->path_dpo);
307  }
308 }
309 
310 static inline void
312  u32 n_buckets)
313 {
314  rep->rep_n_buckets = n_buckets;
315 }
316 
317 void
319  load_balance_path_t * next_hops)
320 {
322  dpo_id_t *tmp_dpo;
323  u32 ii, n_buckets;
324  replicate_t *rep;
325  index_t repi;
326 
327  ASSERT(DPO_REPLICATE == dpo->dpoi_type);
328  repi = dpo->dpoi_index & ~MPLS_IS_REPLICATE;
329  rep = replicate_get(repi);
331  rep->rep_proto);
332  n_buckets = vec_len(nhs);
333 
334  if (0 == rep->rep_n_buckets)
335  {
336  /*
337  * first time initialisation. no packets inflight, so we can write
338  * at leisure.
339  */
340  replicate_set_n_buckets(rep, n_buckets);
341 
342  if (!REP_HAS_INLINE_BUCKETS(rep))
344  rep->rep_n_buckets - 1,
346 
349  n_buckets);
350  }
351  else
352  {
353  /*
354  * This is a modification of an existing replicate.
355  * We need to ensure that packets in flight see a consistent state, that
356  * is the number of reported buckets the REP has
357  * is not more than it actually has. So if the
358  * number of buckets is increasing, we must update the bucket array first,
359  * then the reported number. vice-versa if the number of buckets goes down.
360  */
361  if (n_buckets == rep->rep_n_buckets)
362  {
363  /*
364  * no change in the number of buckets. we can simply fill what
365  * is new over what is old.
366  */
369  n_buckets);
370  }
371  else if (n_buckets > rep->rep_n_buckets)
372  {
373  /*
374  * we have more buckets. the old replicate map (if there is one)
375  * will remain valid, i.e. mapping to indices within range, so we
376  * update it last.
377  */
378  if (n_buckets > REP_NUM_INLINE_BUCKETS &&
380  {
381  /*
382  * the new increased number of buckets is crossing the threshold
383  * from the inline storage to out-line. Alloc the outline buckets
384  * first, then fixup the number. then reset the inlines.
385  */
386  ASSERT(NULL == rep->rep_buckets);
388  n_buckets - 1,
390 
392  rep->rep_buckets,
393  n_buckets);
395  replicate_set_n_buckets(rep, n_buckets);
396 
398 
399  for (ii = 0; ii < REP_NUM_INLINE_BUCKETS; ii++)
400  {
401  dpo_reset(&rep->rep_buckets_inline[ii]);
402  }
403  }
404  else
405  {
406  if (n_buckets <= REP_NUM_INLINE_BUCKETS)
407  {
408  /*
409  * we are not crossing the threshold and it's still inline buckets.
410  * we can write the new on the old..
411  */
414  n_buckets);
416  replicate_set_n_buckets(rep, n_buckets);
417  }
418  else
419  {
420  /*
421  * we are not crossing the threshold. We need a new bucket array to
422  * hold the increased number of choices.
423  */
424  dpo_id_t *new_buckets, *old_buckets, *tmp_dpo;
425 
426  new_buckets = NULL;
427  old_buckets = replicate_get_buckets(rep);
428 
429  vec_validate_aligned(new_buckets,
430  n_buckets - 1,
432 
433  replicate_fill_buckets(rep, nhs, new_buckets, n_buckets);
435  rep->rep_buckets = new_buckets;
437  replicate_set_n_buckets(rep, n_buckets);
438 
439  vec_foreach(tmp_dpo, old_buckets)
440  {
441  dpo_reset(tmp_dpo);
442  }
443  vec_free(old_buckets);
444  }
445  }
446  }
447  else
448  {
449  /*
450  * bucket size shrinkage.
451  */
452  if (n_buckets <= REP_NUM_INLINE_BUCKETS &&
454  {
455  /*
456  * the new decreased number of buckets is crossing the threshold
457  * from out-line storage to inline:
458  * 1 - Fill the inline buckets,
459  * 2 - fixup the number (and this point the inline buckets are
460  * used).
461  * 3 - free the outline buckets
462  */
464  rep->rep_buckets_inline,
465  n_buckets);
467  replicate_set_n_buckets(rep, n_buckets);
469 
470  vec_foreach(tmp_dpo, rep->rep_buckets)
471  {
472  dpo_reset(tmp_dpo);
473  }
474  vec_free(rep->rep_buckets);
475  }
476  else
477  {
478  /*
479  * not crossing the threshold.
480  * 1 - update the number to the smaller size
481  * 2 - write the new buckets
482  * 3 - reset those no longer used.
483  */
484  dpo_id_t *buckets;
485  u32 old_n_buckets;
486 
487  old_n_buckets = rep->rep_n_buckets;
488  buckets = replicate_get_buckets(rep);
489 
490  replicate_set_n_buckets(rep, n_buckets);
492 
494  buckets,
495  n_buckets);
496 
497  for (ii = n_buckets; ii < old_n_buckets; ii++)
498  {
499  dpo_reset(&buckets[ii]);
500  }
501  }
502  }
503  }
504 
505  vec_foreach (nh, nhs)
506  {
507  dpo_reset(&nh->path_dpo);
508  }
509  vec_free(nhs);
510 }
511 
512 static void
514 {
515  replicate_t *rep;
516 
517  rep = replicate_get(dpo->dpoi_index);
518 
519  rep->rep_locks++;
520 }
521 
522 index_t
524  index_t repi)
525 {
526  replicate_t *rep, *copy;
527 
528  rep = replicate_get(repi);
529 
530  if (rep->rep_flags == flags ||
532  {
533  /*
534  * we can include all the buckets from the original in the copy
535  */
536  return (repi);
537  }
538  else
539  {
540  /*
541  * caller doesn't want the local paths that the original has
542  */
543  if (rep->rep_n_buckets == 1)
544  {
545  /*
546  * original has only one bucket that is the local, so create
547  * a new one with only the drop
548  */
549  copy = replicate_create_i (1, rep->rep_proto);
550 
551  replicate_set_bucket_i(copy, 0,
552  replicate_get_buckets(copy),
553  drop_dpo_get(rep->rep_proto));
554  }
555  else
556  {
557  dpo_id_t *old_buckets, *copy_buckets;
558  u16 bucket, pos;
559 
560  copy = replicate_create_i(rep->rep_n_buckets - 1,
561  rep->rep_proto);
562 
563  rep = replicate_get(repi);
564  old_buckets = replicate_get_buckets(rep);
565  copy_buckets = replicate_get_buckets(copy);
566  pos = 0;
567 
568  for (bucket = 0; bucket < rep->rep_n_buckets; bucket++)
569  {
570  if (!dpo_is_receive(&old_buckets[bucket]))
571  {
572  replicate_set_bucket_i(copy, pos, copy_buckets,
573  (&old_buckets[bucket]));
574  pos++;
575  }
576  }
577  }
578  }
579 
580  return (replicate_get_index(copy));
581 }
582 
583 static void
585 {
586  dpo_id_t *buckets;
587  int i;
588 
589  buckets = replicate_get_buckets(rep);
590 
591  for (i = 0; i < rep->rep_n_buckets; i++)
592  {
593  dpo_reset(&buckets[i]);
594  }
595 
596  REP_DBG(rep, "destroy");
597  if (!REP_HAS_INLINE_BUCKETS(rep))
598  {
599  vec_free(rep->rep_buckets);
600  }
601 
602  pool_put(replicate_pool, rep);
603 }
604 
605 static void
607 {
608  replicate_t *rep;
609 
610  rep = replicate_get(dpo->dpoi_index);
611 
612  rep->rep_locks--;
613 
614  if (0 == rep->rep_locks)
615  {
616  replicate_destroy(rep);
617  }
618 }
619 
620 static void
622 {
623  fib_show_memory_usage("replicate",
626  sizeof(replicate_t));
627 }
628 
629 const static dpo_vft_t rep_vft = {
631  .dv_unlock = replicate_unlock,
632  .dv_format = format_replicate_dpo,
633  .dv_mem_show = replicate_mem_show,
634 };
635 
636 /**
637  * @brief The per-protocol VLIB graph nodes that are assigned to a replicate
638  * object.
639  *
640  * this means that these graph nodes are ones from which a replicate is the
641  * parent object in the DPO-graph.
642  */
643 const static char* const replicate_ip4_nodes[] =
644 {
645  "ip4-replicate",
646  NULL,
647 };
648 const static char* const replicate_ip6_nodes[] =
649 {
650  "ip6-replicate",
651  NULL,
652 };
653 const static char* const replicate_mpls_nodes[] =
654 {
655  "mpls-replicate",
656  NULL,
657 };
658 
659 const static char* const * const replicate_nodes[DPO_PROTO_NUM] =
660 {
664 };
665 
666 void
668 {
670  replicate_logger = vlib_log_register_class("dpo", "replicate");
671 }
672 
673 static clib_error_t *
675  unformat_input_t * input,
676  vlib_cli_command_t * cmd)
677 {
678  index_t repi = INDEX_INVALID;
679 
681  {
682  if (unformat (input, "%d", &repi))
683  ;
684  else
685  break;
686  }
687 
688  if (INDEX_INVALID != repi)
689  {
691  vlib_cli_output (vm, "no such index %d", repi);
692  else
693  vlib_cli_output (vm, "%U", format_replicate, repi,
695  }
696  else
697  {
698  replicate_t *rep;
699 
701  {
703  replicate_get_index(rep),
705  }
706  }
707 
708  return 0;
709 }
710 
712  .path = "show replicate",
713  .short_help = "show replicate [<index>]",
714  .function = replicate_show,
715 };
716 
717 typedef struct replicate_trace_t_
718 {
722 
723 static uword
727 {
730  u32 n_left_from, * from, * to_next, next_index;
732 
734  n_left_from = frame->n_vectors;
735  next_index = node->cached_next_index;
736 
737  while (n_left_from > 0)
738  {
739  u32 n_left_to_next;
740 
742  to_next, n_left_to_next);
743 
744  while (n_left_from > 0 && n_left_to_next > 0)
745  {
746  u32 next0, ci0, bi0, bucket, repi0;
747  const replicate_t *rep0;
748  vlib_buffer_t * b0, *c0;
749  const dpo_id_t *dpo0;
750  u8 num_cloned;
751 
752  bi0 = from[0];
753  from += 1;
754  n_left_from -= 1;
755 
756  b0 = vlib_get_buffer (vm, bi0);
757  repi0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
758  rep0 = replicate_get(repi0);
759 
761  cm, thread_index, repi0, 1,
763 
764  vec_validate (rm->clones[thread_index], rep0->rep_n_buckets - 1);
765 
766  num_cloned = vlib_buffer_clone (vm, bi0, rm->clones[thread_index],
767  rep0->rep_n_buckets,
769 
770  if (num_cloned != rep0->rep_n_buckets)
771  {
773  (vm, node->node_index,
774  REPLICATE_DPO_ERROR_BUFFER_ALLOCATION_FAILURE, 1);
775  }
776 
777  for (bucket = 0; bucket < num_cloned; bucket++)
778  {
779  ci0 = rm->clones[thread_index][bucket];
780  c0 = vlib_get_buffer(vm, ci0);
781 
782  to_next[0] = ci0;
783  to_next += 1;
784  n_left_to_next -= 1;
785 
786  dpo0 = replicate_get_bucket_i(rep0, bucket);
787  next0 = dpo0->dpoi_next_node;
788  vnet_buffer (c0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
789 
790  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
791  {
793 
794  t = vlib_add_trace (vm, node, c0, sizeof (*t));
795  t->rep_index = repi0;
796  t->dpo = *dpo0;
797  }
798 
800  to_next, n_left_to_next,
801  ci0, next0);
802  if (PREDICT_FALSE (n_left_to_next == 0))
803  {
804  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
805  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
806  }
807  }
809  }
810 
811  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
812  }
813 
814  return frame->n_vectors;
815 }
816 
817 static u8 *
818 format_replicate_trace (u8 * s, va_list * args)
819 {
820  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
821  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
822  replicate_trace_t *t = va_arg (*args, replicate_trace_t *);
823 
824  s = format (s, "replicate: %d via %U",
825  t->rep_index,
826  format_dpo_id, &t->dpo, 0);
827  return s;
828 }
829 
830 static uword
834 {
835  return (replicate_inline (vm, node, frame));
836 }
837 
838 /**
839  * @brief IP4 replication node
840  */
842  .function = ip4_replicate,
843  .name = "ip4-replicate",
844  .vector_size = sizeof (u32),
845 
847  .error_strings = replicate_dpo_error_strings,
848 
849  .format_trace = format_replicate_trace,
850  .n_next_nodes = 1,
851  .next_nodes = {
852  [0] = "ip4-drop",
853  },
854 };
855 
856 static uword
860 {
861  return (replicate_inline (vm, node, frame));
862 }
863 
864 /**
865  * @brief IPv6 replication node
866  */
868  .function = ip6_replicate,
869  .name = "ip6-replicate",
870  .vector_size = sizeof (u32),
871 
873  .error_strings = replicate_dpo_error_strings,
874 
875  .format_trace = format_replicate_trace,
876  .n_next_nodes = 1,
877  .next_nodes = {
878  [0] = "ip6-drop",
879  },
880 };
881 
882 static uword
886 {
887  return (replicate_inline (vm, node, frame));
888 }
889 
890 /**
891  * @brief MPLS replication node
892  */
894  .function = mpls_replicate,
895  .name = "mpls-replicate",
896  .vector_size = sizeof (u32),
897 
899  .error_strings = replicate_dpo_error_strings,
900 
901  .format_trace = format_replicate_trace,
902  .n_next_nodes = 1,
903  .next_nodes = {
904  [0] = "mpls-drop",
905  },
906 };
907 
908 clib_error_t *
910 {
912 
914 
915  return 0;
916 }
917 
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
to
u32 * to
Definition: interface_output.c:1078
foreach_replicate_dpo_error
#define foreach_replicate_dpo_error
Definition: replicate_dpo.c:38
dpo_is_drop
int dpo_is_drop(const dpo_id_t *dpo)
The Drop DPO will drop all packets, no questions asked.
Definition: drop_dpo.c:33
replicate_nodes
const static char *const *const replicate_nodes[DPO_PROTO_NUM]
Definition: replicate_dpo.c:659
dpo_id_t_::dpoi_next_node
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:186
adj.h
vlib_num_workers
static u32 vlib_num_workers()
Definition: threads.h:354
dpo_id_t_::dpoi_index
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:190
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:492
replicate_lock
static void replicate_lock(dpo_id_t *dpo)
Definition: replicate_dpo.c:513
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
ip6_replicate
static uword ip6_replicate(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: replicate_dpo.c:857
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
dpo_proto_t
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
dpo_id_t_::dpoi_type
dpo_type_t dpoi_type
the type
Definition: dpo.h:178
REP_DBG
#define REP_DBG(_rep, _fmt, _args...)
Definition: replicate_dpo.c:28
vlib_log_class_t
u32 vlib_log_class_t
Definition: vlib.h:52
REP_NUM_INLINE_BUCKETS
#define REP_NUM_INLINE_BUCKETS
The number of buckets that a load-balance object can have and still fit in one cache-line.
Definition: replicate_dpo.h:47
pool_get_aligned
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:249
next
u16 * next
Definition: nat44_ei_out2in.c:718
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
replicate_get_bucket_i
static const dpo_id_t * replicate_get_bucket_i(const replicate_t *rep, u32 bucket)
Definition: replicate_dpo.h:156
vlib_cli_command_t::path
char * path
Definition: cli.h:96
format_replicate
u8 * format_replicate(u8 *s, va_list *args)
Definition: replicate_dpo.c:152
REP_HAS_INLINE_BUCKETS
#define REP_HAS_INLINE_BUCKETS(_rep)
Definition: replicate_dpo.h:152
u16
unsigned short u16
Definition: types.h:57
format_dpo_type
u8 * format_dpo_type(u8 *s, va_list *args)
format a DPO type
Definition: dpo.c:140
dpo_is_receive
int dpo_is_receive(const dpo_id_t *dpo)
Definition: receive_dpo.c:29
vlib_validate_combined_counter
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:119
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
replicate_dpo_init
clib_error_t * replicate_dpo_init(vlib_main_t *vm)
Definition: replicate_dpo.c:909
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
REPLICATE_DPO_N_ERROR
@ REPLICATE_DPO_N_ERROR
Definition: replicate_dpo.c:45
replicate_t_
The FIB DPO provieds;.
Definition: replicate_dpo.h:63
vlib_combined_counter_main_t::name
char * name
The counter collection's name.
Definition: counter.h:206
VLIB_BUFFER_CLONE_HEAD_SIZE
#define VLIB_BUFFER_CLONE_HEAD_SIZE
Definition: buffer.h:61
replicate_multipath_next_hop_fixup
static load_balance_path_t * replicate_multipath_next_hop_fixup(load_balance_path_t *nhs, dpo_proto_t drop_proto)
Definition: replicate_dpo.c:265
nhs
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:313
unformat_input_t
struct _unformat_input_t unformat_input_t
vlib_frame_t
Definition: node.h:372
drop_dpo.h
vlib_buffer_length_in_chain
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:433
replicate_show
static clib_error_t * replicate_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: replicate_dpo.c:674
replicate_trace_t_
Definition: replicate_dpo.c:717
replicate_dpo.h
replicate_t_::rep_locks
u32 rep_locks
The number of locks, which is approximately the number of users, of this load-balance.
Definition: replicate_dpo.h:93
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ip4_replicate_node
vlib_node_registration_t ip4_replicate_node
IP4 replication node.
Definition: replicate_dpo.c:841
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
format_replicate_dpo
static u8 * format_replicate_dpo(u8 *s, va_list *args)
Definition: replicate_dpo.c:160
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
replicate_t_::rep_n_buckets
u16 rep_n_buckets
number of buckets in the replicate.
Definition: replicate_dpo.h:73
replicate_mem_show
static void replicate_mem_show(void)
Definition: replicate_dpo.c:621
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
receive_dpo.h
MPLS_IS_REPLICATE
#define MPLS_IS_REPLICATE
The top bit of the index, which is the result of the MPLS lookup is used to determine if the DPO is a...
Definition: mpls_types.h:66
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
dpo_stack
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:535
ip6_replicate_node
vlib_node_registration_t ip6_replicate_node
IPv6 replication node.
Definition: replicate_dpo.c:867
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vlib_counter_t
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:208
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
replicate_set_bucket
void replicate_set_bucket(index_t repi, u32 bucket, const dpo_id_t *next)
Definition: replicate_dpo.c:216
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
index_t
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:43
ip4_replicate
static uword ip4_replicate(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: replicate_dpo.c:831
replicate_trace_t
struct replicate_trace_t_ replicate_trace_t
replicate_ip4_nodes
const static char *const replicate_ip4_nodes[]
The per-protocol VLIB graph nodes that are assigned to a replicate object.
Definition: replicate_dpo.c:643
fib_show_memory_usage
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
uword
u64 uword
Definition: types.h:112
vlib_zero_combined_counter
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:298
replicate_main_t_::clones
u32 ** clones
Definition: replicate_dpo.h:38
replicate_destroy
static void replicate_destroy(replicate_t *rep)
Definition: replicate_dpo.c:584
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
replicate_unlock
static void replicate_unlock(dpo_id_t *dpo)
Definition: replicate_dpo.c:606
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
vlib_buffer_clone
static u16 vlib_buffer_clone(vlib_main_t *vm, u32 src_buffer, u32 *buffers, u16 n_buffers, u16 head_end_offset)
Create multiple clones of buffer and store them in the supplied array.
Definition: buffer_funcs.h:1328
replicate_create
index_t replicate_create(u32 n_buckets, dpo_proto_t rep_proto)
Definition: replicate_dpo.c:192
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:591
replicate_ip6_nodes
const static char *const replicate_ip6_nodes[]
Definition: replicate_dpo.c:648
replicate_dpo_error_strings
static char * replicate_dpo_error_strings[]
Definition: replicate_dpo.c:48
replicate_dpo_error_t
replicate_dpo_error_t
Definition: replicate_dpo.c:41
rep_vft
const static dpo_vft_t rep_vft
Definition: replicate_dpo.c:629
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
nh
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
dpo_vft_t_::dv_lock
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:428
replicate_t_::rep_flags
replicate_flags_t rep_flags
Flags specifying the replicate properties/behaviour.
Definition: replicate_dpo.h:85
CLIB_MEMORY_BARRIER
#define CLIB_MEMORY_BARRIER()
Definition: clib.h:137
REPLICATE_FLAGS_NONE
@ REPLICATE_FLAGS_NONE
Definition: replicate_dpo.h:54
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
replicate_mpls_nodes
const static char *const replicate_mpls_nodes[]
Definition: replicate_dpo.c:653
format_dpo_id
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:150
replicate_trace_t_::rep_index
index_t rep_index
Definition: replicate_dpo.c:719
mpls_types.h
replicate_is_drop
int replicate_is_drop(const dpo_id_t *dpo)
Definition: replicate_dpo.c:233
format_replicate_flags
static u8 * format_replicate_flags(u8 *s, va_list *args)
Definition: replicate_dpo.c:105
replicate_get_buckets
static dpo_id_t * replicate_get_buckets(replicate_t *rep)
Definition: replicate_dpo.c:76
vlib_get_combined_counter
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:272
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
pool_len
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:139
vlib_validate_buffer_enqueue_x1
#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:224
dpo_copy
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:264
replicate_main_t_
replicate main
Definition: replicate_dpo.h:33
replicate_t_::rep_buckets
dpo_id_t * rep_buckets
Vector of buckets containing the next DPOs, sized as repo_num.
Definition: replicate_dpo.h:98
replicate_set_n_buckets
static void replicate_set_n_buckets(replicate_t *rep, u32 n_buckets)
Definition: replicate_dpo.c:311
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
vlib_combined_counter_main_t
A collection of combined counters.
Definition: counter.h:203
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
replicate_logger
vlib_log_class_t replicate_logger
the logger
Definition: replicate_dpo.c:26
DPO_PROTO_IP6
@ DPO_PROTO_IP6
Definition: dpo.h:65
DPO_PROTO_MPLS
@ DPO_PROTO_MPLS
Definition: dpo.h:66
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
REPLICATE_FORMAT_DETAIL
@ REPLICATE_FORMAT_DETAIL
Definition: replicate_dpo.h:117
replicate_main_t_::repm_counters
vlib_combined_counter_main_t repm_counters
Definition: replicate_dpo.h:35
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
replicate_t_::rep_buckets_inline
dpo_id_t rep_buckets_inline[REP_NUM_INLINE_BUCKETS]
The rest of the cache line is used for buckets.
Definition: replicate_dpo.h:106
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
mpls_replicate_node
vlib_node_registration_t mpls_replicate_node
MPLS replication node.
Definition: replicate_dpo.c:893
mpls_replicate
static uword mpls_replicate(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: replicate_dpo.c:883
REPLICATE_FLAGS_HAS_LOCAL
@ REPLICATE_FLAGS_HAS_LOCAL
Definition: replicate_dpo.h:55
replicate_trace_t_::dpo
dpo_id_t dpo
Definition: replicate_dpo.c:720
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
replicate_module_init
void replicate_module_init(void)
Definition: replicate_dpo.c:667
drop_dpo_get
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
vlib_node_t
Definition: node.h:247
dpo_vft_t_
A virtual function table regisitered for a DPO type.
Definition: dpo.h:423
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
lookup.h
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
replicate_format_flags_t
enum replicate_format_flags_t_ replicate_format_flags_t
Flags controlling load-balance formatting/display.
format_replicate_trace
static u8 * format_replicate_trace(u8 *s, va_list *args)
Definition: replicate_dpo.c:818
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
replicate_flags_t
enum replicate_flags_t_ replicate_flags_t
Flags on the replicate DPO.
replicate_format
static u8 * replicate_format(index_t repi, replicate_format_flags_t flags, u32 indent, u8 *s)
Definition: replicate_dpo.c:122
replicate_create_i
static replicate_t * replicate_create_i(u32 num_buckets, dpo_proto_t rep_proto)
Definition: replicate_dpo.c:170
replicate_alloc_i
static replicate_t * replicate_alloc_i(void)
Definition: replicate_dpo.c:89
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
replicate_get_index
static index_t replicate_get_index(const replicate_t *rep)
Definition: replicate_dpo.c:70
replicate_get
static replicate_t * replicate_get(index_t repi)
Definition: replicate_dpo.h:146
replicate_main
replicate_main_t replicate_main
The one instance of replicate main.
Definition: replicate_dpo.c:62
vlib_node_runtime_t
Definition: node.h:454
replicate_set_bucket_i
static void replicate_set_bucket_i(replicate_t *rep, u32 bucket, dpo_id_t *buckets, const dpo_id_t *next)
Definition: replicate_dpo.c:199
replicate_fill_buckets
static void replicate_fill_buckets(replicate_t *rep, load_balance_path_t *nhs, dpo_id_t *buckets, u32 n_buckets)
Definition: replicate_dpo.c:289
vlib_cli_command_t
Definition: cli.h:92
from
from
Definition: nat44_ei_hairpinning.c:415
INDEX_INVALID
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
vlib_get_next_frame
#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:395
REPLICATE_FORMAT_NONE
@ REPLICATE_FORMAT_NONE
Definition: replicate_dpo.h:116
load_balance_path_t_
One path from an [EU]CMP set that the client wants to add to a load-balance object.
Definition: load_balance.h:62
replicate_multipath_update
void replicate_multipath_update(const dpo_id_t *dpo, load_balance_path_t *next_hops)
Definition: replicate_dpo.c:318
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
dpo_reset
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:234
replicate_inline
static uword replicate_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: replicate_dpo.c:724
replicate_show_command
static vlib_cli_command_t replicate_show_command
(constructor) VLIB_CLI_COMMAND (replicate_show_command)
Definition: replicate_dpo.c:711
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
replicate_t_::rep_proto
dpo_proto_t rep_proto
The protocol of packets that traverse this REP.
Definition: replicate_dpo.h:80
DPO_PROTO_NUM
#define DPO_PROTO_NUM
Definition: dpo.h:72
replicate_pool
replicate_t * replicate_pool
Pool of all DPOs.
Definition: replicate_dpo.c:57
replicate_dup
index_t replicate_dup(replicate_flags_t flags, index_t repi)
Definition: replicate_dpo.c:523
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
format_white_space
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
dpo_register
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:329
DPO_REPLICATE
@ DPO_REPLICATE
Definition: dpo.h:105
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
replicate_get_bucket
const dpo_id_t * replicate_get_bucket(index_t repi, u32 bucket)
Definition: replicate_dpo.c:252
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105