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