blob: 4aaf9e01e04775769aa6ad9a9df74e3e5de291d0 [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
Brian Russellb0468302021-02-17 15:51:45 +0000168int
169policer_input (u8 *name, u32 sw_if_index, bool apply)
170{
171 vnet_policer_main_t *pm = &vnet_policer_main;
172 policer_t *policer;
173 u32 policer_index;
174 uword *p;
175
176 p = hash_get_mem (pm->policer_index_by_name, name);
177 if (p == 0)
178 {
179 return VNET_API_ERROR_NO_SUCH_ENTRY;
180 }
181
182 policer = &pm->policers[p[0]];
183 policer_index = policer - pm->policers;
184
185 if (apply)
186 {
187 vec_validate (pm->policer_index_by_sw_if_index, sw_if_index);
188 pm->policer_index_by_sw_if_index[sw_if_index] = policer_index;
189 }
190 else
191 {
192 pm->policer_index_by_sw_if_index[sw_if_index] = ~0;
193 }
194
195 vnet_feature_enable_disable ("device-input", "policer-input", sw_if_index,
196 apply, 0, 0);
197 return 0;
198}
199
Damjan Marion3891cd82016-10-27 10:27:00 +0200200u8 *
201format_policer_instance (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700202{
Brian Russell54be0cc2021-02-15 11:49:42 +0000203 policer_t *i = va_arg (*va, policer_t *);
Brian Russella71ed782021-01-27 11:34:33 +0000204 uword pi = va_arg (*va, uword);
205 int result;
206 vlib_counter_t counts[NUM_POLICE_RESULTS];
207
208 for (result = 0; result < NUM_POLICE_RESULTS; result++)
209 {
210 vlib_get_combined_counter (&policer_counters[result], pi,
211 &counts[result]);
212 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213
Damjan Marion3891cd82016-10-27 10:27:00 +0200214 s = format (s, "policer at %llx: %s rate, %s color-aware\n",
215 i, i->single_rate ? "single" : "dual",
216 i->color_aware ? "is" : "not");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700217 s = format (s, "cir %u tok/period, pir %u tok/period, scale %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200218 i->cir_tokens_per_period, i->pir_tokens_per_period, i->scale);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700219 s = format (s, "cur lim %u, cur bkt %u, ext lim %u, ext bkt %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200220 i->current_limit,
221 i->current_bucket, i->extended_limit, i->extended_bucket);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700222 s = format (s, "last update %llu\n", i->last_update_time);
Brian Russella71ed782021-01-27 11:34:33 +0000223 s = format (s, "conform %llu packets, %llu bytes\n",
224 counts[POLICE_CONFORM].packets, counts[POLICE_CONFORM].bytes);
225 s = format (s, "exceed %llu packets, %llu bytes\n",
226 counts[POLICE_EXCEED].packets, counts[POLICE_EXCEED].bytes);
227 s = format (s, "violate %llu packets, %llu bytes\n",
228 counts[POLICE_VIOLATE].packets, counts[POLICE_VIOLATE].bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229 return s;
Damjan Marion3891cd82016-10-27 10:27:00 +0200230}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700231
Damjan Marion3891cd82016-10-27 10:27:00 +0200232static u8 *
233format_policer_round_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234{
Brian Russellc5299ff2021-02-09 10:16:58 +0000235 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700236
Brian Russellc5299ff2021-02-09 10:16:58 +0000237 if (c->rnd_type == QOS_ROUND_TO_CLOSEST)
Damjan Marion3891cd82016-10-27 10:27:00 +0200238 s = format (s, "closest");
Brian Russellc5299ff2021-02-09 10:16:58 +0000239 else if (c->rnd_type == QOS_ROUND_TO_UP)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240 s = format (s, "up");
Brian Russellc5299ff2021-02-09 10:16:58 +0000241 else if (c->rnd_type == QOS_ROUND_TO_DOWN)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700242 s = format (s, "down");
243 else
244 s = format (s, "ILLEGAL");
245 return s;
246}
247
248
Damjan Marion3891cd82016-10-27 10:27:00 +0200249static u8 *
250format_policer_rate_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251{
Brian Russellc5299ff2021-02-09 10:16:58 +0000252 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700253
Brian Russellc5299ff2021-02-09 10:16:58 +0000254 if (c->rate_type == QOS_RATE_KBPS)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255 s = format (s, "kbps");
Brian Russellc5299ff2021-02-09 10:16:58 +0000256 else if (c->rate_type == QOS_RATE_PPS)
Damjan Marion3891cd82016-10-27 10:27:00 +0200257 s = format (s, "pps");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258 else
259 s = format (s, "ILLEGAL");
260 return s;
261}
262
Damjan Marion3891cd82016-10-27 10:27:00 +0200263static u8 *
264format_policer_type (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265{
Brian Russellc5299ff2021-02-09 10:16:58 +0000266 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Damjan Marion3891cd82016-10-27 10:27:00 +0200267
Brian Russellc5299ff2021-02-09 10:16:58 +0000268 if (c->rfc == QOS_POLICER_TYPE_1R2C)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700269 s = format (s, "1r2c");
Damjan Marion3891cd82016-10-27 10:27:00 +0200270
Brian Russellc5299ff2021-02-09 10:16:58 +0000271 else if (c->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272 s = format (s, "1r3c");
273
Brian Russellc5299ff2021-02-09 10:16:58 +0000274 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275 s = format (s, "2r3c-2698");
276
Brian Russellc5299ff2021-02-09 10:16:58 +0000277 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700278 s = format (s, "2r3c-4115");
279
Brian Russellc5299ff2021-02-09 10:16:58 +0000280 else if (c->rfc == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281 s = format (s, "2r3c-mef5cf1");
282 else
283 s = format (s, "ILLEGAL");
284 return s;
285}
286
Damjan Marion3891cd82016-10-27 10:27:00 +0200287static u8 *
Damjan Marion3891cd82016-10-27 10:27:00 +0200288format_policer_action_type (u8 * s, va_list * va)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700289{
Brian Russellc5299ff2021-02-09 10:16:58 +0000290 qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700291
Brian Russellc5299ff2021-02-09 10:16:58 +0000292 if (a->action_type == QOS_ACTION_DROP)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700293 s = format (s, "drop");
Brian Russellc5299ff2021-02-09 10:16:58 +0000294 else if (a->action_type == QOS_ACTION_TRANSMIT)
Matus Fabian4ac74c92016-05-31 07:33:29 -0700295 s = format (s, "transmit");
Brian Russellc5299ff2021-02-09 10:16:58 +0000296 else if (a->action_type == QOS_ACTION_MARK_AND_TRANSMIT)
Brian Russelle3845d72021-02-08 15:33:18 +0000297 s = format (s, "mark-and-transmit %U", format_ip_dscp, a->dscp);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700298 else
299 s = format (s, "ILLEGAL");
300 return s;
301}
302
Damjan Marion3891cd82016-10-27 10:27:00 +0200303u8 *
304format_policer_config (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700305{
Brian Russellc5299ff2021-02-09 10:16:58 +0000306 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307
308 s = format (s, "type %U cir %u eir %u cb %u eb %u\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200309 format_policer_type, c,
310 c->rb.kbps.cir_kbps,
311 c->rb.kbps.eir_kbps, c->rb.kbps.cb_bytes, c->rb.kbps.eb_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700312 s = format (s, "rate type %U, round type %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200313 format_policer_rate_type, c, format_policer_round_type, c);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700314 s = format (s, "conform action %U, exceed action %U, violate action %U\n",
Damjan Marion3891cd82016-10-27 10:27:00 +0200315 format_policer_action_type, &c->conform_action,
316 format_policer_action_type, &c->exceed_action,
317 format_policer_action_type, &c->violate_action);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700318 return s;
319}
320
321static uword
322unformat_policer_type (unformat_input_t * input, va_list * va)
323{
Brian Russellc5299ff2021-02-09 10:16:58 +0000324 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700325
326 if (!unformat (input, "type"))
327 return 0;
328
329 if (unformat (input, "1r2c"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000330 c->rfc = QOS_POLICER_TYPE_1R2C;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331 else if (unformat (input, "1r3c"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000332 c->rfc = QOS_POLICER_TYPE_1R3C_RFC_2697;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700333 else if (unformat (input, "2r3c-2698"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000334 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_2698;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700335 else if (unformat (input, "2r3c-4115"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000336 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_4115;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337 else if (unformat (input, "2r3c-mef5cf1"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000338 c->rfc = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700339 else
340 return 0;
341 return 1;
342}
343
344static uword
345unformat_policer_round_type (unformat_input_t * input, va_list * va)
346{
Brian Russellc5299ff2021-02-09 10:16:58 +0000347 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348
Damjan Marion3891cd82016-10-27 10:27:00 +0200349 if (!unformat (input, "round"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700350 return 0;
351
Damjan Marion3891cd82016-10-27 10:27:00 +0200352 if (unformat (input, "closest"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000353 c->rnd_type = QOS_ROUND_TO_CLOSEST;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700354 else if (unformat (input, "up"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000355 c->rnd_type = QOS_ROUND_TO_UP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700356 else if (unformat (input, "down"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000357 c->rnd_type = QOS_ROUND_TO_DOWN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700358 else
359 return 0;
360 return 1;
361}
362
363static uword
364unformat_policer_rate_type (unformat_input_t * input, va_list * va)
365{
Brian Russellc5299ff2021-02-09 10:16:58 +0000366 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700367
Damjan Marion3891cd82016-10-27 10:27:00 +0200368 if (!unformat (input, "rate"))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700369 return 0;
370
371 if (unformat (input, "kbps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000372 c->rate_type = QOS_RATE_KBPS;
Damjan Marion3891cd82016-10-27 10:27:00 +0200373 else if (unformat (input, "pps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000374 c->rate_type = QOS_RATE_PPS;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700375 else
376 return 0;
377 return 1;
378}
379
380static uword
381unformat_policer_cir (unformat_input_t * input, va_list * va)
382{
Brian Russellc5299ff2021-02-09 10:16:58 +0000383 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
385 if (unformat (input, "cir %u", &c->rb.kbps.cir_kbps))
386 return 1;
387 return 0;
388}
389
390static uword
391unformat_policer_eir (unformat_input_t * input, va_list * va)
392{
Brian Russellc5299ff2021-02-09 10:16:58 +0000393 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700394
395 if (unformat (input, "eir %u", &c->rb.kbps.eir_kbps))
396 return 1;
397 return 0;
398}
399
400static uword
401unformat_policer_cb (unformat_input_t * input, va_list * va)
402{
Brian Russellc5299ff2021-02-09 10:16:58 +0000403 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700404
405 if (unformat (input, "cb %u", &c->rb.kbps.cb_bytes))
406 return 1;
407 return 0;
408}
409
410static uword
411unformat_policer_eb (unformat_input_t * input, va_list * va)
412{
Brian Russellc5299ff2021-02-09 10:16:58 +0000413 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700414
415 if (unformat (input, "eb %u", &c->rb.kbps.eb_bytes))
416 return 1;
417 return 0;
418}
419
Matus Fabian4ac74c92016-05-31 07:33:29 -0700420static uword
Matus Fabian4ac74c92016-05-31 07:33:29 -0700421unformat_policer_action_type (unformat_input_t * input, va_list * va)
422{
Brian Russellc5299ff2021-02-09 10:16:58 +0000423 qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700424
425 if (unformat (input, "drop"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000426 a->action_type = QOS_ACTION_DROP;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700427 else if (unformat (input, "transmit"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000428 a->action_type = QOS_ACTION_TRANSMIT;
Brian Russelle3845d72021-02-08 15:33:18 +0000429 else if (unformat (input, "mark-and-transmit %U", unformat_ip_dscp,
430 &a->dscp))
Brian Russellc5299ff2021-02-09 10:16:58 +0000431 a->action_type = QOS_ACTION_MARK_AND_TRANSMIT;
Matus Fabian4ac74c92016-05-31 07:33:29 -0700432 else
433 return 0;
434 return 1;
435}
436
437static uword
438unformat_policer_action (unformat_input_t * input, va_list * va)
439{
Brian Russellc5299ff2021-02-09 10:16:58 +0000440 qos_pol_cfg_params_st *c = va_arg (*va, qos_pol_cfg_params_st *);
Matus Fabian4ac74c92016-05-31 07:33:29 -0700441
442 if (unformat (input, "conform-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200443 &c->conform_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700444 return 1;
445 else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200446 &c->exceed_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700447 return 1;
448 else if (unformat (input, "violate-action %U", unformat_policer_action_type,
Damjan Marion3891cd82016-10-27 10:27:00 +0200449 &c->violate_action))
Matus Fabian4ac74c92016-05-31 07:33:29 -0700450 return 1;
451 return 0;
452}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700453
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700454static uword
455unformat_policer_classify_next_index (unformat_input_t * input, va_list * va)
456{
Damjan Marion3891cd82016-10-27 10:27:00 +0200457 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700458 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200459 uword *p;
460 u8 *match_name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700461
462 if (unformat (input, "%s", &match_name))
463 ;
464 else
465 return 0;
466
467 p = hash_get_mem (pm->policer_index_by_name, match_name);
468
469 if (p == 0)
470 return 0;
471
472 *r = p[0];
473
474 return 1;
475}
476
477static uword
478unformat_policer_classify_precolor (unformat_input_t * input, va_list * va)
479{
Damjan Marion3891cd82016-10-27 10:27:00 +0200480 u32 *r = va_arg (*va, u32 *);
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700481
482 if (unformat (input, "conform-color"))
483 *r = POLICE_CONFORM;
484 else if (unformat (input, "exceed-color"))
485 *r = POLICE_EXCEED;
486 else
487 return 0;
488
489 return 1;
490}
491
Ed Warnickecb9cada2015-12-08 15:45:58 -0700492#define foreach_config_param \
493_(eb) \
494_(cb) \
495_(eir) \
496_(cir) \
497_(rate_type) \
498_(round_type) \
Matus Fabian4ac74c92016-05-31 07:33:29 -0700499_(type) \
500_(action)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700501
502static clib_error_t *
503configure_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200504 unformat_input_t * input,
505 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700506{
Brian Russellc5299ff2021-02-09 10:16:58 +0000507 qos_pol_cfg_params_st c;
Damjan Marion3891cd82016-10-27 10:27:00 +0200508 unformat_input_t _line_input, *line_input = &_line_input;
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700509 u8 is_add = 1;
Damjan Marion3891cd82016-10-27 10:27:00 +0200510 u8 *name = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700511 u32 pi;
Billy McFalla9a20e72017-02-15 11:39:12 -0500512 clib_error_t *error = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700513
514 /* Get a line of input. */
Damjan Marion3891cd82016-10-27 10:27:00 +0200515 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700516 return 0;
517
Dave Barachb7b92992018-10-17 10:38:51 -0400518 clib_memset (&c, 0, sizeof (c));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700519
Damjan Marion3891cd82016-10-27 10:27:00 +0200520 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700521 {
522 if (unformat (line_input, "del"))
Damjan Marion3891cd82016-10-27 10:27:00 +0200523 is_add = 0;
524 else if (unformat (line_input, "name %s", &name))
525 ;
526 else if (unformat (line_input, "color-aware"))
527 c.color_aware = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700528
529#define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
530 foreach_config_param
531#undef _
Damjan Marion3891cd82016-10-27 10:27:00 +0200532 else
Billy McFalla9a20e72017-02-15 11:39:12 -0500533 {
534 error = clib_error_return (0, "unknown input `%U'",
535 format_unformat_error, line_input);
536 goto done;
537 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700538 }
539
Billy McFalla9a20e72017-02-15 11:39:12 -0500540 error = policer_add_del (vm, name, &c, &pi, is_add);
541
542done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700543 unformat_free (line_input);
544
Billy McFalla9a20e72017-02-15 11:39:12 -0500545 return error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700546}
547
Damjan Marion3891cd82016-10-27 10:27:00 +0200548/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700549VLIB_CLI_COMMAND (configure_policer_command, static) = {
550 .path = "configure policer",
551 .short_help = "configure policer name <name> <params> ",
552 .function = configure_policer_command_fn,
553};
Damjan Marion3891cd82016-10-27 10:27:00 +0200554/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700555
556static clib_error_t *
557show_policer_command_fn (vlib_main_t * vm,
Damjan Marion3891cd82016-10-27 10:27:00 +0200558 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700559{
560 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200561 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700562 u32 pool_index;
Damjan Marion3891cd82016-10-27 10:27:00 +0200563 u8 *match_name = 0;
564 u8 *name;
Brian Russella71ed782021-01-27 11:34:33 +0000565 uword *pi;
Brian Russellc5299ff2021-02-09 10:16:58 +0000566 qos_pol_cfg_params_st *config;
Brian Russell54be0cc2021-02-15 11:49:42 +0000567 policer_t *templ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700568
569 (void) unformat (input, "name %s", &match_name);
570
Damjan Marion3891cd82016-10-27 10:27:00 +0200571 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700572 hash_foreach_pair (p, pm->policer_config_by_name,
573 ({
574 name = (u8 *) p->key;
575 if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
576 {
Brian Russella71ed782021-01-27 11:34:33 +0000577 pi = hash_get_mem (pm->policer_index_by_name, name);
578
579 pool_index = p->value[0];
580 config = pool_elt_at_index (pm->configs, pool_index);
581 templ = pool_elt_at_index (pm->policer_templates, pool_index);
582 vlib_cli_output (vm, "Name \"%s\" %U ", name, format_policer_config,
583 config);
584 vlib_cli_output (vm, "Template %U", format_policer_instance, templ,
585 pi[0]);
586 vlib_cli_output (vm, "-----------");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700587 }
588 }));
Damjan Marion3891cd82016-10-27 10:27:00 +0200589 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700590 return 0;
591}
592
593
Damjan Marion3891cd82016-10-27 10:27:00 +0200594/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700595VLIB_CLI_COMMAND (show_policer_command, static) = {
596 .path = "show policer",
597 .short_help = "show policer [name]",
598 .function = show_policer_command_fn,
599};
Damjan Marion3891cd82016-10-27 10:27:00 +0200600/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700601
Chaoyu Jin913b8732017-08-08 13:36:23 -0700602static clib_error_t *
603show_policer_pools_command_fn (vlib_main_t * vm,
604 unformat_input_t * input,
605 vlib_cli_command_t * cmd)
606{
607 vnet_policer_main_t *pm = &vnet_policer_main;
608
609 vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
610 pool_elts (pm->configs),
611 pool_elts (pm->policer_templates),
612 pool_elts (pm->policers));
613 return 0;
614}
615/* *INDENT-OFF* */
616VLIB_CLI_COMMAND (show_policer_pools_command, static) = {
617 .path = "show policer pools",
618 .short_help = "show policer pools",
619 .function = show_policer_pools_command_fn,
620};
621/* *INDENT-ON* */
622
Damjan Marion3891cd82016-10-27 10:27:00 +0200623clib_error_t *
624policer_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700625{
Damjan Marion3891cd82016-10-27 10:27:00 +0200626 vnet_policer_main_t *pm = &vnet_policer_main;
Damjan Marion3891cd82016-10-27 10:27:00 +0200627
Ed Warnickecb9cada2015-12-08 15:45:58 -0700628 pm->vlib_main = vm;
Damjan Marion3891cd82016-10-27 10:27:00 +0200629 pm->vnet_main = vnet_get_main ();
Brian Russellbbccdc52021-02-10 18:34:48 +0000630 pm->log_class = vlib_log_register_class ("policer", 0);
Brian Russell1aa99122021-02-18 11:00:38 +0000631 pm->fq_index = vlib_frame_queue_main_init (policer_input_node.index, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700632
633 pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700634 pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
635
636 vnet_classify_register_unformat_policer_next_index_fn
637 (unformat_policer_classify_next_index);
638 vnet_classify_register_unformat_opaque_index_fn
639 (unformat_policer_classify_precolor);
640
Ed Warnickecb9cada2015-12-08 15:45:58 -0700641 return 0;
642}
643
Damjan Marion3891cd82016-10-27 10:27:00 +0200644VLIB_INIT_FUNCTION (policer_init);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700645
646
Damjan Marion3891cd82016-10-27 10:27:00 +0200647
648/*
649 * fd.io coding-style-patch-verification: ON
650 *
651 * Local Variables:
652 * eval: (c-set-style "gnu")
653 * End:
654 */