FD.io VPP  v16.06
Vector Packet Processing
node_funcs.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * node_funcs.h: processing nodes global functions/inlines
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #ifndef included_vlib_node_funcs_h
41 #define included_vlib_node_funcs_h
42 
43 #include <vppinfra/fifo.h>
44 
47 { return vec_elt (vm->node_main.nodes, i); }
48 
50 vlib_get_next_node (vlib_main_t * vm, u32 node_index, u32 next_index)
51 {
52  vlib_node_main_t * nm = &vm->node_main;
53  vlib_node_t * n;
54 
55  n = vec_elt (nm->nodes, node_index);
56  ASSERT (next_index < vec_len (n->next_nodes));
57  return vlib_get_node (vm, n->next_nodes[next_index]);
58 }
59 
62 {
63  vlib_node_main_t * nm = &vm->node_main;
64  vlib_node_t * n = vec_elt (nm->nodes, node_index);
65  vlib_process_t * p;
66  if (n->type != VLIB_NODE_TYPE_PROCESS)
67  return vec_elt_at_index (nm->nodes_by_type[n->type], n->runtime_index);
68  else
69  {
70  p = vec_elt (nm->processes, n->runtime_index);
71  return &p->node_runtime;
72  }
73 }
74 
75 always_inline void *
77 {
78  vlib_node_runtime_t * r = vlib_node_get_runtime (vm, node_index);
79  return r->runtime_data;
80 }
81 
82 always_inline void
84  void * runtime_data,
85  u32 n_runtime_data_bytes)
86 {
87  vlib_node_t * n = vlib_get_node (vm, node_index);
88  vlib_node_runtime_t * r = vlib_node_get_runtime (vm, node_index);
89 
90  n->runtime_data_bytes = n_runtime_data_bytes;
92  vec_add (n->runtime_data, runtime_data, n_runtime_data_bytes);
93 
94  ASSERT (vec_len (n->runtime_data) <= sizeof (r->runtime_data));
95  if (vec_len (n->runtime_data) > 0)
97 }
98 
99 always_inline void
101 {
102  vlib_node_main_t * nm = &vm->node_main;
103  vlib_node_t * n;
105 
106  n = vec_elt (nm->nodes, node_index);
107  if (n->type == VLIB_NODE_TYPE_PROCESS)
108  {
110  r = &p->node_runtime;
111 
112  /* When disabling make sure flags are cleared. */
116  }
117  else
119 
120  ASSERT (new_state < VLIB_N_NODE_STATE);
121 
122  if (n->type == VLIB_NODE_TYPE_INPUT)
123  {
125  nm->input_node_counts_by_state[n->state] -= 1;
126  nm->input_node_counts_by_state[new_state] += 1;
127  }
128 
129  n->state = new_state;
130  r->state = new_state;
131 }
132 
133 always_inline void
135 {
136  vlib_node_main_t * nm = &vm->node_main;
137  vlib_node_t * n = vec_elt (nm->nodes, node_index);
140 }
141 
144 {
145  vlib_node_main_t * nm = &vm->node_main;
147  return vec_elt (nm->processes, node->runtime_index);
148 }
149 
150 /* Fetches frame with given handle. */
153 {
154  vlib_frame_t * f;
155  u32 cpu_index = frame_index & VLIB_CPU_MASK;
156  u32 offset = frame_index & VLIB_OFFSET_MASK;
157  vm = vlib_mains ? vlib_mains[cpu_index] : vm;
158  f = vm->heap_base + offset;
159  return f;
160 }
161 
164 {
165  u32 i;
166 
167  ASSERT (((uword)f & VLIB_CPU_MASK)==0);
168 
169  vm = vlib_mains ? vlib_mains[f->cpu_index] : vm;
170 
171  i = ((u8 *) f - (u8 *) vm->heap_base);
172  return i | f->cpu_index;
173 }
174 
176 vlib_get_frame (vlib_main_t * vm, uword frame_index)
177 {
178  vlib_frame_t * f = vlib_get_frame_no_check (vm, frame_index);
180  return f;
181 }
182 
185 {
187  ASSERT (vlib_get_frame (vm, i) == f);
188  return i;
189 }
190 
191 /* Byte alignment for vector arguments. */
192 #define VLIB_FRAME_VECTOR_ALIGN (1 << 4)
193 
196 {
197  return round_pow2 (sizeof (vlib_frame_t) + scalar_size,
199 }
200 
201 always_inline void *
203 {
204  return (void *) f + vlib_frame_vector_byte_offset (f->scalar_size);
205 }
206 
207 /* Scalar data lies before aligned vector data. */
208 always_inline void *
210 { return vlib_frame_vector_args (f) - f->scalar_size; }
211 
215  u32 next_index)
216 {
217  vlib_node_main_t * nm = &vm->node_main;
218  vlib_next_frame_t * nf;
219 
220  ASSERT (next_index < n->n_next_nodes);
221  nf = vec_elt_at_index (nm->next_frames,
222  n->next_frame_index + next_index);
223 
224  if (CLIB_DEBUG > 0)
225  {
226  vlib_node_t * node, * next;
227  node = vec_elt (nm->nodes, n->node_index);
228  next = vec_elt (nm->nodes, node->next_nodes[next_index]);
229  ASSERT (nf->node_runtime_index == next->runtime_index);
230  }
231 
232  return nf;
233 }
234 
237  u32 node_index,
238  u32 next_index)
239 {
240  vlib_node_main_t * nm = &vm->node_main;
241  vlib_node_t * n;
243 
244  n = vec_elt (nm->nodes, node_index);
246  return vlib_node_runtime_get_next_frame (vm, r, next_index);
247 }
248 
249 vlib_frame_t *
251  vlib_node_runtime_t * node,
252  u32 next_index,
253  u32 alloc_new_frame);
254 
255 #define vlib_get_next_frame_macro(vm,node,next_index,vectors,n_vectors_left,alloc_new_frame) \
256 do { \
257  vlib_frame_t * _f \
258  = vlib_get_next_frame_internal ((vm), (node), (next_index), \
259  (alloc_new_frame)); \
260  u32 _n = _f->n_vectors; \
261  (vectors) = vlib_frame_vector_args (_f) + _n * sizeof ((vectors)[0]); \
262  (n_vectors_left) = VLIB_FRAME_SIZE - _n; \
263 } while (0)
264 
265 #define vlib_get_next_frame(vm,node,next_index,vectors,n_vectors_left) \
266  vlib_get_next_frame_macro (vm, node, next_index, \
267  vectors, n_vectors_left, \
268  /* alloc new frame */ 0)
269 
270 #define vlib_get_new_next_frame(vm,node,next_index,vectors,n_vectors_left) \
271  vlib_get_next_frame_macro (vm, node, next_index, \
272  vectors, n_vectors_left, \
273  /* alloc new frame */ 1)
274 
275 void
278  u32 next_index,
279  u32 n_packets_left);
280 
281 /* Combination get plus put. Returns vector argument just added. */
282 #define vlib_set_next_frame(vm,node,next_index,v) \
283 ({ \
284  uword _n_left; \
285  vlib_get_next_frame ((vm), (node), (next_index), (v), _n_left); \
286  ASSERT (_n_left > 0); \
287  vlib_put_next_frame ((vm), (node), (next_index), _n_left - 1); \
288  (v); \
289 })
290 
291 always_inline void
293  vlib_node_runtime_t * node,
294  u32 next_index,
295  u32 buffer_index)
296 {
297  u32 * p;
298  p = vlib_set_next_frame (vm, node, next_index, p);
299  p[0] = buffer_index;
300 }
301 
302 vlib_frame_t * vlib_get_frame_to_node (vlib_main_t * vm, u32 to_node_index);
303 void vlib_put_frame_to_node (vlib_main_t * vm, u32 to_node_index, vlib_frame_t * f);
304 
307 {
308  vlib_node_main_t * nm = &vm->node_main;
309  return vec_elt (nm->processes, nm->current_process_index);
310 }
311 
314 { return vm->node_main.current_process_index != ~0; }
315 
319 
320 /* Anything less than 1e-6 is considered zero. */
323 { return dt < 1e-6; }
324 
327 {
328  uword r;
329  vlib_node_main_t * nm = &vm->node_main;
331  u64 dt_cpu = dt * vm->clib_time.clocks_per_second;
332 
335 
339  {
340  p->resume_cpu_time = clib_cpu_time_now () + dt_cpu;
342  }
343 
344  return r;
345 }
346 
347 always_inline void
349 {
352  if (is_one_time_event)
354  clib_bitmap_andnoti (p->one_time_event_type_bitmap, t);
355 }
356 
357 always_inline void
359 {
362  vlib_process_free_event_type (p, t, /* is_one_time_event */ 1);
363 }
364 
365 always_inline void *
366 vlib_process_get_event_data (vlib_main_t * vm, uword * return_event_type_opaque)
367 {
368  vlib_node_main_t * nm = &vm->node_main;
369  vlib_process_t * p;
371  uword t, l;
372  void * event_data_vector;
373 
374  p = vec_elt (nm->processes, nm->current_process_index);
375 
376  /* Find first type with events ready.
377  Return invalid type when there's nothing there. */
379  if (t == ~0)
380  return 0;
381 
382  p->non_empty_event_type_bitmap = clib_bitmap_andnoti (p->non_empty_event_type_bitmap, t);
383 
384  l = _vec_len (p->pending_event_data_by_type_index[t]);
385  ASSERT (l > 0);
386  event_data_vector = p->pending_event_data_by_type_index[t];
388 
389  et = pool_elt_at_index (p->event_type_pool, t);
390 
391  /* Return user's opaque value and possibly index. */
392  *return_event_type_opaque = et->opaque;
393 
395 
396  return event_data_vector;
397 }
398 
399 /* Return event data vector for later reuse. We reuse event data to avoid
400  repeatedly allocating event vectors in cases where we care about speed. */
401 always_inline void
402 vlib_process_put_event_data (vlib_main_t * vm, void * event_data)
403 {
404  vlib_node_main_t * nm = &vm->node_main;
405  vec_add1 (nm->recycled_event_data_vectors, event_data);
406 }
407 
408 /* Return type & add any events to data vector. */
411 {
412  vlib_node_main_t * nm = &vm->node_main;
413  vlib_process_t * p;
415  uword r, t, l;
416 
417  p = vec_elt (nm->processes, nm->current_process_index);
418 
419  /* Find first type with events ready.
420  Return invalid type when there's nothing there. */
422  if (t == ~0)
423  return t;
424 
425  p->non_empty_event_type_bitmap = clib_bitmap_andnoti (p->non_empty_event_type_bitmap, t);
426 
427  l = _vec_len (p->pending_event_data_by_type_index[t]);
428  if (data_vector)
429  vec_add (*data_vector, p->pending_event_data_by_type_index[t], l);
430  _vec_len (p->pending_event_data_by_type_index[t]) = 0;
431 
432  et = pool_elt_at_index (p->event_type_pool, t);
433 
434  /* Return user's opaque value. */
435  r = et->opaque;
436 
438 
439  return r;
440 }
441 
444 {
445  uword l;
446 
447  p->non_empty_event_type_bitmap = clib_bitmap_andnoti (p->non_empty_event_type_bitmap, t);
448 
449  l = _vec_len (p->pending_event_data_by_type_index[t]);
450  if (data_vector)
451  vec_add (*data_vector, p->pending_event_data_by_type_index[t], l);
452  _vec_len (p->pending_event_data_by_type_index[t]) = 0;
453 
455 
456  return l;
457 }
458 
459 /* As above but query as specified type of event. Returns number of
460  events found. */
463  uword with_type_opaque)
464 {
465  vlib_node_main_t * nm = &vm->node_main;
466  vlib_process_t * p;
467  uword t, * h;
468 
469  p = vec_elt (nm->processes, nm->current_process_index);
470  h = hash_get (p->event_type_index_by_type_opaque, with_type_opaque);
471  if (! h)
472  /* This can happen when an event has not yet been
473  signaled with given opaque type. */
474  return 0;
475 
476  t = h[0];
478  return 0;
479 
480  return vlib_process_get_events_helper (p, t, data_vector);
481 }
482 
485 {
486  vlib_node_main_t * nm = &vm->node_main;
487  vlib_process_t * p;
488  uword r;
489 
490  p = vec_elt (nm->processes, nm->current_process_index);
492  {
497  }
498 
499  return p->non_empty_event_type_bitmap;
500 }
501 
504  uword ** data_vector,
505  uword with_type_index)
506 {
507  vlib_node_main_t * nm = &vm->node_main;
508  vlib_process_t * p;
509  uword r;
510 
511  p = vec_elt (nm->processes, nm->current_process_index);
512  ASSERT (! pool_is_free_index (p->event_type_pool, with_type_index));
513  while (! clib_bitmap_get (p->non_empty_event_type_bitmap, with_type_index))
514  {
519  }
520 
521  return vlib_process_get_events_helper (p, with_type_index, data_vector);
522 }
523 
526  uword ** data_vector,
527  uword with_type_opaque)
528 {
529  vlib_node_main_t * nm = &vm->node_main;
530  vlib_process_t * p;
531  uword r, * h;
532 
533  p = vec_elt (nm->processes, nm->current_process_index);
534  h = hash_get (p->event_type_index_by_type_opaque, with_type_opaque);
535  while (! h || ! clib_bitmap_get (p->non_empty_event_type_bitmap, h[0]))
536  {
541 
542  /* See if unknown event type has been signaled now. */
543  if (! h)
544  h = hash_get (p->event_type_index_by_type_opaque, with_type_opaque);
545  }
546 
547  return vlib_process_get_events_helper (p, h[0], data_vector);
548 }
549 
552 {
553  vlib_node_main_t * nm = &vm->node_main;
554  vlib_process_t * p;
555  f64 wakeup_time;
556  uword r;
557 
558  p = vec_elt (nm->processes, nm->current_process_index);
559 
562  return dt;
563 
564  wakeup_time = vlib_time_now (vm) + dt;
565 
566  /* Suspend waiting for both clock and event to occur. */
569 
572  {
574  + (dt * vm->clib_time.clocks_per_second));
576  }
577 
578  /* Return amount of time still left to sleep.
579  If <= 0 then we've been waken up by the clock (and not an event). */
580  return wakeup_time - vlib_time_now (vm);
581 }
582 
585 {
587  pool_get (p->event_type_pool, et);
588  et->opaque = with_type_opaque;
589  return et;
590 }
591 
593 vlib_process_create_one_time_event (vlib_main_t * vm, uword node_index, uword with_type_opaque)
594 {
595  vlib_node_main_t * nm = &vm->node_main;
596  vlib_node_t * n = vlib_get_node (vm, node_index);
599  uword t;
600 
601  et = vlib_process_new_event_type (p, with_type_opaque);
602  t = et - p->event_type_pool;
603  p->one_time_event_type_bitmap = clib_bitmap_ori (p->one_time_event_type_bitmap, t);
604  return t;
605 }
606 
607 always_inline void
609 {
610  vlib_node_main_t * nm = &vm->node_main;
611  vlib_node_t * n = vlib_get_node (vm, node_index);
613 
615  vlib_process_free_event_type (p, t, /* is_one_time_event */ 1);
616 }
617 
618 always_inline void *
620  vlib_node_t * n,
621  vlib_process_t * p,
622  uword t,
623  uword n_data_elts,
624  uword n_data_elt_bytes)
625 {
626  uword p_flags, add_to_pending, delete_from_wheel;
627  void * data_to_be_written_by_caller;
628 
630 
632 
633  /* Resize data vector and return caller's data to be written. */
634  {
635  void * data_vec = p->pending_event_data_by_type_index[t];
636  uword l;
637 
638  if (! data_vec && vec_len (nm->recycled_event_data_vectors))
639  {
640  data_vec = vec_pop (nm->recycled_event_data_vectors);
641  _vec_len (data_vec) = 0;
642  }
643 
644  l = vec_len (data_vec);
645 
646  data_vec = _vec_resize (data_vec,
647  /* length_increment */ n_data_elts,
648  /* total size after increment */ (l + n_data_elts) * n_data_elt_bytes,
649  /* header_bytes */ 0, /* data_align */ 0);
650 
651  p->pending_event_data_by_type_index[t] = data_vec;
652  data_to_be_written_by_caller = data_vec + l * n_data_elt_bytes;
653  }
654 
655  p->non_empty_event_type_bitmap = clib_bitmap_ori (p->non_empty_event_type_bitmap, t);
656 
657  p_flags = p->flags;
658 
659  /* Event was already signalled? */
660  add_to_pending = (p_flags & VLIB_PROCESS_RESUME_PENDING) == 0;
661 
662  /* Process will resume when suspend time elapses? */
663  delete_from_wheel = 0;
665  {
666  /* Waiting for both event and clock? */
668  delete_from_wheel = 1;
669  else
670  /* Waiting only for clock. Event will be queue and may be
671  handled when timer expires. */
672  add_to_pending = 0;
673  }
674 
675  /* Never add current process to pending vector since current process is
676  already running. */
677  add_to_pending &= nm->current_process_index != n->runtime_index;
678 
679  if (add_to_pending)
680  {
682  p->flags = p_flags | VLIB_PROCESS_RESUME_PENDING;
684  if (delete_from_wheel)
686  }
687 
688  return data_to_be_written_by_caller;
689 }
690 
691 always_inline void *
693  uword node_index,
694  uword type_opaque,
695  uword n_data_elts,
696  uword n_data_elt_bytes)
697 {
698  vlib_node_main_t * nm = &vm->node_main;
699  vlib_node_t * n = vlib_get_node (vm, node_index);
701  uword * h, t;
702 
703  h = hash_get (p->event_type_index_by_type_opaque, type_opaque);
704  if (! h)
705  {
707  t = et - p->event_type_pool;
708  hash_set (p->event_type_index_by_type_opaque, type_opaque, t);
709  }
710  else
711  t = h[0];
712 
713  return vlib_process_signal_event_helper (nm, n, p, t, n_data_elts, n_data_elt_bytes);
714 }
715 
716 always_inline void *
718  f64 dt,
719  uword node_index,
720  uword type_opaque,
721  uword n_data_elts,
722  uword n_data_elt_bytes)
723 {
724  vlib_node_main_t * nm = &vm->node_main;
725  vlib_node_t * n = vlib_get_node (vm, node_index);
727  uword * h, t;
728 
729  h = hash_get (p->event_type_index_by_type_opaque, type_opaque);
730  if (! h)
731  {
733  t = et - p->event_type_pool;
734  hash_set (p->event_type_index_by_type_opaque, type_opaque, t);
735  }
736  else
737  t = h[0];
738 
740  return vlib_process_signal_event_helper (nm, n, p, t, n_data_elts, n_data_elt_bytes);
741  else
742  {
744  u64 dt_cpu = dt * vm->clib_time.clocks_per_second;
745 
746  pool_get_aligned (nm->signal_timed_event_data_pool, te, sizeof (te[0]));
747 
748  te->n_data_elts = n_data_elts;
749  te->n_data_elt_bytes = n_data_elt_bytes;
750  te->n_data_bytes = n_data_elts * n_data_elt_bytes;
751 
752  /* Assert that structure fields are big enough. */
753  ASSERT (te->n_data_elts == n_data_elts);
754  ASSERT (te->n_data_elt_bytes == n_data_elt_bytes);
755  ASSERT (te->n_data_bytes == n_data_elts * n_data_elt_bytes);
756 
758  te->event_type_index = t;
759 
762 
763  /* Inline data big enough to hold event? */
764  if (te->n_data_bytes < sizeof (te->inline_event_data))
765  return te->inline_event_data;
766  else
767  {
768  te->event_data_as_vector = 0;
770  return te->event_data_as_vector;
771  }
772  }
773 }
774 
775 always_inline void *
777  uword node_index,
778  uword type_index,
779  uword n_data_elts,
780  uword n_data_elt_bytes)
781 {
782  vlib_node_main_t * nm = &vm->node_main;
783  vlib_node_t * n = vlib_get_node (vm, node_index);
785  return vlib_process_signal_event_helper (nm, n, p, type_index, n_data_elts, n_data_elt_bytes);
786 }
787 
788 always_inline void
790  uword node_index,
791  uword type_opaque,
792  uword data)
793 {
794  uword * d = vlib_process_signal_event_data (vm, node_index, type_opaque,
795  1 /* elts */, sizeof (uword));
796  d[0] = data;
797 }
798 
799 always_inline void
801  uword node_index,
802  uword type_opaque,
803  void * data)
804 {
805  void ** d = vlib_process_signal_event_data (vm, node_index, type_opaque,
806  1 /* elts */, sizeof (data));
807  d[0] = data;
808 }
809 
810 always_inline void
812  uword node_index,
813  uword type_index,
814  uword data)
815 {
816  uword * d = vlib_process_signal_one_time_event_data (vm, node_index, type_index,
817  1 /* elts */, sizeof (uword));
818  d[0] = data;
819 }
820 
821 always_inline void
823 {
825  memset (p, ~0, sizeof (p[0]));
826 }
827 
828 always_inline void
831 {
833  vec_foreach (wp, *wps)
835  vec_free (*wps);
836 }
837 
838 always_inline void
840 {
842  p->one_time_event =
843  vlib_process_create_one_time_event (vm, p->node_index, /* type opaque */ ~0);
845  /* don't care about data */ 0,
846  p->one_time_event);
847 }
848 
849 always_inline void
852 {
854  vec_add2 (*wps, wp, 1);
856 }
857 
860  vlib_node_runtime_t * node,
861  uword n_vectors)
862 {
863  u32 i, d, vi0, vi1;
864  u32 i0, i1;
865 
868  & (ARRAY_LEN (node->main_loop_vector_stats) - 1));
869  i0 = i ^ 0;
870  i1 = i ^ 1;
873  vi0 = node->main_loop_vector_stats[i0];
874  vi1 = node->main_loop_vector_stats[i1];
875  vi0 = d == 0 ? vi0 : 0;
876  vi1 = d <= 1 ? vi1 : 0;
877  vi0 += n_vectors;
878  node->main_loop_vector_stats[i0] = vi0;
879  node->main_loop_vector_stats[i1] = vi1;
881  /* Return previous counter. */
882  return node->main_loop_vector_stats[i1];
883 }
884 
887 {
888  vlib_node_runtime_t * rt = vlib_node_get_runtime (vm, node_index);
889  u32 v;
890 
891  v = vlib_node_runtime_update_main_loop_vector_stats (vm, rt, /* n_vectors */ 0);
892  return (f64) v / (1 << VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE);
893 }
894 
897 {
898  vlib_node_runtime_t * rt = vlib_node_get_runtime (vm, node_index);
899  u32 v;
900 
901  v = vlib_node_runtime_update_main_loop_vector_stats (vm, rt, /* n_vectors */ 0);
903 }
904 
905 void
908  vlib_frame_t * f);
909 
910 /* Add next node to given node in given slot. */
911 uword
913  uword node,
914  uword next_node,
915  uword slot);
916 
917 /* As above but adds to end of node's next vector. */
919 vlib_node_add_next (vlib_main_t * vm, uword node, uword next_node)
920 { return vlib_node_add_next_with_slot (vm, node, next_node, ~0); }
921 
922 /* Add next node to given node in given slot. */
923 uword
925  uword node,
926  char * next_name,
927  uword slot);
928 
929 /* As above but adds to end of node's next vector. */
932  uword node,
933  char * name)
934 { return vlib_node_add_named_next_with_slot (vm, node, name, ~0); }
935 
936 /* Query node given name. */
938 
939 /* Rename a node. */
940 void vlib_node_rename (vlib_main_t * vm, u32 node_index, char * fmt, ...);
941 
942 /* Register new packet processing node. Nodes can be registered
943  dynamically via this call or statically via the VLIB_REGISTER_NODE
944  macro. */
946 
947 /* Register all static nodes registered via VLIB_REGISTER_NODE. */
949 
950 /* Start a process. */
951 void vlib_start_process (vlib_main_t * vm, uword process_index);
952 
953 /* Sync up runtime and main node stats. */
954 void
956 
957 /* Node graph initialization function. */
959 
966 /* Parse node name -> node index. */
968 
969 always_inline void
971  u32 counter_index, u64 increment)
972 {
973  vlib_node_t * n = vlib_get_node (vm, node_index);
974  vlib_error_main_t * em = &vm->error_main;
975  u32 node_counter_base_index = n->error_heap_index;
976  em->counters[node_counter_base_index + counter_index] += increment;
977 }
978 
979 #endif /* included_vlib_node_funcs_h */
u32 * next_nodes
Definition: node.h:254
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
always_inline u32 vlib_frame_index_no_check(vlib_main_t *vm, vlib_frame_t *f)
Definition: node_funcs.h:163
always_inline uword round_pow2(uword x, uword pow2)
Definition: clib.h:255
u32 error_heap_index
Definition: node.h:244
u32 next_frame_index
Definition: node.h:396
#define hash_set(h, key, value)
Definition: hash.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword( unformat_function_t)(unformat_input_t *input, va_list *args)
Definition: format.h:229
always_inline uword vlib_process_create_one_time_event(vlib_main_t *vm, uword node_index, uword with_type_opaque)
Definition: node_funcs.h:593
vlib_process_t ** processes
Definition: node.h:610
always_inline uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Definition: node_funcs.h:410
format_function_t format_vlib_node_name
Definition: node_funcs.h:961
vlib_node_runtime_t node_runtime
Definition: node.h:450
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:191
always_inline vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Definition: node_funcs.h:46
always_inline vlib_next_frame_t * vlib_node_runtime_get_next_frame(vlib_main_t *vm, vlib_node_runtime_t *n, u32 next_index)
Definition: node_funcs.h:213
#define VLIB_FRAME_IS_ALLOCATED
Definition: node.h:335
f64 clocks_per_second
Definition: time.h:52
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:44
u32 main_loop_vector_stats[2]
Definition: node.h:409
always_inline void vlib_process_signal_event_pointer(vlib_main_t *vm, uword node_index, uword type_opaque, void *data)
Definition: node_funcs.h:800
void ** pending_event_data_by_type_index
Definition: node.h:481
u32 current_process_index
Definition: node.h:613
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
always_inline uword vlib_process_suspend_time_is_zero(f64 dt)
Definition: node_funcs.h:322
#define vlib_set_next_frame(vm, node, next_index, v)
Definition: node_funcs.h:282
always_inline void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:134
struct _vlib_node_registration vlib_node_registration_t
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:519
always_inline void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:789
always_inline uword vlib_process_get_events_with_type(vlib_main_t *vm, uword **data_vector, uword with_type_opaque)
Definition: node_funcs.h:462
always_inline void * vlib_process_signal_event_helper(vlib_node_main_t *nm, vlib_node_t *n, vlib_process_t *p, uword t, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:619
void clib_longjmp(clib_longjmp_t *save, uword return_value)
format_function_t format_vlib_cpu_time
Definition: node_funcs.h:964
clib_time_t clib_time
Definition: main.h:61
always_inline uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Definition: node_funcs.h:326
#define VLIB_CPU_MASK
Definition: threads.h:61
void * runtime_data
Definition: node.h:209
void timing_wheel_insert(timing_wheel_t *w, u64 insert_cpu_time, u32 user_data)
Definition: timing_wheel.c:273
#define pool_get(P, E)
Definition: pool.h:186
uword clib_setjmp(clib_longjmp_t *save, uword return_value_not_taken)
always_inline void vlib_signal_one_time_waiting_process_vector(vlib_main_t *vm, vlib_one_time_waiting_process_t **wps)
Definition: node_funcs.h:829
always_inline u32 vlib_timing_wheel_data_set_timed_event(u32 i)
Definition: node.h:561
always_inline vlib_frame_t * vlib_get_frame(vlib_main_t *vm, uword frame_index)
Definition: node_funcs.h:176
vlib_node_state_t
Definition: node.h:175
#define VLIB_PROCESS_RESUME_PENDING
Definition: node.h:467
#define vec_pop(V)
Returns last element of a vector and decrements its length.
Definition: vec.h:574
u8 state
Definition: node.h:231
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:557
u32 * pending_interrupt_node_runtime_indices
Definition: node.h:583
u32 main_loop_count_last_dispatch
Definition: node.h:407
void vlib_node_rename(vlib_main_t *vm, u32 node_index, char *fmt,...)
Definition: node.c:73
void ** recycled_event_data_vectors
Definition: node.h:619
#define always_inline
Definition: clib.h:84
format_function_t format_vlib_node_and_next
Definition: node_funcs.h:963
vlib_node_t ** nodes
Definition: node.h:570
#define VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE
Definition: main.h:83
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline uword clib_bitmap_first_set(uword *ai)
Definition: bitmap.h:329
always_inline void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Definition: node_funcs.h:100
unsigned long u64
Definition: types.h:89
always_inline void vlib_signal_one_time_waiting_process(vlib_main_t *vm, vlib_one_time_waiting_process_t *p)
Definition: node_funcs.h:822
format_function_t format_vlib_next_node_name
Definition: node_funcs.h:962
#define VLIB_OFFSET_MASK
Definition: threads.h:62
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:199
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
Definition: main.c:211
vlib_node_runtime_t * nodes_by_type[VLIB_N_NODE_TYPE]
Definition: node.h:580
always_inline uword vlib_process_get_events_helper(vlib_process_t *p, uword t, uword **data_vector)
Definition: node_funcs.h:443
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
clib_error_t * vlib_node_main_init(vlib_main_t *vm)
Definition: node.c:467
always_inline void vlib_process_maybe_free_event_type(vlib_process_t *p, uword t)
Definition: node_funcs.h:358
#define hash_get(h, key)
Definition: hash.h:231
#define pool_elt_at_index(p, i)
Definition: pool.h:346
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:449
vlib_signal_timed_event_data_t * signal_timed_event_data_pool
Definition: node.h:600
vlib_error_main_t error_main
Definition: main.h:124
always_inline uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:484
always_inline u32 vlib_node_vectors_per_main_loop_as_integer(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:896
always_inline void vlib_process_signal_one_time_event(vlib_main_t *vm, uword node_index, uword type_index, uword data)
Definition: node_funcs.h:811
u8 inline_event_data[64-3 *sizeof(u32)-2 *sizeof(u16)]
Definition: node.h:545
always_inline void vlib_process_free_event_type(vlib_process_t *p, uword t, uword is_one_time_event)
Definition: node_funcs.h:348
always_inline f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Definition: node_funcs.h:551
always_inline uword vlib_process_wait_for_one_time_event(vlib_main_t *vm, uword **data_vector, uword with_type_index)
Definition: node_funcs.h:503
#define VLIB_PROCESS_RESUME_LONGJMP_SUSPEND
Definition: node.h:460
always_inline u32 vlib_frame_vector_byte_offset(u32 scalar_size)
Definition: node_funcs.h:195
always_inline void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:970
always_inline vlib_frame_t * vlib_get_frame_no_check(vlib_main_t *vm, uword frame_index)
Definition: node_funcs.h:152
always_inline u32 vlib_node_runtime_update_main_loop_vector_stats(vlib_main_t *vm, vlib_node_runtime_t *node, uword n_vectors)
Definition: node_funcs.h:859
always_inline void * vlib_frame_args(vlib_frame_t *f)
Definition: node_funcs.h:209
always_inline vlib_node_t * vlib_get_next_node(vlib_main_t *vm, u32 node_index, u32 next_index)
Definition: node_funcs.h:50
#define VLIB_PROCESS_RETURN_LONGJMP_SUSPEND
Definition: node.h:456
always_inline uword vlib_node_add_named_next(vlib_main_t *vm, uword node, char *name)
Definition: node_funcs.h:931
always_inline vlib_next_frame_t * vlib_node_get_next_frame(vlib_main_t *vm, u32 node_index, u32 next_index)
Definition: node_funcs.h:236
#define pool_get_aligned(P, E, A)
Definition: pool.h:155
timing_wheel_t timing_wheel
Definition: node.h:598
#define VLIB_FRAME_VECTOR_ALIGN
Definition: node_funcs.h:192
always_inline uword clib_bitmap_get(uword *ai, uword i)
Definition: bitmap.h:158
u64 * counters
Definition: error.h:73
u32 runtime_index
Definition: node.h:206
uword vlib_node_add_named_next_with_slot(vlib_main_t *vm, uword node, char *next_name, uword slot)
Definition: node.c:219
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
void * heap_base
Definition: main.h:100
#define clib_memcpy(a, b, c)
Definition: string.h:63
void timing_wheel_delete(timing_wheel_t *w, u32 user_data)
Definition: timing_wheel.c:305
always_inline uword vlib_process_wait_for_event_with_type(vlib_main_t *vm, uword **data_vector, uword with_type_opaque)
Definition: node_funcs.h:525
uword vlib_node_add_next_with_slot(vlib_main_t *vm, uword node, uword next_node, uword slot)
Definition: node.c:154
always_inline void vlib_process_put_event_data(vlib_main_t *vm, void *event_data)
Definition: node_funcs.h:402
always_inline void * vlib_process_signal_event_data(vlib_main_t *vm, uword node_index, uword type_opaque, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:692
#define pool_is_free_index(P, I)
Definition: pool.h:197
#define ARRAY_LEN(x)
Definition: clib.h:59
always_inline u32 vlib_frame_index(vlib_main_t *vm, vlib_frame_t *f)
Definition: node_funcs.h:184
always_inline u32 vlib_timing_wheel_data_set_suspended_process(u32 i)
Definition: node.h:557
uword * one_time_event_type_bitmap
Definition: node.h:487
always_inline uword is_pow2(uword x)
Definition: clib.h:252
#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT
Definition: node.h:465
void vlib_start_process(vlib_main_t *vm, uword process_index)
Definition: main.c:1284
#define pool_put_index(p, i)
Definition: pool.h:214
#define ASSERT(truth)
always_inline vlib_process_t * vlib_get_process_from_node(vlib_main_t *vm, vlib_node_t *node)
Definition: node_funcs.h:143
unsigned int u32
Definition: types.h:88
u16 flags
Definition: node.h:298
u16 cpu_index
Definition: node.h:310
always_inline void vlib_process_delete_one_time_event(vlib_main_t *vm, uword node_index, uword t)
Definition: node_funcs.h:608
always_inline f64 vlib_node_vectors_per_main_loop_as_float(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:886
always_inline vlib_process_event_type_t * vlib_process_new_event_type(vlib_process_t *p, uword with_type_opaque)
Definition: node_funcs.h:584
#define VLIB_PROCESS_RESUME_LONGJMP_RESUME
Definition: node.h:461
u8 *( format_function_t)(u8 *s, va_list *args)
Definition: format.h:48
vlib_frame_t * vlib_get_next_frame_internal(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 alloc_new_frame)
Definition: main.c:358
always_inline uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:919
u64 uword
Definition: types.h:112
always_inline uword clib_bitmap_is_zero(uword *ai)
Definition: bitmap.h:50
#define vec_elt(v, i)
Get vector value at index i.
void vlib_node_sync_stats(vlib_main_t *vm, vlib_node_t *n)
Definition: main.c:577
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_packets_left)
Definition: main.c:459
always_inline void * vlib_node_get_runtime_data(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:76
vlib_process_event_type_t * event_type_pool
Definition: node.h:494
always_inline void vlib_current_process_wait_for_one_time_event_vector(vlib_main_t *vm, vlib_one_time_waiting_process_t **wps)
Definition: node_funcs.h:850
u32 * data_from_advancing_timing_wheel
Definition: node.h:603
always_inline void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:366
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:140
u32 input_node_counts_by_state[VLIB_N_NODE_STATE]
Definition: node.h:622
unsigned char u8
Definition: types.h:56
vlib_node_main_t node_main
Definition: main.h:115
format_function_t format_vlib_time
Definition: node_funcs.h:965
vlib_next_frame_t * next_frames
Definition: node.h:592
always_inline void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
Definition: node_funcs.h:292
always_inline void vlib_node_set_runtime_data(vlib_main_t *vm, u32 node_index, void *runtime_data, u32 n_runtime_data_bytes)
Definition: node_funcs.h:83
uword * event_type_index_by_type_opaque
Definition: node.h:491
#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK
Definition: node.h:464
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:967
u16 flags
Definition: node.h:463
vlib_node_type_t type
Definition: node.h:200
always_inline uword vlib_in_process_context(vlib_main_t *vm)
Definition: node_funcs.h:313
always_inline uword vlib_current_process(vlib_main_t *vm)
Definition: node_funcs.h:317
always_inline vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:61
void vlib_register_all_static_nodes(vlib_main_t *vm)
Definition: node.c:455
u64 resume_cpu_time
Definition: node.h:497
always_inline vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
Definition: node_funcs.h:306
#define vec_foreach(var, vec)
Vector iterator.
always_inline void * vlib_process_signal_one_time_event_data(vlib_main_t *vm, uword node_index, uword type_index, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:776
clib_longjmp_t return_longjmp
Definition: node.h:453
always_inline f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
u32 node_runtime_index
Definition: node.h:321
u8 scalar_size
Definition: node.h:301
always_inline void * vlib_process_signal_event_at_time(vlib_main_t *vm, f64 dt, uword node_index, uword type_opaque, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:717
clib_longjmp_t resume_longjmp
Definition: node.h:459
always_inline u64 clib_cpu_time_now(void)
Definition: time.h:71
u32 main_loop_count
Definition: main.h:70
uword runtime_data[(128-1 *sizeof(vlib_node_function_t *)-1 *sizeof(vlib_error_t *)-11 *sizeof(u32)-5 *sizeof(u16))/sizeof(uword)]
Definition: node.h:432
always_inline void vlib_current_process_wait_for_one_time_event(vlib_main_t *vm, vlib_one_time_waiting_process_t *p)
Definition: node_funcs.h:839
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:184
u8 runtime_data_bytes
Definition: node.h:234
always_inline u32 counter_index(vlib_main_t *vm, vlib_error_t e)
format_function_t format_vlib_node_graph
Definition: node_funcs.h:960
vlib_main_t ** vlib_mains
Definition: buffer.c:244
uword * non_empty_event_type_bitmap
Definition: node.h:484