FD.io VPP  v17.10-9-gd594711
Vector Packet Processing
policer.c
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 #include <stdint.h>
16 #include <vnet/policer/policer.h>
18 
21  u8 * name,
23  u32 * policer_index, u8 is_add)
24 {
26  policer_read_response_type_st test_policer;
28  uword *p;
29  u32 pi;
30  int rv;
31 
32  p = hash_get_mem (pm->policer_config_by_name, name);
33 
34  if (is_add == 0)
35  {
36  /* free policer config and template */
37  if (p == 0)
38  {
39  vec_free (name);
40  return clib_error_return (0, "No such policer configuration");
41  }
42  pool_put_index (pm->configs, p[0]);
45 
46  /* free policer */
47  p = hash_get_mem (pm->policer_index_by_name, name);
48  if (p == 0)
49  {
50  vec_free (name);
51  return clib_error_return (0, "No such policer");
52  }
53  pool_put_index (pm->policers, p[0]);
55 
56  vec_free (name);
57  return 0;
58  }
59 
60  if (p != 0)
61  {
62  vec_free (name);
63  return clib_error_return (0, "Policer already exists");
64  }
65 
66  /* Vet the configuration before adding it to the table */
67  rv = sse2_pol_logical_2_physical (cfg, &test_policer);
68 
69  if (rv == 0)
70  {
73 
74  pool_get (pm->configs, cp);
75  pool_get (pm->policer_templates, pp);
76 
77  ASSERT (cp - pm->configs == pp - pm->policer_templates);
78 
79  clib_memcpy (cp, cfg, sizeof (*cp));
80  clib_memcpy (pp, &test_policer, sizeof (*pp));
81 
82  hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
84  policer[0] = pp[0];
85  pi = policer - pm->policers;
86  hash_set_mem (pm->policer_index_by_name, name, pi);
87  *policer_index = pi;
88  }
89  else
90  {
91  vec_free (name);
92  return clib_error_return (0, "Config failed sanity check");
93  }
94 
95  return 0;
96 }
97 
98 u8 *
99 format_policer_instance (u8 * s, va_list * va)
100 {
102  = va_arg (*va, policer_read_response_type_st *);
103 
104  s = format (s, "policer at %llx: %s rate, %s color-aware\n",
105  i, i->single_rate ? "single" : "dual",
106  i->color_aware ? "is" : "not");
107  s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
109  s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
110  i->current_limit,
112  s = format (s, "last update %llu\n", i->last_update_time);
113  return s;
114 }
115 
116 static u8 *
117 format_policer_round_type (u8 * s, va_list * va)
118 {
120 
122  s = format (s, "closest");
123  else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP)
124  s = format (s, "up");
125  else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN)
126  s = format (s, "down");
127  else
128  s = format (s, "ILLEGAL");
129  return s;
130 }
131 
132 
133 static u8 *
134 format_policer_rate_type (u8 * s, va_list * va)
135 {
137 
138  if (c->rate_type == SSE2_QOS_RATE_KBPS)
139  s = format (s, "kbps");
140  else if (c->rate_type == SSE2_QOS_RATE_PPS)
141  s = format (s, "pps");
142  else
143  s = format (s, "ILLEGAL");
144  return s;
145 }
146 
147 static u8 *
148 format_policer_type (u8 * s, va_list * va)
149 {
151 
153  s = format (s, "1r2c");
154 
156  s = format (s, "1r3c");
157 
159  s = format (s, "2r3c-2698");
160 
162  s = format (s, "2r3c-4115");
163 
165  s = format (s, "2r3c-mef5cf1");
166  else
167  s = format (s, "ILLEGAL");
168  return s;
169 }
170 
171 static u8 *
172 format_dscp (u8 * s, va_list * va)
173 {
174  u32 i = va_arg (*va, u32);
175  char *t = 0;
176 
177  switch (i)
178  {
179 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
181 #undef _
182  default:
183  return format (s, "ILLEGAL");
184  }
185  s = format (s, "%s", t);
186  return s;
187 }
188 
189 static u8 *
190 format_policer_action_type (u8 * s, va_list * va)
191 {
193  = va_arg (*va, sse2_qos_pol_action_params_st *);
194 
196  s = format (s, "drop");
197  else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT)
198  s = format (s, "transmit");
200  s = format (s, "mark-and-transmit %U", format_dscp, a->dscp);
201  else
202  s = format (s, "ILLEGAL");
203  return s;
204 }
205 
206 u8 *
207 format_policer_config (u8 * s, va_list * va)
208 {
210 
211  s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
213  c->rb.kbps.cir_kbps,
214  c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
215  s = format (s, "rate type %U, round type %U\n",
217  s = format (s, "conform action %U, exceed action %U, violate action %U\n",
221  return s;
222 }
223 
224 static uword
226 {
228 
229  if (!unformat (input, "type"))
230  return 0;
231 
232  if (unformat (input, "1r2c"))
234  else if (unformat (input, "1r3c"))
236  else if (unformat (input, "2r3c-2698"))
238  else if (unformat (input, "2r3c-4115"))
240  else if (unformat (input, "2r3c-mef5cf1"))
242  else
243  return 0;
244  return 1;
245 }
246 
247 static uword
249 {
251 
252  if (!unformat (input, "round"))
253  return 0;
254 
255  if (unformat (input, "closest"))
257  else if (unformat (input, "up"))
259  else if (unformat (input, "down"))
261  else
262  return 0;
263  return 1;
264 }
265 
266 static uword
268 {
270 
271  if (!unformat (input, "rate"))
272  return 0;
273 
274  if (unformat (input, "kbps"))
276  else if (unformat (input, "pps"))
278  else
279  return 0;
280  return 1;
281 }
282 
283 static uword
284 unformat_policer_cir (unformat_input_t * input, va_list * va)
285 {
287 
288  if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
289  return 1;
290  return 0;
291 }
292 
293 static uword
294 unformat_policer_eir (unformat_input_t * input, va_list * va)
295 {
297 
298  if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
299  return 1;
300  return 0;
301 }
302 
303 static uword
304 unformat_policer_cb (unformat_input_t * input, va_list * va)
305 {
307 
308  if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
309  return 1;
310  return 0;
311 }
312 
313 static uword
314 unformat_policer_eb (unformat_input_t * input, va_list * va)
315 {
317 
318  if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
319  return 1;
320  return 0;
321 }
322 
323 static uword
324 unformat_dscp (unformat_input_t * input, va_list * va)
325 {
326  u8 *r = va_arg (*va, u8 *);
327 
328  if (0);
329 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
331 #undef _
332  else
333  return 0;
334  return 1;
335 }
336 
337 static uword
339 {
341  = va_arg (*va, sse2_qos_pol_action_params_st *);
342 
343  if (unformat (input, "drop"))
345  else if (unformat (input, "transmit"))
347  else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
349  else
350  return 0;
351  return 1;
352 }
353 
354 static uword
356 {
358 
359  if (unformat (input, "conform-action %U", unformat_policer_action_type,
360  &c->conform_action))
361  return 1;
362  else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
363  &c->exceed_action))
364  return 1;
365  else if (unformat (input, "violate-action %U", unformat_policer_action_type,
366  &c->violate_action))
367  return 1;
368  return 0;
369 }
370 
371 static uword
373 {
374  u32 *r = va_arg (*va, u32 *);
376  uword *p;
377  u8 *match_name = 0;
378 
379  if (unformat (input, "%s", &match_name))
380  ;
381  else
382  return 0;
383 
384  p = hash_get_mem (pm->policer_index_by_name, match_name);
385 
386  if (p == 0)
387  return 0;
388 
389  *r = p[0];
390 
391  return 1;
392 }
393 
394 static uword
396 {
397  u32 *r = va_arg (*va, u32 *);
398 
399  if (unformat (input, "conform-color"))
400  *r = POLICE_CONFORM;
401  else if (unformat (input, "exceed-color"))
402  *r = POLICE_EXCEED;
403  else
404  return 0;
405 
406  return 1;
407 }
408 
409 #define foreach_config_param \
410 _(eb) \
411 _(cb) \
412 _(eir) \
413 _(cir) \
414 _(rate_type) \
415 _(round_type) \
416 _(type) \
417 _(action)
418 
419 static clib_error_t *
421  unformat_input_t * input,
422  vlib_cli_command_t * cmd)
423 {
425  unformat_input_t _line_input, *line_input = &_line_input;
426  u8 is_add = 1;
427  u8 *name = 0;
428  u32 pi;
429  clib_error_t *error = NULL;
430 
431  /* Get a line of input. */
432  if (!unformat_user (input, unformat_line_input, line_input))
433  return 0;
434 
435  memset (&c, 0, sizeof (c));
436 
437  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
438  {
439  if (unformat (line_input, "del"))
440  is_add = 0;
441  else if (unformat (line_input, "name %s", &name))
442  ;
443  else if (unformat (line_input, "color-aware"))
444  c.color_aware = 1;
445 
446 #define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
448 #undef _
449  else
450  {
451  error = clib_error_return (0, "unknown input `%U'",
452  format_unformat_error, line_input);
453  goto done;
454  }
455  }
456 
457  error = policer_add_del (vm, name, &c, &pi, is_add);
458 
459 done:
460  unformat_free (line_input);
461 
462  return error;
463 }
464 
465 /* *INDENT-OFF* */
466 VLIB_CLI_COMMAND (configure_policer_command, static) = {
467  .path = "configure policer",
468  .short_help = "configure policer name <name> <params> ",
469  .function = configure_policer_command_fn,
470 };
471 /* *INDENT-ON* */
472 
473 static clib_error_t *
475  unformat_input_t * input, vlib_cli_command_t * cmd)
476 {
478  hash_pair_t *p;
479  u32 pool_index;
480  u8 *match_name = 0;
481  u8 *name;
484 
485  (void) unformat (input, "name %s", &match_name);
486 
487  /* *INDENT-OFF* */
489  ({
490  name = (u8 *) p->key;
491  if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
492  {
493  pool_index = p->value[0];
494  config = pool_elt_at_index (pm->configs, pool_index);
495  templ = pool_elt_at_index (pm->policer_templates, pool_index);
496  vlib_cli_output (vm, "Name \"%s\" %U ",
497  name, format_policer_config, config);
498  vlib_cli_output (vm, "Template %U",
499  format_policer_instance, templ);
500  vlib_cli_output (vm, "-----------");
501  }
502  }));
503  /* *INDENT-ON* */
504  return 0;
505 }
506 
507 
508 /* *INDENT-OFF* */
509 VLIB_CLI_COMMAND (show_policer_command, static) = {
510  .path = "show policer",
511  .short_help = "show policer [name]",
512  .function = show_policer_command_fn,
513 };
514 /* *INDENT-ON* */
515 
516 static clib_error_t *
518  unformat_input_t * input,
519  vlib_cli_command_t * cmd)
520 {
522 
523  vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
524  pool_elts (pm->configs),
526  pool_elts (pm->policers));
527  return 0;
528 }
529 /* *INDENT-OFF* */
530 VLIB_CLI_COMMAND (show_policer_pools_command, static) = {
531  .path = "show policer pools",
532  .short_help = "show policer pools",
533  .function = show_policer_pools_command_fn,
534 };
535 /* *INDENT-ON* */
536 
537 clib_error_t *
539 {
542 
544 
545  pm->vlib_main = vm;
546  pm->vnet_main = vnet_get_main ();
547 
548  pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
549  pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
550 
555 
556  return 0;
557 }
558 
560 
561 
562 
563 /*
564  * fd.io coding-style-patch-verification: ON
565  *
566  * Local Variables:
567  * eval: (c-set-style "gnu")
568  * End:
569  */
uword * policer_index_by_name
Definition: policer.h:37
static uword unformat_policer_eir(unformat_input_t *input, va_list *va)
Definition: policer.c:294
sse2_qos_pol_cfg_params_st * configs
Definition: policer.h:30
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static uword unformat_policer_action(unformat_input_t *input, va_list *va)
Definition: policer.c:355
#define foreach_config_param
Definition: policer.c:409
a
Definition: bitmap.h:516
sse2_qos_pol_action_params_st conform_action
Definition: xlate.h:151
struct sse2_qos_pol_cfg_params_st_::@234::@235 kbps
static u8 * format_dscp(u8 *s, va_list *va)
Definition: policer.c:172
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
uword * policer_config_by_name
Definition: policer.h:34
#define NULL
Definition: clib.h:55
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
#define hash_set_mem(h, key, value)
Definition: hash.h:274
static uword unformat_policer_rate_type(unformat_input_t *input, va_list *va)
Definition: policer.c:267
vnet_main_t * vnet_main
Definition: policer.h:44
union sse2_qos_pol_cfg_params_st_::@234 rb
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static uword unformat_policer_type(unformat_input_t *input, va_list *va)
Definition: policer.c:225
u8 * format_policer_instance(u8 *s, va_list *va)
Definition: policer.c:99
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
static u8 * format_policer_round_type(u8 *s, va_list *va)
Definition: policer.c:117
static uword unformat_policer_action_type(unformat_input_t *input, va_list *va)
Definition: policer.c:338
static clib_error_t * show_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:474
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static u8 * format_policer_rate_type(u8 *s, va_list *va)
Definition: policer.c:134
#define clib_error_return(e, args...)
Definition: error.h:99
static uword unformat_policer_round_type(unformat_input_t *input, va_list *va)
Definition: policer.c:248
static uword unformat_policer_cir(unformat_input_t *input, va_list *va)
Definition: policer.c:284
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
unformat_function_t unformat_line_input
Definition: format.h:281
#define hash_unset_mem(h, key)
Definition: hash.h:280
clib_error_t * policer_init(vlib_main_t *vm)
Definition: policer.c:538
struct _unformat_input_t unformat_input_t
sse2_qos_pol_action_params_st violate_action
Definition: xlate.h:153
void vnet_classify_register_unformat_opaque_index_fn(unformat_function_t *fn)
policer_read_response_type_st * policers
Definition: policer.h:27
void vnet_policer_node_funcs_reference(void)
Definition: node_funcs.c:353
sse2_qos_pol_action_params_st exceed_action
Definition: xlate.h:152
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:188
vlib_main_t * vlib_main
Definition: policer.h:43
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
svmdb_client_t * c
vlib_main_t * vm
Definition: buffer.c:283
static uword unformat_policer_classify_next_index(unformat_input_t *input, va_list *va)
Definition: policer.c:372
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
static clib_error_t * configure_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:420
#define clib_memcpy(a, b, c)
Definition: string.h:69
int sse2_pol_logical_2_physical(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *phys)
Definition: xlate.c:1171
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:293
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
clib_error_t * policer_add_del(vlib_main_t *vm, u8 *name, sse2_qos_pol_cfg_params_st *cfg, u32 *policer_index, u8 is_add)
Definition: policer.c:20
static uword unformat_dscp(unformat_input_t *input, va_list *va)
Definition: policer.c:324
static u8 * format_policer_type(u8 *s, va_list *va)
Definition: policer.c:148
u64 uword
Definition: types.h:112
u8 * format_policer_config(u8 *s, va_list *va)
Definition: policer.c:207
static clib_error_t * show_policer_pools_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:517
unsigned char u8
Definition: types.h:56
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:349
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
static u8 * format_policer_action_type(u8 *s, va_list *va)
Definition: policer.c:190
#define hash_get_mem(h, key)
Definition: hash.h:268
static uword unformat_policer_cb(unformat_input_t *input, va_list *va)
Definition: policer.c:304
static uword unformat_policer_classify_precolor(unformat_input_t *input, va_list *va)
Definition: policer.c:395
policer_read_response_type_st * policer_templates
Definition: policer.h:31
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void vnet_classify_register_unformat_policer_next_index_fn(unformat_function_t *fn)
Definition: vnet_classify.c:93
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
vnet_policer_main_t vnet_policer_main
Definition: policer.h:47
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_policer_eb(unformat_input_t *input, va_list *va)
Definition: policer.c:314
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128