blob: 80fa1e6f68da7d68337935faeb7c35929c702842 [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>
Brian Russell97de8a22021-01-19 16:50:56 +000017#include <vnet/policer/police_inlines.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070018#include <vnet/classify/vnet_classify.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070019
Dave Wallace71612d62017-10-24 01:32:41 -040020vnet_policer_main_t vnet_policer_main;
21
Brian Russell97de8a22021-01-19 16:50:56 +000022u8 *
23format_policer_handoff_trace (u8 *s, va_list *args)
24{
25 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
26 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
27 policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *);
28
29 s = format (s, "policer %d, handoff thread %d to %d", t->policer_index,
30 t->current_worker_index, t->next_worker_index);
31
32 return s;
33}
34
Matus Fabian65fcd4d2016-05-13 05:44:48 -070035clib_error_t *
Damjan Marion3891cd82016-10-27 10:27:00 +020036policer_add_del (vlib_main_t * vm,
37 u8 * name,
38 sse2_qos_pol_cfg_params_st * cfg,
39 u32 * policer_index, u8 is_add)
Matus Fabian65fcd4d2016-05-13 05:44:48 -070040{
41 vnet_policer_main_t *pm = &vnet_policer_main;
42 policer_read_response_type_st test_policer;
Damjan Marion3891cd82016-10-27 10:27:00 +020043 policer_read_response_type_st *policer;
44 uword *p;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070045 u32 pi;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070046 int rv;
47
Matus Fabian70e6a8d2016-06-20 08:10:42 -070048 p = hash_get_mem (pm->policer_config_by_name, name);
49
Matus Fabian65fcd4d2016-05-13 05:44:48 -070050 if (is_add == 0)
51 {
Chaoyu Jin913b8732017-08-08 13:36:23 -070052 /* free policer config and template */
Matus Fabian65fcd4d2016-05-13 05:44:48 -070053 if (p == 0)
Damjan Marion3891cd82016-10-27 10:27:00 +020054 {
55 vec_free (name);
56 return clib_error_return (0, "No such policer configuration");
57 }
Chaoyu Jin913b8732017-08-08 13:36:23 -070058 pool_put_index (pm->configs, p[0]);
59 pool_put_index (pm->policer_templates, p[0]);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070060 hash_unset_mem (pm->policer_config_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070061
62 /* free policer */
63 p = hash_get_mem (pm->policer_index_by_name, name);
64 if (p == 0)
65 {
66 vec_free (name);
67 return clib_error_return (0, "No such policer");
68 }
69 pool_put_index (pm->policers, p[0]);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070070 hash_unset_mem (pm->policer_index_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070071
Damjan Marion3891cd82016-10-27 10:27:00 +020072 vec_free (name);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070073 return 0;
74 }
75
Matus Fabian70e6a8d2016-06-20 08:10:42 -070076 if (p != 0)
77 {
Damjan Marion3891cd82016-10-27 10:27:00 +020078 vec_free (name);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070079 return clib_error_return (0, "Policer already exists");
80 }
81
Matus Fabian65fcd4d2016-05-13 05:44:48 -070082 /* Vet the configuration before adding it to the table */
83 rv = sse2_pol_logical_2_physical (cfg, &test_policer);
84
85 if (rv == 0)
86 {
87 policer_read_response_type_st *pp;
88 sse2_qos_pol_cfg_params_st *cp;
89
90 pool_get (pm->configs, cp);
91 pool_get (pm->policer_templates, pp);
92
93 ASSERT (cp - pm->configs == pp - pm->policer_templates);
94
95 clib_memcpy (cp, cfg, sizeof (*cp));
96 clib_memcpy (pp, &test_policer, sizeof (*pp));
97
98 hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070099 pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES);
100 policer[0] = pp[0];
101 pi = policer - pm->policers;
102 hash_set_mem (pm->policer_index_by_name, name, pi);
103 *policer_index = pi;
Brian Russell89cd7442021-01-19 16:46:08 +0000104 policer->thread_index = ~0;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700105 }
106 else
107 {
108 vec_free (name);
109 return clib_error_return (0, "Config failed sanity check");
110 }
111
112 return 0;
113}
114
Damjan Marion3891cd82016-10-27 10:27:00 +0200115u8 *
116format_policer_instance (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700117{
Damjan Marion3891cd82016-10-27 10:27:00 +0200118 policer_read_response_type_st *i
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119 = va_arg (*va, policer_read_response_type_st *);
120
Damjan Marion3891cd82016-10-27 10:27:00 +0200121 s = format (s, "policer at %llx: %s rate, %s color-aware\n",
122 i, i->single_rate ? "single" : "dual",
123 i->color_aware ? "is" : "not");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124 s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200125 i->cir_tokens_per_period, i->pir_tokens_per_period, i->scale);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700126 s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200127 i->current_limit,
128 i->current_bucket, i->extended_limit, i->extended_bucket);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700129 s = format (s, "last update %llu\n", i->last_update_time);
130 return s;
Damjan Marion3891cd82016-10-27 10:27:00 +0200131}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700132
Damjan Marion3891cd82016-10-27 10:27:00 +0200133static u8 *
134format_policer_round_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->rnd_type == SSE2_QOS_ROUND_TO_CLOSEST)
Damjan Marion3891cd82016-10-27 10:27:00 +0200139 s = format (s, "closest");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140 else if (c->rnd_type == SSE2_QOS_ROUND_TO_UP)
141 s = format (s, "up");
142 else if (c->rnd_type == SSE2_QOS_ROUND_TO_DOWN)
143 s = format (s, "down");
144 else
145 s = format (s, "ILLEGAL");
146 return s;
147}
148
149
Damjan Marion3891cd82016-10-27 10:27:00 +0200150static u8 *
151format_policer_rate_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700152{
Damjan Marion3891cd82016-10-27 10:27:00 +0200153 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700154
155 if (c->rate_type == SSE2_QOS_RATE_KBPS)
156 s = format (s, "kbps");
157 else if (c->rate_type == SSE2_QOS_RATE_PPS)
Damjan Marion3891cd82016-10-27 10:27:00 +0200158 s = format (s, "pps");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159 else
160 s = format (s, "ILLEGAL");
161 return s;
162}
163
Damjan Marion3891cd82016-10-27 10:27:00 +0200164static u8 *
165format_policer_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166{
Damjan Marion3891cd82016-10-27 10:27:00 +0200167 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
168
Ed Warnickecb9cada2015-12-08 15:45:58 -0700169 if (c->rfc == SSE2_QOS_POLICER_TYPE_1R2C)
170 s = format (s, "1r2c");
Damjan Marion3891cd82016-10-27 10:27:00 +0200171
Ed Warnickecb9cada2015-12-08 15:45:58 -0700172 else if (c->rfc == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
173 s = format (s, "1r3c");
174
175 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
176 s = format (s, "2r3c-2698");
177
178 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
179 s = format (s, "2r3c-4115");
180
181 else if (c->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
182 s = format (s, "2r3c-mef5cf1");
183 else
184 s = format (s, "ILLEGAL");
185 return s;
186}
187
Damjan Marion3891cd82016-10-27 10:27:00 +0200188static u8 *
189format_dscp (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700190{
191 u32 i = va_arg (*va, u32);
Damjan Marion3891cd82016-10-27 10:27:00 +0200192 char *t = 0;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700193
Damjan Marion3891cd82016-10-27 10:27:00 +0200194 switch (i)
195 {
196#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
197 foreach_vnet_dscp
198#undef _
Matus Fabian4ac74c92016-05-31 07:33:29 -0700199 default:
200 return format (s, "ILLEGAL");
Damjan Marion3891cd82016-10-27 10:27:00 +0200201 }
Matus Fabian4ac74c92016-05-31 07:33:29 -0700202 s = format (s, "%s", t);
203 return s;
204}
205
Damjan Marion3891cd82016-10-27 10:27:00 +0200206static u8 *
207format_policer_action_type (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700208{
Damjan Marion3891cd82016-10-27 10:27:00 +0200209 sse2_qos_pol_action_params_st *a
Matus Fabian4ac74c92016-05-31 07:33:29 -0700210 = va_arg (*va, sse2_qos_pol_action_params_st *);
211
212 if (a->action_type == SSE2_QOS_ACTION_DROP)
213 s = format (s, "drop");
214 else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT)
215 s = format (s, "transmit");
216 else if (a->action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
217 s = format (s, "mark-and-transmit %U", format_dscp, a->dscp);
218 else
219 s = format (s, "ILLEGAL");
220 return s;
221}
222
Damjan Marion3891cd82016-10-27 10:27:00 +0200223u8 *
224format_policer_config (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700225{
Damjan Marion3891cd82016-10-27 10:27:00 +0200226 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227
228 s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200229 format_policer_type, c,
230 c->rb.kbps.cir_kbps,
231 c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700232 s = format (s, "rate type %U, round type %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200233 format_policer_rate_type, c, format_policer_round_type, c);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700234 s = format (s, "conform action %U, exceed action %U, violate action %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200235 format_policer_action_type, &c->conform_action,
236 format_policer_action_type, &c->exceed_action,
237 format_policer_action_type, &c->violate_action);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700238 return s;
239}
240
241static uword
242unformat_policer_type (unformat_input_t * input, va_list * va)
243{
Damjan Marion3891cd82016-10-27 10:27:00 +0200244 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700245
246 if (!unformat (input, "type"))
247 return 0;
248
249 if (unformat (input, "1r2c"))
250 c->rfc = SSE2_QOS_POLICER_TYPE_1R2C;
251 else if (unformat (input, "1r3c"))
252 c->rfc = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
253 else if (unformat (input, "2r3c-2698"))
254 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
255 else if (unformat (input, "2r3c-4115"))
256 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
257 else if (unformat (input, "2r3c-mef5cf1"))
258 c->rfc = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
259 else
260 return 0;
261 return 1;
262}
263
264static uword
265unformat_policer_round_type (unformat_input_t * input, va_list * va)
266{
Damjan Marion3891cd82016-10-27 10:27:00 +0200267 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700268
Damjan Marion3891cd82016-10-27 10:27:00 +0200269 if (!unformat (input, "round"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270 return 0;
271
Damjan Marion3891cd82016-10-27 10:27:00 +0200272 if (unformat (input, "closest"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273 c->rnd_type = SSE2_QOS_ROUND_TO_CLOSEST;
274 else if (unformat (input, "up"))
275 c->rnd_type = SSE2_QOS_ROUND_TO_UP;
276 else if (unformat (input, "down"))
277 c->rnd_type = SSE2_QOS_ROUND_TO_DOWN;
278 else
279 return 0;
280 return 1;
281}
282
283static uword
284unformat_policer_rate_type (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
Damjan Marion3891cd82016-10-27 10:27:00 +0200288 if (!unformat (input, "rate"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700289 return 0;
290
291 if (unformat (input, "kbps"))
292 c->rate_type = SSE2_QOS_RATE_KBPS;
Damjan Marion3891cd82016-10-27 10:27:00 +0200293 else if (unformat (input, "pps"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294 c->rate_type = SSE2_QOS_RATE_PPS;
295 else
296 return 0;
297 return 1;
298}
299
300static uword
301unformat_policer_cir (unformat_input_t * input, va_list * va)
302{
Damjan Marion3891cd82016-10-27 10:27:00 +0200303 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700304
305 if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
306 return 1;
307 return 0;
308}
309
310static uword
311unformat_policer_eir (unformat_input_t * input, va_list * va)
312{
Damjan Marion3891cd82016-10-27 10:27:00 +0200313 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700314
315 if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
316 return 1;
317 return 0;
318}
319
320static uword
321unformat_policer_cb (unformat_input_t * input, va_list * va)
322{
Damjan Marion3891cd82016-10-27 10:27:00 +0200323 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700324
325 if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
326 return 1;
327 return 0;
328}
329
330static uword
331unformat_policer_eb (unformat_input_t * input, va_list * va)
332{
Damjan Marion3891cd82016-10-27 10:27:00 +0200333 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700334
335 if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
336 return 1;
337 return 0;
338}
339
Matus Fabian4ac74c92016-05-31 07:33:29 -0700340static uword
341unformat_dscp (unformat_input_t * input, va_list * va)
342{
Damjan Marion3891cd82016-10-27 10:27:00 +0200343 u8 *r = va_arg (*va, u8 *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700344
Damjan Marion3891cd82016-10-27 10:27:00 +0200345 if (0);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700346#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
Damjan Marion3891cd82016-10-27 10:27:00 +0200347 foreach_vnet_dscp
Matus Fabian4ac74c92016-05-31 07:33:29 -0700348#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200349 else
Matus Fabian4ac74c92016-05-31 07:33:29 -0700350 return 0;
351 return 1;
352}
353
354static uword
355unformat_policer_action_type (unformat_input_t * input, va_list * va)
356{
Damjan Marion3891cd82016-10-27 10:27:00 +0200357 sse2_qos_pol_action_params_st *a
Matus Fabian4ac74c92016-05-31 07:33:29 -0700358 = va_arg (*va, sse2_qos_pol_action_params_st *);
359
360 if (unformat (input, "drop"))
361 a->action_type = SSE2_QOS_ACTION_DROP;
362 else if (unformat (input, "transmit"))
363 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
364 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
365 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
366 else
367 return 0;
368 return 1;
369}
370
371static uword
372unformat_policer_action (unformat_input_t * input, va_list * va)
373{
Damjan Marion3891cd82016-10-27 10:27:00 +0200374 sse2_qos_pol_cfg_params_st *c = va_arg (*va, sse2_qos_pol_cfg_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700375
376 if (unformat (input, "conform-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200377 &c->conform_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700378 return 1;
379 else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200380 &c->exceed_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700381 return 1;
382 else if (unformat (input, "violate-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200383 &c->violate_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700384 return 1;
385 return 0;
386}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700387
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700388static uword
389unformat_policer_classify_next_index (unformat_input_t * input, va_list * va)
390{
Damjan Marion3891cd82016-10-27 10:27:00 +0200391 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700392 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200393 uword *p;
394 u8 *match_name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700395
396 if (unformat (input, "%s", &match_name))
397 ;
398 else
399 return 0;
400
401 p = hash_get_mem (pm->policer_index_by_name, match_name);
402
403 if (p == 0)
404 return 0;
405
406 *r = p[0];
407
408 return 1;
409}
410
411static uword
412unformat_policer_classify_precolor (unformat_input_t * input, va_list * va)
413{
Damjan Marion3891cd82016-10-27 10:27:00 +0200414 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700415
416 if (unformat (input, "conform-color"))
417 *r = POLICE_CONFORM;
418 else if (unformat (input, "exceed-color"))
419 *r = POLICE_EXCEED;
420 else
421 return 0;
422
423 return 1;
424}
425
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426#define foreach_config_param \
427_(eb) \
428_(cb) \
429_(eir) \
430_(cir) \
431_(rate_type) \
432_(round_type) \
Matus Fabian4ac74c92016-05-31 07:33:29 -0700433_(type) \
434_(action)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700435
436static clib_error_t *
437configure_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200438 unformat_input_t * input,
439 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700440{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700441 sse2_qos_pol_cfg_params_st c;
Damjan Marion3891cd82016-10-27 10:27:00 +0200442 unformat_input_t _line_input, *line_input = &_line_input;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700443 u8 is_add = 1;
Damjan Marion3891cd82016-10-27 10:27:00 +0200444 u8 *name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700445 u32 pi;
Billy McFalla9a20e72017-02-15 11:39:12 -0500446 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700447
448 /* Get a line of input. */
Damjan Marion3891cd82016-10-27 10:27:00 +0200449 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700450 return 0;
451
Dave Barachb7b92992018-10-17 10:38:51 -0400452 clib_memset (&c, 0, sizeof (c));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700453
Damjan Marion3891cd82016-10-27 10:27:00 +0200454 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700455 {
456 if (unformat (line_input, "del"))
Damjan Marion3891cd82016-10-27 10:27:00 +0200457 is_add = 0;
458 else if (unformat (line_input, "name %s", &name))
459 ;
460 else if (unformat (line_input, "color-aware"))
461 c.color_aware = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700462
463#define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
464 foreach_config_param
465#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200466 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500467 {
468 error = clib_error_return (0, "unknown input `%U'",
469 format_unformat_error, line_input);
470 goto done;
471 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472 }
473
Billy McFalla9a20e72017-02-15 11:39:12 -0500474 error = policer_add_del (vm, name, &c, &pi, is_add);
475
476done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700477 unformat_free (line_input);
478
Billy McFalla9a20e72017-02-15 11:39:12 -0500479 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700480}
481
Damjan Marion3891cd82016-10-27 10:27:00 +0200482/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700483VLIB_CLI_COMMAND (configure_policer_command, static) = {
484 .path = "configure policer",
485 .short_help = "configure policer name <name> <params> ",
486 .function = configure_policer_command_fn,
487};
Damjan Marion3891cd82016-10-27 10:27:00 +0200488/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700489
490static clib_error_t *
491show_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200492 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700493{
494 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200495 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700496 u32 pool_index;
Damjan Marion3891cd82016-10-27 10:27:00 +0200497 u8 *match_name = 0;
498 u8 *name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700499 sse2_qos_pol_cfg_params_st *config;
500 policer_read_response_type_st *templ;
501
502 (void) unformat (input, "name %s", &match_name);
503
Damjan Marion3891cd82016-10-27 10:27:00 +0200504 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700505 hash_foreach_pair (p, pm->policer_config_by_name,
506 ({
507 name = (u8 *) p->key;
508 if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
509 {
510 pool_index = p->value[0];
511 config = pool_elt_at_index (pm->configs, pool_index);
512 templ = pool_elt_at_index (pm->policer_templates, pool_index);
Damjan Marion3891cd82016-10-27 10:27:00 +0200513 vlib_cli_output (vm, "Name \"%s\" %U ",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700514 name, format_policer_config, config);
Damjan Marion3891cd82016-10-27 10:27:00 +0200515 vlib_cli_output (vm, "Template %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700516 format_policer_instance, templ);
517 vlib_cli_output (vm, "-----------");
518 }
519 }));
Damjan Marion3891cd82016-10-27 10:27:00 +0200520 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700521 return 0;
522}
523
524
Damjan Marion3891cd82016-10-27 10:27:00 +0200525/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700526VLIB_CLI_COMMAND (show_policer_command, static) = {
527 .path = "show policer",
528 .short_help = "show policer [name]",
529 .function = show_policer_command_fn,
530};
Damjan Marion3891cd82016-10-27 10:27:00 +0200531/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700532
Chaoyu Jin913b8732017-08-08 13:36:23 -0700533static clib_error_t *
534show_policer_pools_command_fn (vlib_main_t * vm,
535 unformat_input_t * input,
536 vlib_cli_command_t * cmd)
537{
538 vnet_policer_main_t *pm = &vnet_policer_main;
539
540 vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
541 pool_elts (pm->configs),
542 pool_elts (pm->policer_templates),
543 pool_elts (pm->policers));
544 return 0;
545}
546/* *INDENT-OFF* */
547VLIB_CLI_COMMAND (show_policer_pools_command, static) = {
548 .path = "show policer pools",
549 .short_help = "show policer pools",
550 .function = show_policer_pools_command_fn,
551};
552/* *INDENT-ON* */
553
Damjan Marion3891cd82016-10-27 10:27:00 +0200554clib_error_t *
555policer_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700556{
Damjan Marion3891cd82016-10-27 10:27:00 +0200557 vnet_policer_main_t *pm = &vnet_policer_main;
558 void vnet_policer_node_funcs_reference (void);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700559
Damjan Marion3891cd82016-10-27 10:27:00 +0200560 vnet_policer_node_funcs_reference ();
561
Ed Warnickecb9cada2015-12-08 15:45:58 -0700562 pm->vlib_main = vm;
Damjan Marion3891cd82016-10-27 10:27:00 +0200563 pm->vnet_main = vnet_get_main ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700564
565 pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700566 pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
567
568 vnet_classify_register_unformat_policer_next_index_fn
569 (unformat_policer_classify_next_index);
570 vnet_classify_register_unformat_opaque_index_fn
571 (unformat_policer_classify_precolor);
572
Ed Warnickecb9cada2015-12-08 15:45:58 -0700573 return 0;
574}
575
Damjan Marion3891cd82016-10-27 10:27:00 +0200576VLIB_INIT_FUNCTION (policer_init);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700577
578
Damjan Marion3891cd82016-10-27 10:27:00 +0200579
580/*
581 * fd.io coding-style-patch-verification: ON
582 *
583 * Local Variables:
584 * eval: (c-set-style "gnu")
585 * End:
586 */