blob: 5a7b7711661d2606160180ba46738e3f7f25ec9e [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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 */
Damjan Marione936bbe2016-02-25 23:17:38 +010015#include <stdint.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070016#include <vnet/policer/policer.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070017#include <vnet/classify/vnet_classify.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070018
Matus Fabian65fcd4d2016-05-13 05:44:48 -070019clib_error_t *
Damjan Marion3891cd82016-10-27 10:27:00 +020020policer_add_del (vlib_main_t * vm,
21 u8 * name,
22 sse2_qos_pol_cfg_params_st * cfg,
23 u32 * policer_index, u8 is_add)
Matus Fabian65fcd4d2016-05-13 05:44:48 -070024{
25 vnet_policer_main_t *pm = &vnet_policer_main;
26 policer_read_response_type_st test_policer;
Damjan Marion3891cd82016-10-27 10:27:00 +020027 policer_read_response_type_st *policer;
28 uword *p;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070029 u32 pi;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070030 int rv;
31
Matus Fabian70e6a8d2016-06-20 08:10:42 -070032 p = hash_get_mem (pm->policer_config_by_name, name);
33
Matus Fabian65fcd4d2016-05-13 05:44:48 -070034 if (is_add == 0)
35 {
Chaoyu Jin913b8732017-08-08 13:36:23 -070036 /* free policer config and template */
Matus Fabian65fcd4d2016-05-13 05:44:48 -070037 if (p == 0)
Damjan Marion3891cd82016-10-27 10:27:00 +020038 {
39 vec_free (name);
40 return clib_error_return (0, "No such policer configuration");
41 }
Chaoyu Jin913b8732017-08-08 13:36:23 -070042 pool_put_index (pm->configs, p[0]);
43 pool_put_index (pm->policer_templates, p[0]);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070044 hash_unset_mem (pm->policer_config_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070045
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]);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070054 hash_unset_mem (pm->policer_index_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070055
Damjan Marion3891cd82016-10-27 10:27:00 +020056 vec_free (name);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070057 return 0;
58 }
59
Matus Fabian70e6a8d2016-06-20 08:10:42 -070060 if (p != 0)
61 {
Damjan Marion3891cd82016-10-27 10:27:00 +020062 vec_free (name);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070063 return clib_error_return (0, "Policer already exists");
64 }
65
Matus Fabian65fcd4d2016-05-13 05:44:48 -070066 /* 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 {
71 policer_read_response_type_st *pp;
72 sse2_qos_pol_cfg_params_st *cp;
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);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070083 pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES);
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;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070088 }
89 else
90 {
91 vec_free (name);
92 return clib_error_return (0, "Config failed sanity check");
93 }
94
95 return 0;
96}
97
Damjan Marion3891cd82016-10-27 10:27:00 +020098u8 *
99format_policer_instance (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700100{
Damjan Marion3891cd82016-10-27 10:27:00 +0200101 policer_read_response_type_st *i
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 = va_arg (*va, policer_read_response_type_st *);
103
Damjan Marion3891cd82016-10-27 10:27:00 +0200104 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");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700107 s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200108 i->cir_tokens_per_period, i->pir_tokens_per_period, i->scale);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700109 s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200110 i->current_limit,
111 i->current_bucket, i->extended_limit, i->extended_bucket);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700112 s = format (s, "last update %llu\n", i->last_update_time);
113 return s;
Damjan Marion3891cd82016-10-27 10:27:00 +0200114}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115
Damjan Marion3891cd82016-10-27 10:27:00 +0200116static u8 *
117format_policer_round_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700118{
Damjan Marion3891cd82016-10-27 10:27:00 +0200119 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120
121 if (c->rnd_type == SSE2_QOS_ROUND_TO_CLOSEST)
Damjan Marion3891cd82016-10-27 10:27:00 +0200122 s = format (s, "closest");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123 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
Damjan Marion3891cd82016-10-27 10:27:00 +0200133static u8 *
134format_policer_rate_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135{
Damjan Marion3891cd82016-10-27 10:27:00 +0200136 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700137
138 if (c->rate_type == SSE2_QOS_RATE_KBPS)
139 s = format (s, "kbps");
140 else if (c->rate_type == SSE2_QOS_RATE_PPS)
Damjan Marion3891cd82016-10-27 10:27:00 +0200141 s = format (s, "pps");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700142 else
143 s = format (s, "ILLEGAL");
144 return s;
145}
146
Damjan Marion3891cd82016-10-27 10:27:00 +0200147static u8 *
148format_policer_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149{
Damjan Marion3891cd82016-10-27 10:27:00 +0200150 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
151
Ed Warnickecb9cada2015-12-08 15:45:58 -0700152 if (c->rfc == SSE2_QOS_POLICER_TYPE_1R2C)
153 s = format (s, "1r2c");
Damjan Marion3891cd82016-10-27 10:27:00 +0200154
Ed Warnickecb9cada2015-12-08 15:45:58 -0700155 else if (c->rfc == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
156 s = format (s, "1r3c");
157
158 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
159 s = format (s, "2r3c-2698");
160
161 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
162 s = format (s, "2r3c-4115");
163
164 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
165 s = format (s, "2r3c-mef5cf1");
166 else
167 s = format (s, "ILLEGAL");
168 return s;
169}
170
Damjan Marion3891cd82016-10-27 10:27:00 +0200171static u8 *
172format_dscp (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700173{
174 u32 i = va_arg (*va, u32);
Damjan Marion3891cd82016-10-27 10:27:00 +0200175 char *t = 0;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700176
Damjan Marion3891cd82016-10-27 10:27:00 +0200177 switch (i)
178 {
179#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
180 foreach_vnet_dscp
181#undef _
Matus Fabian4ac74c92016-05-31 07:33:29 -0700182 default:
183 return format (s, "ILLEGAL");
Damjan Marion3891cd82016-10-27 10:27:00 +0200184 }
Matus Fabian4ac74c92016-05-31 07:33:29 -0700185 s = format (s, "%s", t);
186 return s;
187}
188
Damjan Marion3891cd82016-10-27 10:27:00 +0200189static u8 *
190format_policer_action_type (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700191{
Damjan Marion3891cd82016-10-27 10:27:00 +0200192 sse2_qos_pol_action_params_st *a
Matus Fabian4ac74c92016-05-31 07:33:29 -0700193 = va_arg (*va, sse2_qos_pol_action_params_st *);
194
195 if (a->action_type == SSE2_QOS_ACTION_DROP)
196 s = format (s, "drop");
197 else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT)
198 s = format (s, "transmit");
199 else if (a->action_type == SSE2_QOS_ACTION_MARK_AND_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
Damjan Marion3891cd82016-10-27 10:27:00 +0200206u8 *
207format_policer_config (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208{
Damjan Marion3891cd82016-10-27 10:27:00 +0200209 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210
211 s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200212 format_policer_type, c,
213 c->rb.kbps.cir_kbps,
214 c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700215 s = format (s, "rate type %U, round type %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200216 format_policer_rate_type, c, format_policer_round_type, c);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700217 s = format (s, "conform action %U, exceed action %U, violate action %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200218 format_policer_action_type, &c->conform_action,
219 format_policer_action_type, &c->exceed_action,
220 format_policer_action_type, &c->violate_action);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700221 return s;
222}
223
224static uword
225unformat_policer_type (unformat_input_t * input, va_list * va)
226{
Damjan Marion3891cd82016-10-27 10:27:00 +0200227 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700228
229 if (!unformat (input, "type"))
230 return 0;
231
232 if (unformat (input, "1r2c"))
233 c->rfc = SSE2_QOS_POLICER_TYPE_1R2C;
234 else if (unformat (input, "1r3c"))
235 c->rfc = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
236 else if (unformat (input, "2r3c-2698"))
237 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
238 else if (unformat (input, "2r3c-4115"))
239 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
240 else if (unformat (input, "2r3c-mef5cf1"))
241 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
242 else
243 return 0;
244 return 1;
245}
246
247static uword
248unformat_policer_round_type (unformat_input_t * input, va_list * va)
249{
Damjan Marion3891cd82016-10-27 10:27:00 +0200250 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251
Damjan Marion3891cd82016-10-27 10:27:00 +0200252 if (!unformat (input, "round"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700253 return 0;
254
Damjan Marion3891cd82016-10-27 10:27:00 +0200255 if (unformat (input, "closest"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700256 c->rnd_type = SSE2_QOS_ROUND_TO_CLOSEST;
257 else if (unformat (input, "up"))
258 c->rnd_type = SSE2_QOS_ROUND_TO_UP;
259 else if (unformat (input, "down"))
260 c->rnd_type = SSE2_QOS_ROUND_TO_DOWN;
261 else
262 return 0;
263 return 1;
264}
265
266static uword
267unformat_policer_rate_type (unformat_input_t * input, va_list * va)
268{
Damjan Marion3891cd82016-10-27 10:27:00 +0200269 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270
Damjan Marion3891cd82016-10-27 10:27:00 +0200271 if (!unformat (input, "rate"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272 return 0;
273
274 if (unformat (input, "kbps"))
275 c->rate_type = SSE2_QOS_RATE_KBPS;
Damjan Marion3891cd82016-10-27 10:27:00 +0200276 else if (unformat (input, "pps"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277 c->rate_type = SSE2_QOS_RATE_PPS;
278 else
279 return 0;
280 return 1;
281}
282
283static uword
284unformat_policer_cir (unformat_input_t * input, va_list * va)
285{
Damjan Marion3891cd82016-10-27 10:27:00 +0200286 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287
288 if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
289 return 1;
290 return 0;
291}
292
293static uword
294unformat_policer_eir (unformat_input_t * input, va_list * va)
295{
Damjan Marion3891cd82016-10-27 10:27:00 +0200296 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297
298 if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
299 return 1;
300 return 0;
301}
302
303static uword
304unformat_policer_cb (unformat_input_t * input, va_list * va)
305{
Damjan Marion3891cd82016-10-27 10:27:00 +0200306 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307
308 if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
309 return 1;
310 return 0;
311}
312
313static uword
314unformat_policer_eb (unformat_input_t * input, va_list * va)
315{
Damjan Marion3891cd82016-10-27 10:27:00 +0200316 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700317
318 if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
319 return 1;
320 return 0;
321}
322
Matus Fabian4ac74c92016-05-31 07:33:29 -0700323static uword
324unformat_dscp (unformat_input_t * input, va_list * va)
325{
Damjan Marion3891cd82016-10-27 10:27:00 +0200326 u8 *r = va_arg (*va, u8 *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700327
Damjan Marion3891cd82016-10-27 10:27:00 +0200328 if (0);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700329#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
Damjan Marion3891cd82016-10-27 10:27:00 +0200330 foreach_vnet_dscp
Matus Fabian4ac74c92016-05-31 07:33:29 -0700331#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200332 else
Matus Fabian4ac74c92016-05-31 07:33:29 -0700333 return 0;
334 return 1;
335}
336
337static uword
338unformat_policer_action_type (unformat_input_t * input, va_list * va)
339{
Damjan Marion3891cd82016-10-27 10:27:00 +0200340 sse2_qos_pol_action_params_st *a
Matus Fabian4ac74c92016-05-31 07:33:29 -0700341 = va_arg (*va, sse2_qos_pol_action_params_st *);
342
343 if (unformat (input, "drop"))
344 a->action_type = SSE2_QOS_ACTION_DROP;
345 else if (unformat (input, "transmit"))
346 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
347 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
348 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
349 else
350 return 0;
351 return 1;
352}
353
354static uword
355unformat_policer_action (unformat_input_t * input, va_list * va)
356{
Damjan Marion3891cd82016-10-27 10:27:00 +0200357 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700358
359 if (unformat (input, "conform-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200360 &c->conform_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700361 return 1;
362 else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200363 &c->exceed_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700364 return 1;
365 else if (unformat (input, "violate-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200366 &c->violate_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700367 return 1;
368 return 0;
369}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700370
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700371static uword
372unformat_policer_classify_next_index (unformat_input_t * input, va_list * va)
373{
Damjan Marion3891cd82016-10-27 10:27:00 +0200374 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700375 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200376 uword *p;
377 u8 *match_name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700378
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
394static uword
395unformat_policer_classify_precolor (unformat_input_t * input, va_list * va)
396{
Damjan Marion3891cd82016-10-27 10:27:00 +0200397 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700398
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
Ed Warnickecb9cada2015-12-08 15:45:58 -0700409#define foreach_config_param \
410_(eb) \
411_(cb) \
412_(eir) \
413_(cir) \
414_(rate_type) \
415_(round_type) \
Matus Fabian4ac74c92016-05-31 07:33:29 -0700416_(type) \
417_(action)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700418
419static clib_error_t *
420configure_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200421 unformat_input_t * input,
422 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700424 sse2_qos_pol_cfg_params_st c;
Damjan Marion3891cd82016-10-27 10:27:00 +0200425 unformat_input_t _line_input, *line_input = &_line_input;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700426 u8 is_add = 1;
Damjan Marion3891cd82016-10-27 10:27:00 +0200427 u8 *name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700428 u32 pi;
Billy McFalla9a20e72017-02-15 11:39:12 -0500429 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700430
431 /* Get a line of input. */
Damjan Marion3891cd82016-10-27 10:27:00 +0200432 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700433 return 0;
434
435 memset (&c, 0, sizeof (c));
436
Damjan Marion3891cd82016-10-27 10:27:00 +0200437 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700438 {
439 if (unformat (line_input, "del"))
Damjan Marion3891cd82016-10-27 10:27:00 +0200440 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;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700445
446#define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
447 foreach_config_param
448#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200449 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500450 {
451 error = clib_error_return (0, "unknown input `%U'",
452 format_unformat_error, line_input);
453 goto done;
454 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700455 }
456
Billy McFalla9a20e72017-02-15 11:39:12 -0500457 error = policer_add_del (vm, name, &c, &pi, is_add);
458
459done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700460 unformat_free (line_input);
461
Billy McFalla9a20e72017-02-15 11:39:12 -0500462 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700463}
464
Damjan Marion3891cd82016-10-27 10:27:00 +0200465/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700466VLIB_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};
Damjan Marion3891cd82016-10-27 10:27:00 +0200471/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472
473static clib_error_t *
474show_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200475 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700476{
477 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200478 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700479 u32 pool_index;
Damjan Marion3891cd82016-10-27 10:27:00 +0200480 u8 *match_name = 0;
481 u8 *name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700482 sse2_qos_pol_cfg_params_st *config;
483 policer_read_response_type_st *templ;
484
485 (void) unformat (input, "name %s", &match_name);
486
Damjan Marion3891cd82016-10-27 10:27:00 +0200487 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700488 hash_foreach_pair (p, pm->policer_config_by_name,
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);
Damjan Marion3891cd82016-10-27 10:27:00 +0200496 vlib_cli_output (vm, "Name \"%s\" %U ",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700497 name, format_policer_config, config);
Damjan Marion3891cd82016-10-27 10:27:00 +0200498 vlib_cli_output (vm, "Template %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700499 format_policer_instance, templ);
500 vlib_cli_output (vm, "-----------");
501 }
502 }));
Damjan Marion3891cd82016-10-27 10:27:00 +0200503 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700504 return 0;
505}
506
507
Damjan Marion3891cd82016-10-27 10:27:00 +0200508/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700509VLIB_CLI_COMMAND (show_policer_command, static) = {
510 .path = "show policer",
511 .short_help = "show policer [name]",
512 .function = show_policer_command_fn,
513};
Damjan Marion3891cd82016-10-27 10:27:00 +0200514/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700515
Chaoyu Jin913b8732017-08-08 13:36:23 -0700516static clib_error_t *
517show_policer_pools_command_fn (vlib_main_t * vm,
518 unformat_input_t * input,
519 vlib_cli_command_t * cmd)
520{
521 vnet_policer_main_t *pm = &vnet_policer_main;
522
523 vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
524 pool_elts (pm->configs),
525 pool_elts (pm->policer_templates),
526 pool_elts (pm->policers));
527 return 0;
528}
529/* *INDENT-OFF* */
530VLIB_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
Damjan Marion3891cd82016-10-27 10:27:00 +0200537clib_error_t *
538policer_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700539{
Damjan Marion3891cd82016-10-27 10:27:00 +0200540 vnet_policer_main_t *pm = &vnet_policer_main;
541 void vnet_policer_node_funcs_reference (void);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700542
Damjan Marion3891cd82016-10-27 10:27:00 +0200543 vnet_policer_node_funcs_reference ();
544
Ed Warnickecb9cada2015-12-08 15:45:58 -0700545 pm->vlib_main = vm;
Damjan Marion3891cd82016-10-27 10:27:00 +0200546 pm->vnet_main = vnet_get_main ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700547
548 pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700549 pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
550
551 vnet_classify_register_unformat_policer_next_index_fn
552 (unformat_policer_classify_next_index);
553 vnet_classify_register_unformat_opaque_index_fn
554 (unformat_policer_classify_precolor);
555
Ed Warnickecb9cada2015-12-08 15:45:58 -0700556 return 0;
557}
558
Damjan Marion3891cd82016-10-27 10:27:00 +0200559VLIB_INIT_FUNCTION (policer_init);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700560
561
Damjan Marion3891cd82016-10-27 10:27:00 +0200562
563/*
564 * fd.io coding-style-patch-verification: ON
565 *
566 * Local Variables:
567 * eval: (c-set-style "gnu")
568 * End:
569 */