FD.io VPP  v16.09
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,
24  u8 is_add)
25 {
27  policer_read_response_type_st test_policer;
29  uword * p;
30  u32 pi;
31  int rv;
32 
33  p = hash_get_mem (pm->policer_config_by_name, name);
34 
35  if (is_add == 0)
36  {
37  if (p == 0)
38  {
39  vec_free(name);
40  return clib_error_return (0, "No such policer configuration");
41  }
44  vec_free(name);
45  return 0;
46  }
47 
48  if (p != 0)
49  {
50  vec_free(name);
51  return clib_error_return (0, "Policer already exists");
52  }
53 
54  /* Vet the configuration before adding it to the table */
55  rv = sse2_pol_logical_2_physical (cfg, &test_policer);
56 
57  if (rv == 0)
58  {
61 
62  pool_get (pm->configs, cp);
63  pool_get (pm->policer_templates, pp);
64 
65  ASSERT (cp - pm->configs == pp - pm->policer_templates);
66 
67  clib_memcpy (cp, cfg, sizeof (*cp));
68  clib_memcpy (pp, &test_policer, sizeof (*pp));
69 
70  hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
72  policer[0] = pp[0];
73  pi = policer - pm->policers;
74  hash_set_mem (pm->policer_index_by_name, name, pi);
75  *policer_index = pi;
76  }
77  else
78  {
79  vec_free (name);
80  return clib_error_return (0, "Config failed sanity check");
81  }
82 
83  return 0;
84 }
85 
86 u8 * 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  i->scale);
97  s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
98  i->current_limit,
99  i->current_bucket,
100  i->extended_limit,
101  i->extended_bucket);
102  s = format (s, "last update %llu\n", i->last_update_time);
103  return s;
104 }
105 
106 static u8 * format_policer_round_type (u8 * s, va_list * va)
107 {
109  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
110 
112  s = format(s, "closest");
113  else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP)
114  s = format (s, "up");
115  else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN)
116  s = format (s, "down");
117  else
118  s = format (s, "ILLEGAL");
119  return s;
120 }
121 
122 
123 static u8 * format_policer_rate_type (u8 * s, va_list * va)
124 {
126  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
127 
128  if (c->rate_type == SSE2_QOS_RATE_KBPS)
129  s = format (s, "kbps");
130  else if (c->rate_type == SSE2_QOS_RATE_PPS)
131  s = format(s, "pps");
132  else
133  s = format (s, "ILLEGAL");
134  return s;
135 }
136 
137 static u8 * format_policer_type (u8 * s, va_list * va)
138 {
140  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
141 
143  s = format (s, "1r2c");
144 
146  s = format (s, "1r3c");
147 
149  s = format (s, "2r3c-2698");
150 
152  s = format (s, "2r3c-4115");
153 
155  s = format (s, "2r3c-mef5cf1");
156  else
157  s = format (s, "ILLEGAL");
158  return s;
159 }
160 
161 static u8 * format_dscp (u8 * s, va_list * va)
162 {
163  u32 i = va_arg (*va, u32);
164  char * t = 0;
165 
166  switch (i) {
167  #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
169  #undef _
170  default:
171  return format (s, "ILLEGAL");
172  }
173  s = format (s, "%s", t);
174  return s;
175 }
176 
177 static u8 * 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 * format_policer_config (u8 * s, va_list * va)
194 {
196  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
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,
202  c->rb.kbps.cb_bytes,
203  c->rb.kbps.eb_bytes);
204  s = format (s, "rate type %U, round type %U\n",
207  s = format (s, "conform action %U, exceed action %U, violate action %U\n",
211  return s;
212 }
213 
214 static uword
216 {
218  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
219 
220  if (!unformat (input, "type"))
221  return 0;
222 
223  if (unformat (input, "1r2c"))
225  else if (unformat (input, "1r3c"))
227  else if (unformat (input, "2r3c-2698"))
229  else if (unformat (input, "2r3c-4115"))
231  else if (unformat (input, "2r3c-mef5cf1"))
233  else
234  return 0;
235  return 1;
236 }
237 
238 static uword
240 {
242  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
243 
244  if (!unformat(input, "round"))
245  return 0;
246 
247  if (unformat(input, "closest"))
249  else if (unformat (input, "up"))
251  else if (unformat (input, "down"))
253  else
254  return 0;
255  return 1;
256 }
257 
258 static uword
260 {
262  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
263 
264  if (!unformat(input, "rate"))
265  return 0;
266 
267  if (unformat (input, "kbps"))
269  else if (unformat(input, "pps"))
271  else
272  return 0;
273  return 1;
274 }
275 
276 static uword
277 unformat_policer_cir (unformat_input_t * input, va_list * va)
278 {
280  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
281 
282  if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
283  return 1;
284  return 0;
285 }
286 
287 static uword
288 unformat_policer_eir (unformat_input_t * input, va_list * va)
289 {
291  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
292 
293  if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
294  return 1;
295  return 0;
296 }
297 
298 static uword
299 unformat_policer_cb (unformat_input_t * input, va_list * va)
300 {
302  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
303 
304  if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
305  return 1;
306  return 0;
307 }
308 
309 static uword
310 unformat_policer_eb (unformat_input_t * input, va_list * va)
311 {
313  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
314 
315  if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
316  return 1;
317  return 0;
318 }
319 
320 static uword
321 unformat_dscp (unformat_input_t * input, va_list * va)
322 {
323  u8 * r = va_arg (*va, u8 *);
324 
325  if (0) ;
326 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
328 #undef _
329  else
330  return 0;
331  return 1;
332 }
333 
334 static uword
336 {
338  = va_arg (*va, sse2_qos_pol_action_params_st *);
339 
340  if (unformat (input, "drop"))
342  else if (unformat (input, "transmit"))
344  else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
346  else
347  return 0;
348  return 1;
349 }
350 
351 static uword
353 {
355  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
356 
357  if (unformat (input, "conform-action %U", unformat_policer_action_type,
358  &c->conform_action))
359  return 1;
360  else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
361  &c->exceed_action))
362  return 1;
363  else if (unformat (input, "violate-action %U", unformat_policer_action_type,
364  &c->violate_action))
365  return 1;
366  return 0;
367 }
368 
369 static uword
371 {
372  u32 * r = va_arg (*va, u32 *);
374  uword * p;
375  u8 * match_name = 0;
376 
377  if (unformat (input, "%s", &match_name))
378  ;
379  else
380  return 0;
381 
382  p = hash_get_mem (pm->policer_index_by_name, match_name);
383 
384  if (p == 0)
385  return 0;
386 
387  *r = p[0];
388 
389  return 1;
390 }
391 
392 static uword
394 {
395  u32 * r = va_arg (*va, u32 *);
396 
397  if (unformat (input, "conform-color"))
398  *r = POLICE_CONFORM;
399  else if (unformat (input, "exceed-color"))
400  *r = POLICE_EXCEED;
401  else
402  return 0;
403 
404  return 1;
405 }
406 
407 #define foreach_config_param \
408 _(eb) \
409 _(cb) \
410 _(eir) \
411 _(cir) \
412 _(rate_type) \
413 _(round_type) \
414 _(type) \
415 _(action)
416 
417 static clib_error_t *
419  unformat_input_t * input,
420  vlib_cli_command_t * cmd)
421 {
423  unformat_input_t _line_input, * line_input = &_line_input;
424  u8 is_add = 1;
425  u8 * name = 0;
426  u32 pi;
427 
428  /* Get a line of input. */
429  if (! unformat_user (input, unformat_line_input, line_input))
430  return 0;
431 
432  memset (&c, 0, sizeof (c));
433 
434  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
435  {
436  if (unformat (line_input, "del"))
437  is_add = 0;
438  else if (unformat(line_input, "name %s", &name))
439  ;
440  else if (unformat(line_input, "color-aware"))
441  c.color_aware = 1;
442 
443 #define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
445 #undef _
446 
447  else
448  return clib_error_return (0, "unknown input `%U'",
449  format_unformat_error, line_input);
450  }
451 
452  unformat_free (line_input);
453 
454  return policer_add_del(vm, name, &c, &pi, is_add);
455 }
456 
457 VLIB_CLI_COMMAND (configure_policer_command, static) = {
458  .path = "configure policer",
459  .short_help = "configure policer name <name> <params> ",
460  .function = configure_policer_command_fn,
461 };
462 
463 
464 static clib_error_t *
466  unformat_input_t * input,
467  vlib_cli_command_t * cmd)
468 {
470  hash_pair_t * p;
471  u32 pool_index;
472  u8 * match_name = 0;
473  u8 * name;
476 
477  (void) unformat (input, "name %s", &match_name);
478 
480  ({
481  name = (u8 *) p->key;
482  if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
483  {
484  pool_index = p->value[0];
485  config = pool_elt_at_index (pm->configs, pool_index);
486  templ = pool_elt_at_index (pm->policer_templates, pool_index);
487  vlib_cli_output (vm, "Name \"%s\" %U ",
488  name, format_policer_config, config);
489  vlib_cli_output (vm, "Template %U",
490  format_policer_instance, templ);
491  vlib_cli_output (vm, "-----------");
492  }
493  }));
494  return 0;
495 }
496 
497 
498 VLIB_CLI_COMMAND (show_policer_command, static) = {
499  .path = "show policer",
500  .short_help = "show policer [name]",
501  .function = show_policer_command_fn,
502 };
503 
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 
uword * policer_index_by_name
Definition: policer.h:36
static uword unformat_policer_eir(unformat_input_t *input, va_list *va)
Definition: policer.c:288
sse2_qos_pol_cfg_params_st * configs
Definition: policer.h:29
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:352
#define foreach_config_param
Definition: policer.c:407
a
Definition: bitmap.h:516
sse2_qos_pol_action_params_st conform_action
Definition: xlate.h:143
static u8 * format_dscp(u8 *s, va_list *va)
Definition: policer.c:161
uword * policer_config_by_name
Definition: policer.h:33
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define hash_set_mem(h, key, value)
Definition: hash.h:274
trans_layer_rc sse2_pol_logical_2_physical(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *phys)
Definition: xlate.c:1085
static uword unformat_policer_rate_type(unformat_input_t *input, va_list *va)
Definition: policer.c:259
vnet_main_t * vnet_main
Definition: policer.h:43
static uword unformat_policer_type(unformat_input_t *input, va_list *va)
Definition: policer.c:215
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:106
static uword unformat_policer_action_type(unformat_input_t *input, va_list *va)
Definition: policer.c:335
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
static clib_error_t * show_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:465
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static u8 * format_policer_rate_type(u8 *s, va_list *va)
Definition: policer.c:123
struct sse2_qos_pol_cfg_params_st_::@190::@191 kbps
static uword unformat_policer_round_type(unformat_input_t *input, va_list *va)
Definition: policer.c:239
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
union sse2_qos_pol_cfg_params_st_::@190 rb
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:277
#define hash_create_string(elts, value_bytes)
Definition: hash.h:641
#define hash_unset_mem(h, key)
Definition: hash.h:280
clib_error_t * policer_init(vlib_main_t *vm)
Definition: policer.c:504
sse2_qos_pol_action_params_st violate_action
Definition: xlate.h:145
void vnet_classify_register_unformat_opaque_index_fn(unformat_function_t *fn)
Definition: vnet_classify.c:99
policer_read_response_type_st * policers
Definition: policer.h:26
void vnet_policer_node_funcs_reference(void)
Definition: node_funcs.c:356
sse2_qos_pol_action_params_st exceed_action
Definition: xlate.h:144
#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:42
svmdb_client_t * c
static uword unformat_policer_classify_next_index(unformat_input_t *input, va_list *va)
Definition: policer.c:370
#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:418
#define clib_memcpy(a, b, c)
Definition: string.h:63
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
uint32_t cir_tokens_per_period
Definition: police.h:74
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
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:418
static uword unformat_dscp(unformat_input_t *input, va_list *va)
Definition: policer.c:321
static u8 * format_policer_type(u8 *s, va_list *va)
Definition: policer.c:137
u64 uword
Definition: types.h:112
u8 * format_policer_config(u8 *s, va_list *va)
Definition: policer.c:193
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
unsigned char u8
Definition: types.h:56
#define hash_foreach_pair(p, v, body)
Definition: hash.h:338
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:299
static uword unformat_policer_classify_precolor(unformat_input_t *input, va_list *va)
Definition: policer.c:393
policer_read_response_type_st * policer_templates
Definition: policer.h:30
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
void vnet_classify_register_unformat_policer_next_index_fn(unformat_function_t *fn)
Definition: vnet_classify.c:92
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
uint32_t pir_tokens_per_period
Definition: police.h:75
unformat_function_t unformat_line_input
Definition: format.h:281
vnet_policer_main_t vnet_policer_main
Definition: policer.h:46
static uword unformat_policer_eb(unformat_input_t *input, va_list *va)
Definition: policer.c:310