FD.io VPP  v21.06
Vector Packet Processing
punt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 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 <vlib/punt.h>
17 
18 /**
19  * The last allocated punt reason
20  * Value 0 is reserved for invalid index.
21  */
23 
24 /**
25  * Counters per punt-reason
26  */
28  .name = "punt",
29  .stat_segment_name = "/net/punt",
30 };
31 
32 /**
33  * A punt reason
34  */
35 typedef struct punt_reason_data_t_
36 {
37  /**
38  * The reason name
39  */
41 
42  /**
43  * The allocated reason value
44  */
46 
47  /**
48  * Clients/owners that have registered this reason
49  */
51 
52  /**
53  * clients interested/listening to this reason
54  */
56 
57  /**
58  * function to invoke if a client becomes interested in the code.
59  */
61 
62  /**
63  * Data to pass to the callback
64  */
65  void *pd_data;
66 
67  /**
68  * Flags associated to the reason
69  */
71 
72  /**
73  * Formatting function for flags;
74  */
77 
78 /**
79  * data for each punt reason
80  */
82 
84 {
88 
89 /**
90  * A registration, by a client, to direct punted traffic to a given node
91  */
92 typedef struct punt_reg_t_
93 {
94  /**
95  * Reason the packets were punted
96  */
98 
99  /**
100  * number of clients that have made this registration
101  */
103 
104  /**
105  * The edge from the punt dispatch node to the requested node
106  */
108 
109  /**
110  * node-index to send punted packets to
111  */
113 } punt_reg_t;
114 
115 /**
116  * Pool of registrations
117  */
119 
120 /**
121  * A DB of all the register nodes against punt reason and node index
122  */
124 
125 /**
126  * A DB used in the DP per-reason to dispatch packets to the requested nodes.
127  * this is a vector of edges per-reason
128  */
130 
131 /**
132  * A client using the punt serivce and its registrations
133  */
134 typedef struct punt_client_t_
135 {
136  /**
137  * The name of the client
138  */
140 
141  /**
142  * The registrations is has made
143  */
145 } punt_client_t;
146 
147 /**
148  * Pool of clients
149  */
151 
152 /**
153  * DB of clients key'd by their name
154  */
156 
157 u8 *
158 format_vlib_punt_reason (u8 * s, va_list * args)
159 {
160  vlib_punt_reason_t pr = va_arg (*args, int);
161  format_function_t *flags_format = punt_reason_data[pr].flags_format;
162  u32 flags = punt_reason_data[pr].flags;
163  if (flags_format)
164  return (format (s, "[%d] %v flags: %U", pr, punt_reason_data[pr].pd_name,
165  flags_format, flags));
166  else
167  return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name));
168 }
169 
171 vlib_punt_client_register (const char *who)
172 {
173  u8 *pc_name;
174  uword *p;
175  u32 pci;
176 
177  pc_name = format (NULL, "%s", who);
178  p = hash_get_mem (punt_client_db, pc_name);
179 
180  if (NULL == p)
181  {
182  punt_client_t *pc;
183 
184  pool_get (punt_client_pool, pc);
185  pci = pc - punt_client_pool;
186 
187  pc->pc_name = pc_name;
188 
189  hash_set_mem (punt_client_db, pc->pc_name, pci);
190  }
191  else
192  {
193  pci = p[0];
194  vec_free (pc_name);
195  }
196 
197  return (pci);
198 }
199 
200 static int
202 {
203  return (!pool_is_free_index (punt_client_pool, client));
204 }
205 
206 static u64
208 {
209  return (((u64) node_index) << 32 | reason);
210 }
211 
212 static u32
214 {
215  uword *p;
216 
217  p = hash_get (punt_reg_db, punt_reg_mk_key (reason, node_index));
218 
219  if (p)
220  return p[0];
221 
222  return ~0;
223 }
224 
225 static void
227 {
229  pr->pr_node_index),
230  pr - punt_reg_pool);
231 }
232 
233 static void
235 {
237  pr->pr_node_index));
238 }
239 
240 /**
241  * reconstruct the DP per-reason DB
242  */
243 static void
245 {
246  u32 pri, *prip, *pris;
247  const punt_reg_t *pr;
248  u16 *edges, *old;
249  u64 key;
250 
251  pris = NULL;
252  edges = NULL;
253  vec_validate (punt_dp_db, reason);
254 
255  old = punt_dp_db[reason];
256 
257  /* *INDENT-OFF* */
258  hash_foreach (key, pri, punt_reg_db,
259  ({
260  vec_add1(pris, pri);
261  }));
262  /* *INDENT-ON* */
263 
264  /*
265  * A check for an empty vector is done in the DP, so the a zero
266  * length vector here is ok
267  */
268  vec_foreach (prip, pris)
269  {
270  pr = pool_elt_at_index (punt_reg_pool, *prip);
271 
272  if (pr->pr_reason == reason)
273  vec_add1 (edges, pr->pr_edge);
274  }
275 
276  /* atomic update of the DP */
277  punt_dp_db[reason] = edges;
278 
279  vec_free (old);
280 }
281 
282 int
284  vlib_punt_reason_t reason, const char *node_name)
285 {
286  vlib_node_t *punt_to, *punt_from;
287  punt_client_t *pc;
288  vlib_main_t *vm;
289  punt_reg_t *pr;
290  u32 pri;
291 
292  if (reason >= punt_reason_last)
293  return -1;
294  if (!punt_validate_client (client))
295  return -2;
296 
297  vm = vlib_get_main ();
298  pc = pool_elt_at_index (punt_client_pool, client);
299  punt_to = vlib_get_node_by_name (vm, (u8 *) node_name);
300  punt_from = vlib_get_node_by_name (vm, (u8 *) "punt-dispatch");
301 
302  /*
303  * find a global matching registration
304  */
305  pri = punt_reg_find (reason, punt_to->index);
306 
307  if (~0 != pri)
308  {
309  u32 pos;
310 
311  pos = vec_search (pc->pc_regs, pri);
312 
313  if (~0 != pos)
314  {
315  /* duplicate registration for this client */
316  return -1;
317  }
318 
319  pr = pool_elt_at_index (punt_reg_pool, pri);
320  }
321  else
322  {
323  pool_get (punt_reg_pool, pr);
324 
325  pr->pr_reason = reason;
326  pr->pr_node_index = punt_to->index;
327  pr->pr_edge = vlib_node_add_next (vm,
328  punt_from->index, pr->pr_node_index);
329 
330  pri = pr - punt_reg_pool;
331 
332  if (0 == punt_reason_data[reason].pd_users++ &&
333  NULL != punt_reason_data[reason].pd_fn)
334  punt_reason_data[reason].pd_fn (VLIB_ENABLE,
335  punt_reason_data[reason].pd_data);
336 
337  punt_reg_add (pr);
338  }
339 
340  /*
341  * add this reg to the list the client has made
342  */
343  pr->pr_locks++;
344  vec_add1 (pc->pc_regs, pri);
345 
346  punt_reg_mk_dp (reason);
347 
348  return 0;
349 }
350 
351 int
353  vlib_punt_reason_t reason, const char *node_name)
354 {
355  vlib_node_t *punt_to;
356  punt_client_t *pc;
357  vlib_main_t *vm;
358  punt_reg_t *pr;
359  u32 pri;
360 
361  if (reason >= punt_reason_last)
362  return -1;
363 
364  vm = vlib_get_main ();
365  pc = pool_elt_at_index (punt_client_pool, client);
366  punt_to = vlib_get_node_by_name (vm, (u8 *) node_name);
367 
368  /*
369  * construct a registration and check if it's one this client already has
370  */
371  pri = punt_reg_find (reason, punt_to->index);
372 
373  if (~0 != pri)
374  {
375  u32 pos;
376 
377  pos = vec_search (pc->pc_regs, pri);
378 
379  if (~0 == pos)
380  {
381  /* not a registration for this client */
382  return -1;
383  }
384  vec_del1 (pc->pc_regs, pos);
385 
386  pr = pool_elt_at_index (punt_reg_pool, pri);
387 
388  pr->pr_locks--;
389 
390  if (0 == pr->pr_locks)
391  {
392  if (0 == --punt_reason_data[reason].pd_users &&
393  NULL != punt_reason_data[reason].pd_fn)
394  punt_reason_data[reason].pd_fn (VLIB_DISABLE,
395  punt_reason_data[reason].pd_data);
396  punt_reg_remove (pr);
397  pool_put (punt_reg_pool, pr);
398  }
399  }
400 
401  /*
402  * rebuild the DP data-base
403  */
404  punt_reg_mk_dp (reason);
405 
406  return (0);
407 }
408 
409 int
411 {
412  if (reason < punt_reason_last)
413  return (0);
414 
415  return (-1);
416 }
417 
418 u32
420 {
421  return pr < punt_reason_last ? punt_reason_data[pr].flags : 0;
422 }
423 
424 int
425 vlib_punt_reason_alloc (vlib_punt_hdl_t client, const char *reason_name,
427  vlib_punt_reason_t *reason, u32 flags,
429 {
430  vlib_punt_reason_t new;
431 
432  if (!punt_validate_client (client))
433  return -2;
434 
435  new = punt_reason_last++;
436  vec_validate (punt_reason_data, new);
437  punt_reason_data[new].pd_name = format (NULL, "%s", reason_name);
438  punt_reason_data[new].pd_reason = new;
439  punt_reason_data[new].pd_fn = fn;
440  punt_reason_data[new].pd_data = data;
441  punt_reason_data[new].flags = flags;
442  punt_reason_data[new].flags_format = flags_format;
443  vec_add1 (punt_reason_data[new].pd_owners, client);
444 
445  vlib_validate_combined_counter (&punt_counters, new);
446  vlib_zero_combined_counter (&punt_counters, new);
447 
448  *reason = new;
449 
450  /* build the DP data-base */
451  punt_reg_mk_dp (*reason);
452 
453  return (0);
454 }
455 
456 void
458 {
459  punt_reason_data_t *pd;
460 
461  for (pd = punt_reason_data + 1; pd < vec_end (punt_reason_data); pd++)
462  {
463  cb (pd->pd_reason, pd->pd_name, ctx);
464  }
465 }
466 
467 /* Parse node name -> node index. */
468 uword
469 unformat_punt_client (unformat_input_t * input, va_list * args)
470 {
471  u32 *result = va_arg (*args, u32 *);
472 
474  punt_client_db, result);
475 }
476 
477 /* Parse punt reason */
478 uword
479 unformat_punt_reason (unformat_input_t *input, va_list *args)
480 {
481  u32 *result = va_arg (*args, u32 *);
482  u8 *s = 0;
483  u8 found = 0;
484  for (int i = 0; i < punt_reason_last - 1; i++)
485  {
486  punt_reason_data_t *pd = vec_elt_at_index (punt_reason_data, 1 + i);
487  vec_reset_length (s);
488  s = format (0, "%v%c", pd->pd_name, 0);
489  if (unformat (input, (const char *) s))
490  {
491  *result = pd->pd_reason;
492  found = 1;
493  break;
494  }
495  }
496  vec_free (s);
497  return found;
498 }
499 
500 u8 *
501 format_punt_reg (u8 * s, va_list * args)
502 {
503  u32 pri = va_arg (*args, u32);
504  punt_reg_t *pr;
505 
506  pr = pool_elt_at_index (punt_reg_pool, pri);
507 
508  s = format (s, "%U -> %U",
511 
512  return (s);
513 }
514 
515 u8 *
516 format_punt_reason_data (u8 * s, va_list * args)
517 {
518  punt_reason_data_t *pd = va_arg (*args, punt_reason_data_t *);
519  punt_client_t *pc;
520  u32 *pci;
521  if (pd->flags_format)
522  s = format (s, "[%d] %v flags: %U from:[", pd->pd_reason, pd->pd_name,
523  pd->flags_format, pd->flags);
524  else
525  s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name);
526  vec_foreach (pci, pd->pd_owners)
527  {
528  pc = pool_elt_at_index (punt_client_pool, *pci);
529  s = format (s, "%v ", pc->pc_name);
530  }
531  s = format (s, "]");
532 
533  return (s);
534 }
535 
536 u8 *
537 format_punt_client (u8 * s, va_list * args)
538 {
539  u32 pci = va_arg (*args, u32);
541  punt_client_t *pc;
542 
543  pc = pool_elt_at_index (punt_client_pool, pci);
544 
545  s = format (s, "%v", pc->pc_name);
546 
547  if (flags & PUNT_FORMAT_FLAG_DETAIL)
548  {
549  punt_reason_data_t *pd;
550  u32 *pri;
551 
552  s = format (s, "\n registrations:");
553  vec_foreach (pri, pc->pc_regs)
554  {
555  s = format (s, "\n [%U]", format_punt_reg, *pri);
556  }
557 
558  s = format (s, "\n reasons:");
559 
560  vec_foreach (pd, punt_reason_data)
561  {
562  u32 *tmp;
563 
564  vec_foreach (tmp, pd->pd_owners)
565  {
566  if (*tmp == pci)
567  s = format (s, "\n %U", format_punt_reason_data, pd);
568  }
569  }
570  }
571  return (s);
572 }
573 
574 static clib_error_t *
576  unformat_input_t * input, vlib_cli_command_t * cmd)
577 {
578  u32 pci = ~0;
579 
581  {
582  if (unformat (input, "%U", unformat_punt_client, &pci))
583  ;
584  else
585  break;
586  }
587 
588  if (~0 != pci)
589  {
590  vlib_cli_output (vm, "%U", format_punt_client, pci,
592  }
593  else
594  {
595  u8 *name;
596 
597  /* *INDENT-OFF* */
598  hash_foreach(name, pci, punt_client_db,
599  ({
600  vlib_cli_output (vm, "%U", format_punt_client, pci,
602  }));
603  /* *INDENT-ON* */
604  }
605 
606  return (NULL);
607 }
608 
609 /* *INDENT-OFF* */
610 VLIB_CLI_COMMAND (punt_client_show_command, static) =
611 {
612  .path = "show punt client",
613  .short_help = "show client[s] registered with the punt infra",
614  .function = punt_client_show,
615 };
616 /* *INDENT-ON* */
617 
618 static clib_error_t *
620  unformat_input_t * input, vlib_cli_command_t * cmd)
621 {
622  const punt_reason_data_t *pd;
623 
624  vec_foreach (pd, punt_reason_data)
625  {
627  }
628 
629  return (NULL);
630 }
631 
632 /* *INDENT-OFF* */
633 VLIB_CLI_COMMAND (punt_reason_show_command, static) =
634 {
635  .path = "show punt reasons",
636  .short_help = "show all punt reasons",
637  .function = punt_reason_show,
638 };
639 /* *INDENT-ON* */
640 
641 static clib_error_t *
643  unformat_input_t * input, vlib_cli_command_t * cmd)
644 {
645  u32 pri, ii, jj;
646  u64 key;
647 
648  /* *INDENT-OFF* */
649  hash_foreach (key, pri, punt_reg_db,
650  ({
651  vlib_cli_output (vm, " %U", format_punt_reg, pri);
652  }));
653  /* *INDENT-ON* */
654 
655  vlib_cli_output (vm, "\nDerived data-plane data-base:");
656  vlib_cli_output (vm,
657  " (for each punt-reason the edge[s] from punt-dispatch)");
658 
660  {
661  u8 *s = NULL;
662  vlib_cli_output (vm, " %U", format_vlib_punt_reason, ii);
663 
664  vec_foreach_index (jj, punt_dp_db[ii])
665  {
666  s = format (s, "%d ", punt_dp_db[ii][jj]);
667  }
668  vlib_cli_output (vm, " [%v]", s);
669  vec_free (s);
670  }
671 
672  return (NULL);
673 }
674 
675 /* *INDENT-OFF* */
676 VLIB_CLI_COMMAND (punt_db_show_command, static) =
677 {
678  .path = "show punt db",
679  .short_help = "show the punt DB",
680  .function = punt_db_show,
681 };
682 /* *INDENT-ON* */
683 
684 static clib_error_t *
686  unformat_input_t * input, vlib_cli_command_t * cmd)
687 {
690  u32 ii;
691 
692  for (ii = 0; ii < vlib_combined_counter_n_counters (cm); ii++)
693  {
694  vlib_get_combined_counter (cm, ii, &c);
695  vlib_cli_output (vm, "%U packets:%lld bytes:%lld",
697  }
698 
699  return (NULL);
700 }
701 
702 /* *INDENT-OFF* */
703 VLIB_CLI_COMMAND (punt_stats_show_command, static) =
704 {
705  .path = "show punt stats",
706  .short_help = "show the punt stats",
707  .function = punt_stats_show,
708 };
709 /* *INDENT-ON* */
710 
711 static clib_error_t *
713 {
714  punt_client_db = hash_create_vec (0, sizeof (u8), sizeof (u32));
715 
716  return (NULL);
717 }
718 
720 
721 /*
722  * fd.io coding-style-patch-verification: ON
723  *
724  * Local Variables:
725  * eval: (c-set-style "gnu")
726  * End:
727  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
int(* punt_reason_walk_cb_t)(vlib_punt_reason_t id, const u8 *name, void *ctx)
Walk each punt reason.
Definition: punt.h:34
static uword * punt_client_db
DB of clients key&#39;d by their name.
Definition: punt.c:155
#define vec_foreach_index(var, v)
Iterate over vector indices.
uword unformat_punt_client(unformat_input_t *input, va_list *args)
Definition: punt.c:469
A registration, by a client, to direct punted traffic to a given node.
Definition: punt.h:96
#define hash_set(h, key, value)
Definition: hash.h:255
uword unformat_punt_reason(unformat_input_t *input, va_list *args)
Unformat a punt reason.
Definition: punt.c:479
format_function_t * flags_format
Formatting function for flags;.
Definition: punt.c:75
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:119
format_function_t format_vlib_node_name
Definition: node_funcs.h:1235
#define hash_unset(h, key)
Definition: hash.h:261
int vlib_punt_reason_validate(vlib_punt_reason_t reason)
Validate that a punt reason is assigned.
Definition: punt.c:410
static void punt_reg_mk_dp(vlib_punt_reason_t reason)
reconstruct the DP per-reason DB
Definition: punt.c:244
u16 pr_edge
The edge from the punt dispatch node to the requested node.
Definition: punt.c:107
unsigned long u64
Definition: types.h:89
vnet_feature_config_main_t * cm
u32 pr_node_index
node-index to send punted packets to
Definition: punt.c:112
u32 index
Definition: node.h:270
u8 * format_punt_reason_data(u8 *s, va_list *args)
Definition: punt.c:516
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
int vlib_punt_hdl_t
Typedef for a client handle.
Definition: punt.h:52
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
#define hash_set_mem(h, key, value)
Definition: hash.h:275
static punt_reg_t * punt_reg_pool
Pool of registrations.
Definition: punt.c:118
static vlib_punt_reason_t punt_reason_last
The last allocated punt reason Value 0 is reserved for invalid index.
Definition: punt.c:22
string name[64]
Definition: fib.api:25
u32 * pc_regs
The registrations is has made.
Definition: punt.c:144
u8 * pd_name
The reason name.
Definition: punt.c:40
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
u16 pr_locks
number of clients that have made this registration
Definition: punt.c:102
static uword * punt_reg_db
A DB of all the register nodes against punt reason and node index.
Definition: punt.c:123
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:92
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u8 * format_vlib_punt_reason(u8 *s, va_list *args)
Format a punt reason.
Definition: punt.c:158
unsigned int u32
Definition: types.h:88
u8 *() format_function_t(u8 *s, va_list *args)
Definition: format.h:48
static punt_client_t * punt_client_pool
Pool of clients.
Definition: punt.c:150
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
description fragment has unexpected format
Definition: map.api:433
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vec_end(v)
End (last data address) of vector.
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
Definition: vec.h:1055
A client using the punt serivce and its registrations.
Definition: punt.c:134
struct punt_reg_t_ punt_reg_t
A registration, by a client, to direct punted traffic to a given node.
vlib_punt_hdl_t vlib_punt_client_register(const char *who)
Register a new clinet.
Definition: punt.c:171
vlib_punt_reason_t pd_reason
The allocated reason value.
Definition: punt.c:45
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
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
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
struct punt_reason_data_t_ punt_reason_data_t
A punt reason.
counter_t packets
packet counter
Definition: counter_types.h:28
long ctx[MAX_CONNS]
Definition: main.c:144
u32 vlib_combined_counter_n_counters(const vlib_combined_counter_main_t *cm)
The number of counters (not the number of per-thread counters)
Definition: counter.c:191
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static void punt_reg_remove(const punt_reg_t *pr)
Definition: punt.c:234
static clib_error_t * punt_stats_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:685
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
u32 * tmp
static clib_error_t * punt_reason_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:619
static clib_error_t * punt_db_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:642
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:897
u8 * format_punt_reg(u8 *s, va_list *args)
Definition: punt.c:501
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
static clib_error_t * punt_init(vlib_main_t *vm)
Definition: punt.c:712
unformat_function_t unformat_hash_vec_string
Definition: hash.h:718
void * pd_data
Data to pass to the callback.
Definition: punt.c:65
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
svmdb_client_t * c
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
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
static punt_reason_data_t * punt_reason_data
data for each punt reason
Definition: punt.c:81
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
int vlib_punt_unregister(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Definition: punt.c:352
vlib_punt_reason_t pr_reason
Reason the packets were punted.
Definition: punt.c:97
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
void punt_reason_walk(punt_reason_walk_cb_t cb, void *ctx)
Definition: punt.c:457
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
struct punt_client_t_ punt_client_t
A client using the punt serivce and its registrations.
u8 * format_punt_client(u8 *s, va_list *args)
Definition: punt.c:537
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
void(* punt_interested_listener_t)(vlib_enable_or_disable_t i, void *data)
Definition: punt.h:64
typedef key
Definition: ipsec_types.api:88
counter_t bytes
byte counter
Definition: counter_types.h:29
u32 vlib_punt_reason_get_flags(vlib_punt_reason_t pr)
Definition: punt.c:419
static u64 punt_reg_mk_key(vlib_punt_reason_t reason, u32 node_index)
Definition: punt.c:207
int vlib_punt_register(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Register a node to receive particular punted buffers.
Definition: punt.c:283
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:668
punt_format_flags_t_
Definition: punt.c:83
u32 flags
Flags associated to the reason.
Definition: punt.c:70
static clib_error_t * punt_client_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:575
punt_interested_listener_t pd_fn
function to invoke if a client becomes interested in the code.
Definition: punt.c:60
vlib_combined_counter_main_t punt_counters
Counters per punt-reason.
Definition: punt.c:27
u64 uword
Definition: types.h:112
char * name
The counter collection&#39;s name.
Definition: counter.h:206
node node_index
A collection of combined counters.
Definition: counter.h:203
u16 ** punt_dp_db
A DB used in the DP per-reason to dispatch packets to the requested nodes.
Definition: punt.c:129
u32 * pd_owners
Clients/owners that have registered this reason.
Definition: punt.c:50
#define hash_get_mem(h, key)
Definition: hash.h:269
enum punt_format_flags_t_ punt_format_flags_t
A punt reason.
Definition: punt.c:35
u8 * pc_name
The name of the client.
Definition: punt.c:139
static u32 punt_reg_find(vlib_punt_reason_t reason, u32 node_index)
Definition: punt.c:213
#define vec_foreach(var, vec)
Vector iterator.
static void punt_reg_add(const punt_reg_t *pr)
Definition: punt.c:226
static int punt_validate_client(vlib_punt_hdl_t client)
Definition: punt.c:201
int vlib_punt_reason_alloc(vlib_punt_hdl_t client, const char *reason_name, punt_interested_listener_t fn, void *data, vlib_punt_reason_t *reason, u32 flags, format_function_t *flags_format)
Allocate a new punt reason.
Definition: punt.c:425
enum vlib_punt_reason_t_ vlib_punt_reason_t
The &#39;syatem&#39; defined punt reasons.
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
u32 pd_users
clients interested/listening to this reason
Definition: punt.c:55