blob: f6a19f40020ff0ebe6f64ab9b68217cdd5ff83ef [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>
Brian Russell48e26362021-02-10 13:53:42 +000016#include <stdbool.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070017#include <vnet/policer/policer.h>
Brian Russell97de8a22021-01-19 16:50:56 +000018#include <vnet/policer/police_inlines.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070019#include <vnet/classify/vnet_classify.h>
Brian Russelle3845d72021-02-08 15:33:18 +000020#include <vnet/ip/ip_packet.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070021
Dave Wallace71612d62017-10-24 01:32:41 -040022vnet_policer_main_t vnet_policer_main;
23
Brian Russell97de8a22021-01-19 16:50:56 +000024u8 *
25format_policer_handoff_trace (u8 *s, va_list *args)
26{
27 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
28 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
29 policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *);
30
31 s = format (s, "policer %d, handoff thread %d to %d", t->policer_index,
32 t->current_worker_index, t->next_worker_index);
33
34 return s;
35}
36
Brian Russella71ed782021-01-27 11:34:33 +000037vlib_combined_counter_main_t policer_counters[] = {
38 {
39 .name = "Policer-Conform",
40 .stat_segment_name = "/net/policer/conform",
41 },
42 {
43 .name = "Policer-Exceed",
44 .stat_segment_name = "/net/policer/exceed",
45 },
46 {
47 .name = "Policer-Violate",
48 .stat_segment_name = "/net/policer/violate",
49 },
50};
51
Matus Fabian65fcd4d2016-05-13 05:44:48 -070052clib_error_t *
Brian Russellc5299ff2021-02-09 10:16:58 +000053policer_add_del (vlib_main_t *vm, u8 *name, qos_pol_cfg_params_st *cfg,
54 u32 *policer_index, u8 is_add)
Matus Fabian65fcd4d2016-05-13 05:44:48 -070055{
56 vnet_policer_main_t *pm = &vnet_policer_main;
Brian Russell54be0cc2021-02-15 11:49:42 +000057 policer_t test_policer;
58 policer_t *policer;
Damjan Marion3891cd82016-10-27 10:27:00 +020059 uword *p;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070060 u32 pi;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070061 int rv;
62
Matus Fabian70e6a8d2016-06-20 08:10:42 -070063 p = hash_get_mem (pm->policer_config_by_name, name);
64
Matus Fabian65fcd4d2016-05-13 05:44:48 -070065 if (is_add == 0)
66 {
Chaoyu Jin913b8732017-08-08 13:36:23 -070067 /* free policer config and template */
Matus Fabian65fcd4d2016-05-13 05:44:48 -070068 if (p == 0)
Damjan Marion3891cd82016-10-27 10:27:00 +020069 {
70 vec_free (name);
71 return clib_error_return (0, "No such policer configuration");
72 }
Chaoyu Jin913b8732017-08-08 13:36:23 -070073 pool_put_index (pm->configs, p[0]);
74 pool_put_index (pm->policer_templates, p[0]);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070075 hash_unset_mem (pm->policer_config_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070076
77 /* free policer */
78 p = hash_get_mem (pm->policer_index_by_name, name);
79 if (p == 0)
80 {
81 vec_free (name);
82 return clib_error_return (0, "No such policer");
83 }
84 pool_put_index (pm->policers, p[0]);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070085 hash_unset_mem (pm->policer_index_by_name, name);
Chaoyu Jin913b8732017-08-08 13:36:23 -070086
Damjan Marion3891cd82016-10-27 10:27:00 +020087 vec_free (name);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070088 return 0;
89 }
90
Matus Fabian70e6a8d2016-06-20 08:10:42 -070091 if (p != 0)
92 {
Damjan Marion3891cd82016-10-27 10:27:00 +020093 vec_free (name);
Matus Fabian70e6a8d2016-06-20 08:10:42 -070094 return clib_error_return (0, "Policer already exists");
95 }
96
Matus Fabian65fcd4d2016-05-13 05:44:48 -070097 /* Vet the configuration before adding it to the table */
Brian Russellc5299ff2021-02-09 10:16:58 +000098 rv = pol_logical_2_physical (cfg, &test_policer);
Matus Fabian65fcd4d2016-05-13 05:44:48 -070099
100 if (rv == 0)
101 {
Brian Russell54be0cc2021-02-15 11:49:42 +0000102 policer_t *pp;
Brian Russellc5299ff2021-02-09 10:16:58 +0000103 qos_pol_cfg_params_st *cp;
Brian Russella71ed782021-01-27 11:34:33 +0000104 int i;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700105
106 pool_get (pm->configs, cp);
107 pool_get (pm->policer_templates, pp);
108
109 ASSERT (cp - pm->configs == pp - pm->policer_templates);
110
111 clib_memcpy (cp, cfg, sizeof (*cp));
112 clib_memcpy (pp, &test_policer, sizeof (*pp));
113
114 hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700115 pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES);
116 policer[0] = pp[0];
117 pi = policer - pm->policers;
118 hash_set_mem (pm->policer_index_by_name, name, pi);
119 *policer_index = pi;
Brian Russell89cd7442021-01-19 16:46:08 +0000120 policer->thread_index = ~0;
Brian Russella71ed782021-01-27 11:34:33 +0000121
122 for (i = 0; i < NUM_POLICE_RESULTS; i++)
123 {
124 vlib_validate_combined_counter (&policer_counters[i], pi);
125 vlib_zero_combined_counter (&policer_counters[i], pi);
126 }
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700127 }
128 else
129 {
130 vec_free (name);
131 return clib_error_return (0, "Config failed sanity check");
132 }
133
134 return 0;
135}
136
Brian Russell48e26362021-02-10 13:53:42 +0000137int
138policer_bind_worker (u8 *name, u32 worker, bool bind)
139{
140 vnet_policer_main_t *pm = &vnet_policer_main;
Brian Russell54be0cc2021-02-15 11:49:42 +0000141 policer_t *policer;
Brian Russell48e26362021-02-10 13:53:42 +0000142 uword *p;
143
144 p = hash_get_mem (pm->policer_index_by_name, name);
145 if (p == 0)
146 {
147 return VNET_API_ERROR_NO_SUCH_ENTRY;
148 }
149
150 policer = &pm->policers[p[0]];
151
152 if (bind)
153 {
154 if (worker >= vlib_num_workers ())
155 {
156 return VNET_API_ERROR_INVALID_WORKER;
157 }
158
159 policer->thread_index = vlib_get_worker_thread_index (worker);
160 }
161 else
162 {
163 policer->thread_index = ~0;
164 }
165 return 0;
166}
167
Damjan Marion3891cd82016-10-27 10:27:00 +0200168u8 *
169format_policer_instance (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170{
Brian Russell54be0cc2021-02-15 11:49:42 +0000171 policer_t *i = va_arg (*va, policer_t *);
Brian Russella71ed782021-01-27 11:34:33 +0000172 uword pi = va_arg (*va, uword);
173 int result;
174 vlib_counter_t counts[NUM_POLICE_RESULTS];
175
176 for (result = 0; result < NUM_POLICE_RESULTS; result++)
177 {
178 vlib_get_combined_counter (&policer_counters[result], pi,
179 &counts[result]);
180 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181
Damjan Marion3891cd82016-10-27 10:27:00 +0200182 s = format (s, "policer at %llx: %s rate, %s color-aware\n",
183 i, i->single_rate ? "single" : "dual",
184 i->color_aware ? "is" : "not");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700185 s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200186 i->cir_tokens_per_period, i->pir_tokens_per_period, i->scale);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187 s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200188 i->current_limit,
189 i->current_bucket, i->extended_limit, i->extended_bucket);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190 s = format (s, "last update %llu\n", i->last_update_time);
Brian Russella71ed782021-01-27 11:34:33 +0000191 s = format (s, "conform %llu packets, %llu bytes\n",
192 counts[POLICE_CONFORM].packets, counts[POLICE_CONFORM].bytes);
193 s = format (s, "exceed %llu packets, %llu bytes\n",
194 counts[POLICE_EXCEED].packets, counts[POLICE_EXCEED].bytes);
195 s = format (s, "violate %llu packets, %llu bytes\n",
196 counts[POLICE_VIOLATE].packets, counts[POLICE_VIOLATE].bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197 return s;
Damjan Marion3891cd82016-10-27 10:27:00 +0200198}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199
Damjan Marion3891cd82016-10-27 10:27:00 +0200200static u8 *
201format_policer_round_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700202{
Brian Russellc5299ff2021-02-09 10:16:58 +0000203 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700204
Brian Russellc5299ff2021-02-09 10:16:58 +0000205 if (c->rnd_type == QOS_ROUND_TO_CLOSEST)
Damjan Marion3891cd82016-10-27 10:27:00 +0200206 s = format (s, "closest");
Brian Russellc5299ff2021-02-09 10:16:58 +0000207 else if (c->rnd_type == QOS_ROUND_TO_UP)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208 s = format (s, "up");
Brian Russellc5299ff2021-02-09 10:16:58 +0000209 else if (c->rnd_type == QOS_ROUND_TO_DOWN)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210 s = format (s, "down");
211 else
212 s = format (s, "ILLEGAL");
213 return s;
214}
215
216
Damjan Marion3891cd82016-10-27 10:27:00 +0200217static u8 *
218format_policer_rate_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700219{
Brian Russellc5299ff2021-02-09 10:16:58 +0000220 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700221
Brian Russellc5299ff2021-02-09 10:16:58 +0000222 if (c->rate_type == QOS_RATE_KBPS)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223 s = format (s, "kbps");
Brian Russellc5299ff2021-02-09 10:16:58 +0000224 else if (c->rate_type == QOS_RATE_PPS)
Damjan Marion3891cd82016-10-27 10:27:00 +0200225 s = format (s, "pps");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700226 else
227 s = format (s, "ILLEGAL");
228 return s;
229}
230
Damjan Marion3891cd82016-10-27 10:27:00 +0200231static u8 *
232format_policer_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700233{
Brian Russellc5299ff2021-02-09 10:16:58 +0000234 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Damjan Marion3891cd82016-10-27 10:27:00 +0200235
Brian Russellc5299ff2021-02-09 10:16:58 +0000236 if (c->rfc == QOS_POLICER_TYPE_1R2C)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237 s = format (s, "1r2c");
Damjan Marion3891cd82016-10-27 10:27:00 +0200238
Brian Russellc5299ff2021-02-09 10:16:58 +0000239 else if (c->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240 s = format (s, "1r3c");
241
Brian Russellc5299ff2021-02-09 10:16:58 +0000242 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243 s = format (s, "2r3c-2698");
244
Brian Russellc5299ff2021-02-09 10:16:58 +0000245 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700246 s = format (s, "2r3c-4115");
247
Brian Russellc5299ff2021-02-09 10:16:58 +0000248 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700249 s = format (s, "2r3c-mef5cf1");
250 else
251 s = format (s, "ILLEGAL");
252 return s;
253}
254
Damjan Marion3891cd82016-10-27 10:27:00 +0200255static u8 *
Damjan Marion3891cd82016-10-27 10:27:00 +0200256format_policer_action_type (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700257{
Brian Russellc5299ff2021-02-09 10:16:58 +0000258 qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700259
Brian Russellc5299ff2021-02-09 10:16:58 +0000260 if (a->action_type == QOS_ACTION_DROP)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700261 s = format (s, "drop");
Brian Russellc5299ff2021-02-09 10:16:58 +0000262 else if (a->action_type == QOS_ACTION_TRANSMIT)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700263 s = format (s, "transmit");
Brian Russellc5299ff2021-02-09 10:16:58 +0000264 else if (a->action_type == QOS_ACTION_MARK_AND_TRANSMIT)
Brian Russelle3845d72021-02-08 15:33:18 +0000265 s = format (s, "mark-and-transmit %U", format_ip_dscp, a->dscp);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700266 else
267 s = format (s, "ILLEGAL");
268 return s;
269}
270
Damjan Marion3891cd82016-10-27 10:27:00 +0200271u8 *
272format_policer_config (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273{
Brian Russellc5299ff2021-02-09 10:16:58 +0000274 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275
276 s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200277 format_policer_type, c,
278 c->rb.kbps.cir_kbps,
279 c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700280 s = format (s, "rate type %U, round type %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200281 format_policer_rate_type, c, format_policer_round_type, c);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700282 s = format (s, "conform action %U, exceed action %U, violate action %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200283 format_policer_action_type, &c->conform_action,
284 format_policer_action_type, &c->exceed_action,
285 format_policer_action_type, &c->violate_action);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700286 return s;
287}
288
289static uword
290unformat_policer_type (unformat_input_t * input, va_list * va)
291{
Brian Russellc5299ff2021-02-09 10:16:58 +0000292 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700293
294 if (!unformat (input, "type"))
295 return 0;
296
297 if (unformat (input, "1r2c"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000298 c->rfc = QOS_POLICER_TYPE_1R2C;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700299 else if (unformat (input, "1r3c"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000300 c->rfc = QOS_POLICER_TYPE_1R3C_RFC_2697;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301 else if (unformat (input, "2r3c-2698"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000302 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_2698;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700303 else if (unformat (input, "2r3c-4115"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000304 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_4115;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700305 else if (unformat (input, "2r3c-mef5cf1"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000306 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307 else
308 return 0;
309 return 1;
310}
311
312static uword
313unformat_policer_round_type (unformat_input_t * input, va_list * va)
314{
Brian Russellc5299ff2021-02-09 10:16:58 +0000315 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700316
Damjan Marion3891cd82016-10-27 10:27:00 +0200317 if (!unformat (input, "round"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700318 return 0;
319
Damjan Marion3891cd82016-10-27 10:27:00 +0200320 if (unformat (input, "closest"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000321 c->rnd_type = QOS_ROUND_TO_CLOSEST;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700322 else if (unformat (input, "up"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000323 c->rnd_type = QOS_ROUND_TO_UP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700324 else if (unformat (input, "down"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000325 c->rnd_type = QOS_ROUND_TO_DOWN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700326 else
327 return 0;
328 return 1;
329}
330
331static uword
332unformat_policer_rate_type (unformat_input_t * input, va_list * va)
333{
Brian Russellc5299ff2021-02-09 10:16:58 +0000334 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700335
Damjan Marion3891cd82016-10-27 10:27:00 +0200336 if (!unformat (input, "rate"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337 return 0;
338
339 if (unformat (input, "kbps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000340 c->rate_type = QOS_RATE_KBPS;
Damjan Marion3891cd82016-10-27 10:27:00 +0200341 else if (unformat (input, "pps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000342 c->rate_type = QOS_RATE_PPS;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700343 else
344 return 0;
345 return 1;
346}
347
348static uword
349unformat_policer_cir (unformat_input_t * input, va_list * va)
350{
Brian Russellc5299ff2021-02-09 10:16:58 +0000351 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700352
353 if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
354 return 1;
355 return 0;
356}
357
358static uword
359unformat_policer_eir (unformat_input_t * input, va_list * va)
360{
Brian Russellc5299ff2021-02-09 10:16:58 +0000361 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700362
363 if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
364 return 1;
365 return 0;
366}
367
368static uword
369unformat_policer_cb (unformat_input_t * input, va_list * va)
370{
Brian Russellc5299ff2021-02-09 10:16:58 +0000371 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700372
373 if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
374 return 1;
375 return 0;
376}
377
378static uword
379unformat_policer_eb (unformat_input_t * input, va_list * va)
380{
Brian Russellc5299ff2021-02-09 10:16:58 +0000381 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700382
383 if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
384 return 1;
385 return 0;
386}
387
Matus Fabian4ac74c92016-05-31 07:33:29 -0700388static uword
Matus Fabian4ac74c92016-05-31 07:33:29 -0700389unformat_policer_action_type (unformat_input_t * input, va_list * va)
390{
Brian Russellc5299ff2021-02-09 10:16:58 +0000391 qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700392
393 if (unformat (input, "drop"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000394 a->action_type = QOS_ACTION_DROP;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700395 else if (unformat (input, "transmit"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000396 a->action_type = QOS_ACTION_TRANSMIT;
Brian Russelle3845d72021-02-08 15:33:18 +0000397 else if (unformat (input, "mark-and-transmit %U", unformat_ip_dscp,
398 &a->dscp))
Brian Russellc5299ff2021-02-09 10:16:58 +0000399 a->action_type = QOS_ACTION_MARK_AND_TRANSMIT;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700400 else
401 return 0;
402 return 1;
403}
404
405static uword
406unformat_policer_action (unformat_input_t * input, va_list * va)
407{
Brian Russellc5299ff2021-02-09 10:16:58 +0000408 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700409
410 if (unformat (input, "conform-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200411 &c->conform_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700412 return 1;
413 else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200414 &c->exceed_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700415 return 1;
416 else if (unformat (input, "violate-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200417 &c->violate_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700418 return 1;
419 return 0;
420}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700421
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700422static uword
423unformat_policer_classify_next_index (unformat_input_t * input, va_list * va)
424{
Damjan Marion3891cd82016-10-27 10:27:00 +0200425 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700426 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200427 uword *p;
428 u8 *match_name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700429
430 if (unformat (input, "%s", &match_name))
431 ;
432 else
433 return 0;
434
435 p = hash_get_mem (pm->policer_index_by_name, match_name);
436
437 if (p == 0)
438 return 0;
439
440 *r = p[0];
441
442 return 1;
443}
444
445static uword
446unformat_policer_classify_precolor (unformat_input_t * input, va_list * va)
447{
Damjan Marion3891cd82016-10-27 10:27:00 +0200448 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700449
450 if (unformat (input, "conform-color"))
451 *r = POLICE_CONFORM;
452 else if (unformat (input, "exceed-color"))
453 *r = POLICE_EXCEED;
454 else
455 return 0;
456
457 return 1;
458}
459
Ed Warnickecb9cada2015-12-08 15:45:58 -0700460#define foreach_config_param \
461_(eb) \
462_(cb) \
463_(eir) \
464_(cir) \
465_(rate_type) \
466_(round_type) \
Matus Fabian4ac74c92016-05-31 07:33:29 -0700467_(type) \
468_(action)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700469
470static clib_error_t *
471configure_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200472 unformat_input_t * input,
473 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474{
Brian Russellc5299ff2021-02-09 10:16:58 +0000475 qos_pol_cfg_params_st c;
Damjan Marion3891cd82016-10-27 10:27:00 +0200476 unformat_input_t _line_input, *line_input = &_line_input;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700477 u8 is_add = 1;
Damjan Marion3891cd82016-10-27 10:27:00 +0200478 u8 *name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700479 u32 pi;
Billy McFalla9a20e72017-02-15 11:39:12 -0500480 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700481
482 /* Get a line of input. */
Damjan Marion3891cd82016-10-27 10:27:00 +0200483 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700484 return 0;
485
Dave Barachb7b92992018-10-17 10:38:51 -0400486 clib_memset (&c, 0, sizeof (c));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700487
Damjan Marion3891cd82016-10-27 10:27:00 +0200488 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700489 {
490 if (unformat (line_input, "del"))
Damjan Marion3891cd82016-10-27 10:27:00 +0200491 is_add = 0;
492 else if (unformat (line_input, "name %s", &name))
493 ;
494 else if (unformat (line_input, "color-aware"))
495 c.color_aware = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700496
497#define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
498 foreach_config_param
499#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200500 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500501 {
502 error = clib_error_return (0, "unknown input `%U'",
503 format_unformat_error, line_input);
504 goto done;
505 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700506 }
507
Billy McFalla9a20e72017-02-15 11:39:12 -0500508 error = policer_add_del (vm, name, &c, &pi, is_add);
509
510done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700511 unformat_free (line_input);
512
Billy McFalla9a20e72017-02-15 11:39:12 -0500513 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700514}
515
Damjan Marion3891cd82016-10-27 10:27:00 +0200516/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700517VLIB_CLI_COMMAND (configure_policer_command, static) = {
518 .path = "configure policer",
519 .short_help = "configure policer name <name> <params> ",
520 .function = configure_policer_command_fn,
521};
Damjan Marion3891cd82016-10-27 10:27:00 +0200522/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700523
524static clib_error_t *
525show_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200526 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700527{
528 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200529 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700530 u32 pool_index;
Damjan Marion3891cd82016-10-27 10:27:00 +0200531 u8 *match_name = 0;
532 u8 *name;
Brian Russella71ed782021-01-27 11:34:33 +0000533 uword *pi;
Brian Russellc5299ff2021-02-09 10:16:58 +0000534 qos_pol_cfg_params_st *config;
Brian Russell54be0cc2021-02-15 11:49:42 +0000535 policer_t *templ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700536
537 (void) unformat (input, "name %s", &match_name);
538
Damjan Marion3891cd82016-10-27 10:27:00 +0200539 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700540 hash_foreach_pair (p, pm->policer_config_by_name,
541 ({
542 name = (u8 *) p->key;
543 if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
544 {
Brian Russella71ed782021-01-27 11:34:33 +0000545 pi = hash_get_mem (pm->policer_index_by_name, name);
546
547 pool_index = p->value[0];
548 config = pool_elt_at_index (pm->configs, pool_index);
549 templ = pool_elt_at_index (pm->policer_templates, pool_index);
550 vlib_cli_output (vm, "Name \"%s\" %U ", name, format_policer_config,
551 config);
552 vlib_cli_output (vm, "Template %U", format_policer_instance, templ,
553 pi[0]);
554 vlib_cli_output (vm, "-----------");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700555 }
556 }));
Damjan Marion3891cd82016-10-27 10:27:00 +0200557 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700558 return 0;
559}
560
561
Damjan Marion3891cd82016-10-27 10:27:00 +0200562/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700563VLIB_CLI_COMMAND (show_policer_command, static) = {
564 .path = "show policer",
565 .short_help = "show policer [name]",
566 .function = show_policer_command_fn,
567};
Damjan Marion3891cd82016-10-27 10:27:00 +0200568/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700569
Chaoyu Jin913b8732017-08-08 13:36:23 -0700570static clib_error_t *
571show_policer_pools_command_fn (vlib_main_t * vm,
572 unformat_input_t * input,
573 vlib_cli_command_t * cmd)
574{
575 vnet_policer_main_t *pm = &vnet_policer_main;
576
577 vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
578 pool_elts (pm->configs),
579 pool_elts (pm->policer_templates),
580 pool_elts (pm->policers));
581 return 0;
582}
583/* *INDENT-OFF* */
584VLIB_CLI_COMMAND (show_policer_pools_command, static) = {
585 .path = "show policer pools",
586 .short_help = "show policer pools",
587 .function = show_policer_pools_command_fn,
588};
589/* *INDENT-ON* */
590
Damjan Marion3891cd82016-10-27 10:27:00 +0200591clib_error_t *
592policer_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700593{
Damjan Marion3891cd82016-10-27 10:27:00 +0200594 vnet_policer_main_t *pm = &vnet_policer_main;
595 void vnet_policer_node_funcs_reference (void);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700596
Damjan Marion3891cd82016-10-27 10:27:00 +0200597 vnet_policer_node_funcs_reference ();
598
Ed Warnickecb9cada2015-12-08 15:45:58 -0700599 pm->vlib_main = vm;
Damjan Marion3891cd82016-10-27 10:27:00 +0200600 pm->vnet_main = vnet_get_main ();
Brian Russellbbccdc52021-02-10 18:34:48 +0000601 pm->log_class = vlib_log_register_class ("policer", 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700602
603 pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700604 pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
605
606 vnet_classify_register_unformat_policer_next_index_fn
607 (unformat_policer_classify_next_index);
608 vnet_classify_register_unformat_opaque_index_fn
609 (unformat_policer_classify_precolor);
610
Ed Warnickecb9cada2015-12-08 15:45:58 -0700611 return 0;
612}
613
Damjan Marion3891cd82016-10-27 10:27:00 +0200614VLIB_INIT_FUNCTION (policer_init);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700615
616
Damjan Marion3891cd82016-10-27 10:27:00 +0200617
618/*
619 * fd.io coding-style-patch-verification: ON
620 *
621 * Local Variables:
622 * eval: (c-set-style "gnu")
623 * End:
624 */