FD.io VPP  v17.04-9-g99c0734
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  clib_error_t *error = NULL;
417 
418  /* Get a line of input. */
419  if (!unformat_user (input, unformat_line_input, line_input))
420  return 0;
421 
422  memset (&c, 0, sizeof (c));
423 
424  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
425  {
426  if (unformat (line_input, "del"))
427  is_add = 0;
428  else if (unformat (line_input, "name %s", &name))
429  ;
430  else if (unformat (line_input, "color-aware"))
431  c.color_aware = 1;
432 
433 #define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
435 #undef _
436  else
437  {
438  error = clib_error_return (0, "unknown input `%U'",
439  format_unformat_error, line_input);
440  goto done;
441  }
442  }
443 
444  error = policer_add_del (vm, name, &c, &pi, is_add);
445 
446 done:
447  unformat_free (line_input);
448 
449  return error;
450 }
451 
452 /* *INDENT-OFF* */
453 VLIB_CLI_COMMAND (configure_policer_command, static) = {
454  .path = "configure policer",
455  .short_help = "configure policer name <name> <params> ",
456  .function = configure_policer_command_fn,
457 };
458 /* *INDENT-ON* */
459 
460 static clib_error_t *
462  unformat_input_t * input, vlib_cli_command_t * cmd)
463 {
465  hash_pair_t *p;
466  u32 pool_index;
467  u8 *match_name = 0;
468  u8 *name;
471 
472  (void) unformat (input, "name %s", &match_name);
473 
474  /* *INDENT-OFF* */
476  ({
477  name = (u8 *) p->key;
478  if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
479  {
480  pool_index = p->value[0];
481  config = pool_elt_at_index (pm->configs, pool_index);
482  templ = pool_elt_at_index (pm->policer_templates, pool_index);
483  vlib_cli_output (vm, "Name \"%s\" %U ",
484  name, format_policer_config, config);
485  vlib_cli_output (vm, "Template %U",
486  format_policer_instance, templ);
487  vlib_cli_output (vm, "-----------");
488  }
489  }));
490  /* *INDENT-ON* */
491  return 0;
492 }
493 
494 
495 /* *INDENT-OFF* */
496 VLIB_CLI_COMMAND (show_policer_command, static) = {
497  .path = "show policer",
498  .short_help = "show policer [name]",
499  .function = show_policer_command_fn,
500 };
501 /* *INDENT-ON* */
502 
503 clib_error_t *
505 {
508 
510 
511  pm->vlib_main = vm;
512  pm->vnet_main = vnet_get_main ();
513 
514  pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
515  pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
516 
521 
522  return 0;
523 }
524 
526 
527 
528 
529 /*
530  * fd.io coding-style-patch-verification: ON
531  *
532  * Local Variables:
533  * eval: (c-set-style "gnu")
534  * End:
535  */
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
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
union sse2_qos_pol_cfg_params_st_::@198 rb
static u8 * format_dscp(u8 *s, va_list *va)
Definition: policer.c:159
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:982
#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
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
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
struct sse2_qos_pol_cfg_params_st_::@198::@199 kbps
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
static clib_error_t * show_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:461
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static u8 * format_policer_rate_type(u8 *s, va_list *va)
Definition: policer.c:121
#define clib_error_return(e, args...)
Definition: error.h:111
static uword unformat_policer_round_type(unformat_input_t *input, va_list *va)
Definition: policer.c:235
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
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:504
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:169
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:276
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:340
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
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: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 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: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
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
vnet_policer_main_t vnet_policer_main
Definition: policer.h:47
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
static uword unformat_policer_eb(unformat_input_t *input, va_list *va)
Definition: policer.c:301
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169