blob: 7985579d3cf12c5b0e85307b9b16d13905128d47 [file] [log] [blame]
Neale Ranns039cbfe2018-02-27 03:45:38 -08001/*
2 *------------------------------------------------------------------
3 * Copyright (c) 2018 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
16 */
17
18#include <vnet/qos/qos_egress_map.h>
19#include <vnet/qos/qos_mark.h>
20
21/**
22 * Pool from which to allocate table
23 */
24qos_egress_map_t *qem_pool;
25
26/**
27 * DB to map user table-IDs to internal table indicies.
28 */
29uword *qem_db;
30
31index_t
32qos_egress_map_find (qos_egress_map_id_t mid)
33{
34 uword *p = NULL;
35
36 p = hash_get (qem_db, mid);
37
38 if (NULL != p)
39 return p[0];
40
41 return (INDEX_INVALID);
42}
43
Neale Ranns5281a902019-07-23 08:16:19 -070044qos_egress_map_id_t
45qos_egress_map_get_id (index_t qemi)
46{
47 qos_egress_map_id_t qid;
48 index_t qmi;
49
50 /* *INDENT-OFF* */
51 hash_foreach(qid, qmi, qem_db,
52 ({
53 if (qmi == qemi)
54 return (qid);
55 }));
56 /* *INDENT-OFF* */
57
58 return (~0);
59}
60
Neale Ranns039cbfe2018-02-27 03:45:38 -080061qos_egress_map_t *
62qos_egress_map_find_i (qos_egress_map_id_t mid)
63{
64 index_t qemi;
65
66 qemi = qos_egress_map_find (mid);
67
68 if (INDEX_INVALID != qemi)
69 {
70 return (pool_elt_at_index (qem_pool, qemi));
71 }
72
73 return (NULL);
74}
75
76static qos_egress_map_t *
77qos_egress_map_find_or_create (qos_egress_map_id_t mid)
78{
79 qos_egress_map_t *qem;
80
81 /*
82 * Find the existing or create a new table
83 */
84 qem = qos_egress_map_find_i (mid);
85
86 if (NULL == qem)
87 {
88 index_t qemi;
89
90 pool_get_aligned (qem_pool, qem, CLIB_CACHE_LINE_BYTES);
91 qemi = qem - qem_pool;
92
Dave Barachb7b92992018-10-17 10:38:51 -040093 clib_memset (qem, 0, sizeof (*qem));
Neale Ranns039cbfe2018-02-27 03:45:38 -080094 hash_set (qem_db, mid, qemi);
95 }
96
97 return (qem);
98}
99
100void
101qos_egress_map_update (qos_egress_map_id_t mid,
102 qos_source_t input_source, qos_bits_t * values)
103{
104 qos_egress_map_t *qem;
105
106 qem = qos_egress_map_find_or_create (mid);
107
108 clib_memcpy (qem->qem_output[input_source],
109 values, sizeof (qem->qem_output[input_source]));
110}
111
112void
113qos_egress_map_delete (qos_egress_map_id_t mid)
114{
115 qos_egress_map_t *qem;
116
117 qem = qos_egress_map_find_i (mid);
118 hash_unset (qem_db, mid);
119
120 if (NULL != qem)
121 {
122 pool_put (qem_pool, qem);
123 }
124}
125
Neale Ranns5281a902019-07-23 08:16:19 -0700126void
127qos_egress_map_walk (qos_egress_map_walk_cb_t fn, void *c)
128{
129 qos_egress_map_id_t qid;
130 index_t qmi;
131
132 /* *INDENT-OFF* */
133 hash_foreach(qid, qmi, qem_db,
134 ({
135 fn(qid, pool_elt_at_index(qem_pool, qmi), c);
136 }));
137 /* *INDENT-OFF* */
138}
139
Neale Ranns039cbfe2018-02-27 03:45:38 -0800140static clib_error_t *
141qos_egress_map_update_cli (vlib_main_t * vm,
142 unformat_input_t * input, vlib_cli_command_t * cmd)
143{
144 qos_egress_map_id_t map_id;
145 qos_egress_map_t *qem;
146 u8 add;
147
148 add = 1;
149 map_id = ~0;
150 qem = NULL;
151
152 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
153 {
154 if (unformat (input, "delete") || unformat (input, "del"))
155 add = 0;
156 else if (unformat (input, "id %d", &map_id))
157 qem = qos_egress_map_find_or_create (map_id);
158 else
159 {
160 int qs, qi, qo;
161
162 if (NULL == qem)
163 return clib_error_return (0, "map-id must be specified");
164
165 while (unformat
166 (input, "[%U][%d]=%d", unformat_qos_source, &qs, &qi, &qo))
167 qem->qem_output[qs][qi] = qo;
168 break;
169 }
170 }
171
172 if (!add)
173 qos_egress_map_delete (map_id);
174
175 return (NULL);
176}
177
178/*?
179 * Update a Egress Qos Map table
180 *
181 * @cliexpar
182 * @cliexcmd{qos egress map id 0 [ip][4]=4}
183 ?*/
184/* *INDENT-OFF* */
185VLIB_CLI_COMMAND (qos_egress_map_update_command, static) = {
186 .path = "qos egress map",
187 .short_help = "qos egress map id %d [delete] {[SOURCE][INPUT]=OUTPUT}",
188 .function = qos_egress_map_update_cli,
189 .is_mp_safe = 1,
190};
191/* *INDENT-ON* */
192
Neale Ranns5281a902019-07-23 08:16:19 -0700193 u8 *format_qos_egress_map (u8 * s, va_list * args)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800194 {
Neale Ranns5281a902019-07-23 08:16:19 -0700195 qos_egress_map_t *qem = va_arg (*args, qos_egress_map_t *);
196 u32 indent = va_arg (*args, u32);
197 int qs;
198 u32 ii;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800199
Neale Ranns5281a902019-07-23 08:16:19 -0700200 FOR_EACH_QOS_SOURCE (qs)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800201 {
Neale Ranns5281a902019-07-23 08:16:19 -0700202 s = format (s, "%U%U:[",
203 format_white_space, indent, format_qos_source, qs);
204
205 for (ii = 0; ii < ARRAY_LEN (qem->qem_output[qs]) - 1; ii++)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800206 {
Neale Ranns5281a902019-07-23 08:16:19 -0700207 s = format (s, "%d,", qem->qem_output[qs][ii]);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800208 }
Neale Ranns5281a902019-07-23 08:16:19 -0700209 s = format (s, "%d]\n", qem->qem_output[qs][ii]);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800210 }
211
Neale Ranns5281a902019-07-23 08:16:19 -0700212 return (s);
213 }
214
215 static clib_error_t *qos_egress_map_show (vlib_main_t * vm,
216 unformat_input_t * input,
217 vlib_cli_command_t * cmd)
218 {
219 qos_egress_map_id_t map_id;
220 qos_egress_map_t *qem;
221 clib_error_t *error;
222
223 map_id = ~0;
224 qem = NULL;
225 error = NULL;
226
227 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
228 {
229 if (unformat (input, "id %d", &map_id))
230 ;
231 else
232 {
233 error = unformat_parse_error (input);
234 goto done;
235 }
236 }
237
238 if (~0 == map_id)
239 {
240 index_t qemi;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800241
242 /* *INDENT-OFF* */
243 hash_foreach(map_id, qemi, qem_db,
244 ({
245 vlib_cli_output (vm, " Map-ID:%d\n%U",
246 map_id,
247 format_qos_egress_map,
248 pool_elt_at_index(qem_pool, qemi), 2);
249 }));
250 /* *INDENT-ON* */
Neale Ranns5281a902019-07-23 08:16:19 -0700251 }
252 else
253 {
254 qem = qos_egress_map_find_i (map_id);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800255
Neale Ranns5281a902019-07-23 08:16:19 -0700256 if (NULL == qem)
257 {
258 error = clib_error_return (0, "No Map for ID %d", map_id);
259 }
260 else
261 {
262 vlib_cli_output (vm, " Map-ID:%d\n%U",
263 map_id, format_qos_egress_map, qem, 2);
264 }
265 }
Neale Ranns039cbfe2018-02-27 03:45:38 -0800266
Neale Ranns5281a902019-07-23 08:16:19 -0700267 done:
268 return (error);
269 }
Neale Ranns039cbfe2018-02-27 03:45:38 -0800270
271/*?
272 * Show Egress Qos Maps
273 *
274 * @cliexpar
275 * @cliexcmd{show qos egress map}
276 ?*/
277/* *INDENT-OFF* */
278VLIB_CLI_COMMAND (qos_egress_map_show_command, static) = {
279 .path = "show qos egress map",
280 .short_help = "show qos egress map id %d",
281 .function = qos_egress_map_show,
282 .is_mp_safe = 1,
283};
284/* *INDENT-ON* */
285
286/*
287 * fd.io coding-style-patch-verification: ON
288 *
289 * Local Variables:
290 * eval: (c-set-style "gnu")
291 * End:
292 */