FD.io VPP  v16.06
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>
17 
20  u8 * name, sse2_qos_pol_cfg_params_st * cfg,
21  u8 is_add)
22 {
24  policer_read_response_type_st test_policer;
25  uword * p;
26  int rv;
27 
28  if (is_add == 0)
29  {
30  p = hash_get_mem (pm->policer_config_by_name, name);
31  if (p == 0)
32  {
33  vec_free(name);
34  return clib_error_return (0, "No such policer configuration");
35  }
37  vec_free(name);
38  return 0;
39  }
40 
41  /* Vet the configuration before adding it to the table */
42  rv = sse2_pol_logical_2_physical (cfg, &test_policer);
43 
44  if (rv == 0)
45  {
48 
49  pool_get (pm->configs, cp);
50  pool_get (pm->policer_templates, pp);
51 
52  ASSERT (cp - pm->configs == pp - pm->policer_templates);
53 
54  clib_memcpy (cp, cfg, sizeof (*cp));
55  clib_memcpy (pp, &test_policer, sizeof (*pp));
56 
57  hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
58  }
59  else
60  {
61  vec_free (name);
62  return clib_error_return (0, "Config failed sanity check");
63  }
64 
65  return 0;
66 }
67 
68 u8 * format_policer_instance (u8 * s, va_list * va)
69 {
71  = va_arg (*va, policer_read_response_type_st *);
72 
73  s = format (s, "policer at %llx: %s rate, %s color-aware\n",
74  i, i->single_rate ? "single" : "dual",
75  i->color_aware ? "is" : "not");
76  s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
78  i->scale);
79  s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
80  i->current_limit,
81  i->current_bucket,
82  i->extended_limit,
83  i->extended_bucket);
84  s = format (s, "last update %llu\n", i->last_update_time);
85  return s;
86 }
87 
88 static u8 * format_policer_round_type (u8 * s, va_list * va)
89 {
91  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
92 
94  s = format(s, "closest");
95  else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP)
96  s = format (s, "up");
97  else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN)
98  s = format (s, "down");
99  else
100  s = format (s, "ILLEGAL");
101  return s;
102 }
103 
104 
105 static u8 * format_policer_rate_type (u8 * s, va_list * va)
106 {
108  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
109 
110  if (c->rate_type == SSE2_QOS_RATE_KBPS)
111  s = format (s, "kbps");
112  else if (c->rate_type == SSE2_QOS_RATE_PPS)
113  s = format(s, "pps");
114  else
115  s = format (s, "ILLEGAL");
116  return s;
117 }
118 
119 static u8 * format_policer_type (u8 * s, va_list * va)
120 {
122  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
123 
125  s = format (s, "1r2c");
126 
128  s = format (s, "1r3c");
129 
131  s = format (s, "2r3c-2698");
132 
134  s = format (s, "2r3c-4115");
135 
137  s = format (s, "2r3c-mef5cf1");
138  else
139  s = format (s, "ILLEGAL");
140  return s;
141 }
142 
143 u8 * format_policer_config (u8 * s, va_list * va)
144 {
146  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
147 
148  s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
150  c->rb.kbps.cir_kbps,
151  c->rb.kbps.eir_kbps,
152  c->rb.kbps.cb_bytes,
153  c->rb.kbps.eb_bytes);
154  s = format (s, "rate type %U, round type %U\n",
157  return s;
158 }
159 
160 static uword
162 {
164  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
165 
166  if (!unformat (input, "type"))
167  return 0;
168 
169  if (unformat (input, "1r2c"))
171  else if (unformat (input, "1r3c"))
173  else if (unformat (input, "2r3c-2698"))
175  else if (unformat (input, "2r3c-4115"))
177  else if (unformat (input, "2r3c-mef5cf1"))
179  else
180  return 0;
181  return 1;
182 }
183 
184 static uword
186 {
188  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
189 
190  if (!unformat(input, "round"))
191  return 0;
192 
193  if (unformat(input, "closest"))
195  else if (unformat (input, "up"))
197  else if (unformat (input, "down"))
199  else
200  return 0;
201  return 1;
202 }
203 
204 static uword
206 {
208  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
209 
210  if (!unformat(input, "rate"))
211  return 0;
212 
213  if (unformat (input, "kbps"))
215  else if (unformat(input, "pps"))
217  else
218  return 0;
219  return 1;
220 }
221 
222 static uword
223 unformat_policer_cir (unformat_input_t * input, va_list * va)
224 {
226  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
227 
228  if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
229  return 1;
230  return 0;
231 }
232 
233 static uword
234 unformat_policer_eir (unformat_input_t * input, va_list * va)
235 {
237  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
238 
239  if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
240  return 1;
241  return 0;
242 }
243 
244 static uword
245 unformat_policer_cb (unformat_input_t * input, va_list * va)
246 {
248  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
249 
250  if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
251  return 1;
252  return 0;
253 }
254 
255 static uword
256 unformat_policer_eb (unformat_input_t * input, va_list * va)
257 {
259  = va_arg (*va, sse2_qos_pol_cfg_params_st *);
260 
261  if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
262  return 1;
263  return 0;
264 }
265 
266 
267 #define foreach_config_param \
268 _(eb) \
269 _(cb) \
270 _(eir) \
271 _(cir) \
272 _(rate_type) \
273 _(round_type) \
274 _(type)
275 
276 static clib_error_t *
278  unformat_input_t * input,
279  vlib_cli_command_t * cmd)
280 {
282  unformat_input_t _line_input, * line_input = &_line_input;
283  u8 is_add = 1;
284  u8 * name = 0;
285 
286  /* Get a line of input. */
287  if (! unformat_user (input, unformat_line_input, line_input))
288  return 0;
289 
290  memset (&c, 0, sizeof (c));
291 
292  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
293  {
294  if (unformat (line_input, "del"))
295  is_add = 0;
296  else if (unformat(line_input, "name %s", &name))
297  ;
298 
299 #define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
301 #undef _
302 
303  else
304  return clib_error_return (0, "unknown input `%U'",
305  format_unformat_error, line_input);
306  }
307 
308  unformat_free (line_input);
309 
310  return policer_add_del(vm, name, &c, is_add);
311 }
312 
313 VLIB_CLI_COMMAND (configure_policer_command, static) = {
314  .path = "configure policer",
315  .short_help = "configure policer name <name> <params> ",
316  .function = configure_policer_command_fn,
317 };
318 
319 
320 static clib_error_t *
322  unformat_input_t * input,
323  vlib_cli_command_t * cmd)
324 {
326  hash_pair_t * p;
327  u32 pool_index;
328  u8 * match_name = 0;
329  u8 * name;
332 
333  (void) unformat (input, "name %s", &match_name);
334 
336  ({
337  name = (u8 *) p->key;
338  if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
339  {
340  pool_index = p->value[0];
341  config = pool_elt_at_index (pm->configs, pool_index);
342  templ = pool_elt_at_index (pm->policer_templates, pool_index);
343  vlib_cli_output (vm, "Name \"%s\" %U ",
344  name, format_policer_config, config);
345  vlib_cli_output (vm, "Template %U",
346  format_policer_instance, templ);
347  vlib_cli_output (vm, "-----------");
348  }
349  }));
350  return 0;
351 }
352 
353 
354 VLIB_CLI_COMMAND (show_policer_command, static) = {
355  .path = "show policer",
356  .short_help = "show policer [name]",
357  .function = show_policer_command_fn,
358 };
359 
361 {
364 
366 
367  pm->vlib_main = vm;
368  pm->vnet_main = vnet_get_main();
369 
370  pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
371  return 0;
372 }
373 
375 
376 
static uword unformat_policer_eir(unformat_input_t *input, va_list *va)
Definition: policer.c:234
sse2_qos_pol_cfg_params_st * configs
Definition: policer.h:29
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
#define foreach_config_param
Definition: policer.c:267
static void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
uword * policer_config_by_name
Definition: policer.h:33
always_inline void unformat_free(unformat_input_t *i)
Definition: format.h:160
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
#define hash_set_mem(h, key, value)
Definition: hash.h:257
trans_layer_rc sse2_pol_logical_2_physical(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *phys)
Definition: xlate.c:1089
static uword unformat_policer_rate_type(unformat_input_t *input, va_list *va)
Definition: policer.c:205
vnet_main_t * vnet_main
Definition: policer.h:40
union sse2_qos_pol_cfg_params_st_::@153 rb
static uword unformat_policer_type(unformat_input_t *input, va_list *va)
Definition: policer.c:161
u8 * format_policer_instance(u8 *s, va_list *va)
Definition: policer.c:68
#define pool_get(P, E)
Definition: pool.h:186
static u8 * format_policer_round_type(u8 *s, va_list *va)
Definition: policer.c:88
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
clib_error_t * policer_add_del(vlib_main_t *vm, u8 *name, sse2_qos_pol_cfg_params_st *cfg, u8 is_add)
Definition: policer.c:19
static clib_error_t * show_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:321
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
static u8 * format_policer_rate_type(u8 *s, va_list *va)
Definition: policer.c:105
static uword unformat_policer_round_type(unformat_input_t *input, va_list *va)
Definition: policer.c:185
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
static uword unformat_policer_cir(unformat_input_t *input, va_list *va)
Definition: policer.c:223
#define hash_create_string(elts, value_bytes)
Definition: hash.h:609
#define hash_unset_mem(h, key)
Definition: hash.h:263
clib_error_t * policer_init(vlib_main_t *vm)
Definition: policer.c:360
struct sse2_qos_pol_cfg_params_st_::@153::@154 kbps
void vnet_policer_node_funcs_reference(void)
Definition: node_funcs.c:301
vlib_main_t * vlib_main
Definition: policer.h:39
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
static clib_error_t * configure_policer_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: policer.c:277
#define clib_memcpy(a, b, c)
Definition: string.h:63
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
uint32_t cir_tokens_per_period
Definition: police.h:72
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
static u8 * format_policer_type(u8 *s, va_list *va)
Definition: policer.c:119
u64 uword
Definition: types.h:112
u8 * format_policer_config(u8 *s, va_list *va)
Definition: policer.c:143
unsigned char u8
Definition: types.h:56
#define hash_foreach_pair(p, v, body)
Definition: hash.h:311
#define hash_get_mem(h, key)
Definition: hash.h:251
static uword unformat_policer_cb(unformat_input_t *input, va_list *va)
Definition: policer.c:245
policer_read_response_type_st * policer_templates
Definition: policer.h:30
#define clib_error_return(e, args...)
Definition: error.h:112
struct _unformat_input_t unformat_input_t
uint32_t pir_tokens_per_period
Definition: police.h:73
unformat_function_t unformat_line_input
Definition: format.h:279
vnet_policer_main_t vnet_policer_main
Definition: policer.h:43
static uword unformat_policer_eb(unformat_input_t *input, va_list *va)
Definition: policer.c:256