FD.io VPP  v17.01.1-3-gc6833f8
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  if (p == 0)
37  {
38  vec_free (name);
39  return clib_error_return (0, "No such policer configuration");
40  }
43  vec_free (name);
44  return 0;
45  }
46 
47  if (p != 0)
48  {
49  vec_free (name);
50  return clib_error_return (0, "Policer already exists");
51  }
52 
53  /* Vet the configuration before adding it to the table */
54  rv = sse2_pol_logical_2_physical (cfg, &test_policer);
55 
56  if (rv == 0)
57  {
60 
61  pool_get (pm->configs, cp);
62  pool_get (pm->policer_templates, pp);
63 
64  ASSERT (cp - pm->configs == pp - pm->policer_templates);
65 
66  clib_memcpy (cp, cfg, sizeof (*cp));
67  clib_memcpy (pp, &test_policer, sizeof (*pp));
68 
69  hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
71  policer[0] = pp[0];
72  pi = policer - pm->policers;
73  hash_set_mem (pm->policer_index_by_name, name, pi);
74  *policer_index = pi;
75  }
76  else
77  {
78  vec_free (name);
79  return clib_error_return (0, "Config failed sanity check");
80  }
81 
82  return 0;
83 }
84 
85 u8 *
86 format_policer_instance (u8 * s, va_list * va)
87 {
89  = va_arg (*va, policer_read_response_type_st *);
90 
91  s = format (s, "policer at %llx: %s rate, %s color-aware\n",
92  i, i->single_rate ? "single" : "dual",
93  i->color_aware ? "is" : "not");
94  s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
96  s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
97  i->current_limit,
99  s = format (s, "last update %llu\n", i->last_update_time);
100  return s;
101 }
102 
103 static u8 *
104 format_policer_round_type (u8 * s, va_list * va)
105 {
107 
109  s = format (s, "closest");
110  else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP)
111  s = format (s, "up");
112  else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN)
113  s = format (s, "down");
114  else
115  s = format (s, "ILLEGAL");
116  return s;
117 }
118 
119 
120 static u8 *
121 format_policer_rate_type (u8 * s, va_list * va)
122 {
124 
125  if (c->rate_type == SSE2_QOS_RATE_KBPS)
126  s = format (s, "kbps");
127  else if (c->rate_type == SSE2_QOS_RATE_PPS)
128  s = format (s, "pps");
129  else
130  s = format (s, "ILLEGAL");
131  return s;
132 }
133 
134 static u8 *
135 format_policer_type (u8 * s, va_list * va)
136 {
138 
140  s = format (s, "1r2c");
141 
143  s = format (s, "1r3c");
144 
146  s = format (s, "2r3c-2698");
147 
149  s = format (s, "2r3c-4115");
150 
152  s = format (s, "2r3c-mef5cf1");
153  else
154  s = format (s, "ILLEGAL");
155  return s;
156 }
157 
158 static u8 *
159 format_dscp (u8 * s, va_list * va)
160 {
161  u32 i = va_arg (*va, u32);
162  char *t = 0;
163 
164  switch (i)
165  {
166 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
168 #undef _
169  default:
170  return format (s, "ILLEGAL");
171  }
172  s = format (s, "%s", t);
173  return s;
174 }
175 
176 static u8 *
177 format_policer_action_type (u8 * s, va_list * va)
178 {
180  = va_arg (*va, sse2_qos_pol_action_params_st *);
181 
183  s = format (s, "drop");
184  else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT)
185  s = format (s, "transmit");
187  s = format (s, "mark-and-transmit %U", format_dscp, a->dscp);
188  else
189  s = format (s, "ILLEGAL");
190  return s;
191 }
192 
193 u8 *
194 format_policer_config (u8 * s, va_list * va)
195 {
197 
198  s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
200  c->rb.kbps.cir_kbps,
201  c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
202  s = format (s, "rate type %U, round type %U\n",
204  s = format (s, "conform action %U, exceed action %U, violate action %U\n",
208  return s;
209 }
210 
211 static uword
213 {
215 
216  if (!unformat (input, "type"))
217  return 0;
218 
219  if (unformat (input, "1r2c"))
221  else if (unformat (input, "1r3c"))
223  else if (unformat (input, "2r3c-2698"))
225  else if (unformat (input, "2r3c-4115"))
227  else if (unformat (input, "2r3c-mef5cf1"))
229  else
230  return 0;
231  return 1;
232 }
233 
234 static uword
236 {
238 
239  if (!unformat (input, "round"))
240  return 0;
241 
242  if (unformat (input, "closest"))
244  else if (unformat (input, "up"))
246  else if (unformat (input, "down"))
248  else
249  return 0;
250  return 1;
251 }
252 
253 static uword
255 {
257 
258  if (!unformat (input, "rate"))
259  return 0;
260 
261  if (unformat (input, "kbps"))
263  else if (unformat (input, "pps"))
265  else
266  return 0;
267  return 1;
268 }
269 
270 static uword
271 unformat_policer_cir (unformat_input_t * input, va_list * va)
272 {
274 
275  if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
276  return 1;
277  return 0;
278 }
279 
280 static uword
281 unformat_policer_eir (unformat_input_t * input, va_list * va)
282 {
284 
285  if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
286  return 1;
287  return 0;
288 }
289 
290 static uword
291 unformat_policer_cb (unformat_input_t * input, va_list * va)
292 {
294 
295  if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
296  return 1;
297  return 0;
298 }
299 
300 static uword
301 unformat_policer_eb (unformat_input_t * input, va_list * va)
302 {
304 
305  if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
306  return 1;
307  return 0;
308 }
309 
310 static uword
311 unformat_dscp (unformat_input_t * input, va_list * va)
312 {
313  u8 *r = va_arg (*va, u8 *);
314 
315  if (0);
316 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
318 #undef _
319  else
320  return 0;
321  return 1;
322 }
323 
324 static uword
326 {
328  = va_arg (*va, sse2_qos_pol_action_params_st *);
329 
330  if (unformat (input, "drop"))
332  else if (unformat (input, "transmit"))
334  else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
336  else
337  return 0;
338  return 1;
339 }
340 
341 static uword
343 {
345 
346  if (unformat (input, "conform-action %U", unformat_policer_action_type,
347  &c->conform_action))
348  return 1;
349  else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
350  &c->exceed_action))
351  return 1;
352  else if (unformat (input, "violate-action %U", unformat_policer_action_type,
353  &c->violate_action))
354  return 1;
355  return 0;
356 }
357 
358 static uword
360 {
361  u32 *r = va_arg (*va, u32 *);
363  uword *p;
364  u8 *match_name = 0;
365 
366  if (unformat (input, "%s", &match_name))
367  ;
368  else
369  return 0;
370 
371  p = hash_get_mem (pm->policer_index_by_name, match_name);
372 
373  if (p == 0)
374  return 0;
375 
376  *r = p[0];
377 
378  return 1;
379 }
380 
381 static uword
383 {
384  u32 *r = va_arg (*va, u32 *);
385 
386  if (unformat (input, "conform-color"))
387  *r = POLICE_CONFORM;
388  else if (unformat (input, "exceed-color"))
389  *r = POLICE_EXCEED;
390  else
391  return 0;
392 
393  return 1;
394 }
395 
396 #define foreach_config_param \
397 _(eb) \
398 _(cb) \
399 _(eir) \
400 _(cir) \
401 _(rate_type) \
402 _(round_type) \
403 _(type) \
404 _(action)
405 
406 static clib_error_t *
408  unformat_input_t * input,
409  vlib_cli_command_t * cmd)
410 {
412  unformat_input_t _line_input, *line_input = &_line_input;
413  u8 is_add = 1;
414  u8 *name = 0;
415  u32 pi;
416 
417  /* Get a line of input. */
418  if (!unformat_user (input, unformat_line_input, line_input))
419  return 0;
420 
421  memset (&c, 0, sizeof (c));
422 
423  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
424  {
425  if (unformat (line_input, "del"))
426  is_add = 0;
427  else if (unformat (line_input, "name %s", &name))
428  ;
429  else if (unformat (line_input, "color-aware"))
430  c.color_aware = 1;
431 
432 #define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
434 #undef _
435  else
436  return clib_error_return (0, "unknown input `%U'",
437  format_unformat_error, line_input);
438  }
439 
440  unformat_free (line_input);
441 
442  return policer_add_del (vm, name, &c, &pi, is_add);
443 }
444 
445 /* *INDENT-OFF* */
446 VLIB_CLI_COMMAND (configure_policer_command, static) = {
447  .path = "configure policer",
448  .short_help = "configure policer name <name> <params> ",
449  .function = configure_policer_command_fn,
450 };
451 /* *INDENT-ON* */
452 
453 static clib_error_t *
455  unformat_input_t * input, vlib_cli_command_t * cmd)
456 {
458  hash_pair_t *p;
459  u32 pool_index;
460  u8 *match_name = 0;
461  u8 *name;
464 
465  (void) unformat (input, "name %s", &match_name);
466 
467  /* *INDENT-OFF* */
469  ({
470  name = (u8 *) p->key;
471  if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
472  {
473  pool_index = p->value[0];
474  config = pool_elt_at_index (pm->configs, pool_index);
475  templ = pool_elt_at_index (pm->policer_templates, pool_index);
476  vlib_cli_output (vm, "Name \"%s\" %U ",
477  name, format_policer_config, config);
478  vlib_cli_output (vm, "Template %U",
479  format_policer_instance, templ);
480  vlib_cli_output (vm, "-----------");
481  }
482  }));
483  /* *INDENT-ON* */
484  return 0;
485 }
486 
487 
488 /* *INDENT-OFF* */
489 VLIB_CLI_COMMAND (show_policer_command, static) = {
490  .path = "show policer",
491  .short_help = "show policer [name]",
492  .function = show_policer_command_fn,
493 };
494 /* *INDENT-ON* */
495 
496 clib_error_t *
498 {
501 
503 
504  pm->vlib_main = vm;
505  pm->vnet_main = vnet_get_main ();
506 
507  pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
508  pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
509 
514 
515  return 0;
516 }
517 
519 
520 
521 
522 /*
523  * fd.io coding-style-patch-verification: ON
524  *
525  * Local Variables:
526  * eval: (c-set-style "gnu")
527  * End:
528  */
uword * policer_index_by_name
Definition: policer.h:37
static uword unformat_policer_eir(unformat_input_t *input, va_list *va)
Definition: policer.c:281
sse2_qos_pol_cfg_params_st * configs
Definition: policer.h:30
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static uword unformat_policer_action(unformat_input_t *input, va_list *va)
Definition: policer.c:342
#define foreach_config_param
Definition: policer.c:396
a
Definition: bitmap.h:516
sse2_qos_pol_action_params_st conform_action
Definition: xlate.h:151
static u8 * format_dscp(u8 *s, va_list *va)
Definition: policer.c:159
uword * policer_config_by_name
Definition: policer.h:34
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#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:254
vnet_main_t * vnet_main
Definition: policer.h:44
static uword unformat_policer_type(unformat_input_t *input, va_list *va)
Definition: policer.c:212
u8 * format_policer_instance(u8 *s, va_list *va)
Definition: policer.c:86
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static u8 * format_policer_round_type(u8 *s, va_list *va)
Definition: policer.c:104
static uword unformat_policer_action_type(unformat_input_t *input, va_list *va)
Definition: policer.c:325
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static clib_error_t * show_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:454
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static u8 * format_policer_rate_type(u8 *s, va_list *va)
Definition: policer.c:121
static uword unformat_policer_round_type(unformat_input_t *input, va_list *va)
Definition: policer.c:235
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
static uword unformat_policer_cir(unformat_input_t *input, va_list *va)
Definition: policer.c:271
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
#define hash_unset_mem(h, key)
Definition: hash.h:280
clib_error_t * policer_init(vlib_main_t *vm)
Definition: policer.c:497
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:169
vlib_main_t * vlib_main
Definition: policer.h:43
svmdb_client_t * c
static uword unformat_policer_classify_next_index(unformat_input_t *input, va_list *va)
Definition: policer.c:359
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static clib_error_t * configure_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:407
#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 ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
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
union sse2_qos_pol_cfg_params_st_::@238 rb
static uword unformat_dscp(unformat_input_t *input, va_list *va)
Definition: policer.c:311
static u8 * format_policer_type(u8 *s, va_list *va)
Definition: policer.c:135
u64 uword
Definition: types.h:112
u8 * format_policer_config(u8 *s, va_list *va)
Definition: policer.c:194
unsigned char u8
Definition: types.h:56
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:349
static u8 * format_policer_action_type(u8 *s, va_list *va)
Definition: policer.c:177
#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:291
static uword unformat_policer_classify_precolor(unformat_input_t *input, va_list *va)
Definition: policer.c:382
policer_read_response_type_st * policer_templates
Definition: policer.h:31
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
void vnet_classify_register_unformat_policer_next_index_fn(unformat_function_t *fn)
Definition: vnet_classify.c:93
#define clib_error_return(e, args...)
Definition: error.h:111
struct sse2_qos_pol_cfg_params_st_::@238::@239 kbps
struct _unformat_input_t unformat_input_t
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
unformat_function_t unformat_line_input
Definition: format.h:281
vnet_policer_main_t vnet_policer_main
Definition: policer.h:47
static uword unformat_policer_eb(unformat_input_t *input, va_list *va)
Definition: policer.c:301