blob: 43c0c55df076bd144f0b5a5c006f303af578fc25 [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
Neale Ranns5281a902019-07-23 08:16:19 -070050 hash_foreach(qid, qmi, qem_db,
51 ({
52 if (qmi == qemi)
53 return (qid);
54 }));
Neale Ranns5281a902019-07-23 08:16:19 -070055
56 return (~0);
57}
58
Neale Ranns039cbfe2018-02-27 03:45:38 -080059qos_egress_map_t *
60qos_egress_map_find_i (qos_egress_map_id_t mid)
61{
62 index_t qemi;
63
64 qemi = qos_egress_map_find (mid);
65
66 if (INDEX_INVALID != qemi)
67 {
68 return (pool_elt_at_index (qem_pool, qemi));
69 }
70
71 return (NULL);
72}
73
74static qos_egress_map_t *
75qos_egress_map_find_or_create (qos_egress_map_id_t mid)
76{
77 qos_egress_map_t *qem;
78
79 /*
80 * Find the existing or create a new table
81 */
82 qem = qos_egress_map_find_i (mid);
83
84 if (NULL == qem)
85 {
86 index_t qemi;
87
88 pool_get_aligned (qem_pool, qem, CLIB_CACHE_LINE_BYTES);
89 qemi = qem - qem_pool;
90
Dave Barachb7b92992018-10-17 10:38:51 -040091 clib_memset (qem, 0, sizeof (*qem));
Neale Ranns039cbfe2018-02-27 03:45:38 -080092 hash_set (qem_db, mid, qemi);
93 }
94
95 return (qem);
96}
97
98void
99qos_egress_map_update (qos_egress_map_id_t mid,
100 qos_source_t input_source, qos_bits_t * values)
101{
102 qos_egress_map_t *qem;
103
104 qem = qos_egress_map_find_or_create (mid);
105
106 clib_memcpy (qem->qem_output[input_source],
107 values, sizeof (qem->qem_output[input_source]));
108}
109
110void
111qos_egress_map_delete (qos_egress_map_id_t mid)
112{
113 qos_egress_map_t *qem;
114
115 qem = qos_egress_map_find_i (mid);
116 hash_unset (qem_db, mid);
117
118 if (NULL != qem)
119 {
120 pool_put (qem_pool, qem);
121 }
122}
123
Neale Ranns5281a902019-07-23 08:16:19 -0700124void
125qos_egress_map_walk (qos_egress_map_walk_cb_t fn, void *c)
126{
127 qos_egress_map_id_t qid;
128 index_t qmi;
129
Neale Ranns5281a902019-07-23 08:16:19 -0700130 hash_foreach(qid, qmi, qem_db,
131 ({
132 fn(qid, pool_elt_at_index(qem_pool, qmi), c);
133 }));
Neale Ranns5281a902019-07-23 08:16:19 -0700134}
135
Neale Ranns039cbfe2018-02-27 03:45:38 -0800136static clib_error_t *
137qos_egress_map_update_cli (vlib_main_t * vm,
138 unformat_input_t * input, vlib_cli_command_t * cmd)
139{
140 qos_egress_map_id_t map_id;
141 qos_egress_map_t *qem;
142 u8 add;
143
144 add = 1;
145 map_id = ~0;
146 qem = NULL;
147
148 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
149 {
150 if (unformat (input, "delete") || unformat (input, "del"))
151 add = 0;
152 else if (unformat (input, "id %d", &map_id))
153 qem = qos_egress_map_find_or_create (map_id);
154 else
155 {
156 int qs, qi, qo;
157
158 if (NULL == qem)
159 return clib_error_return (0, "map-id must be specified");
160
161 while (unformat
162 (input, "[%U][%d]=%d", unformat_qos_source, &qs, &qi, &qo))
163 qem->qem_output[qs][qi] = qo;
164 break;
165 }
166 }
167
168 if (!add)
169 qos_egress_map_delete (map_id);
170
171 return (NULL);
172}
173
174/*?
175 * Update a Egress Qos Map table
176 *
177 * @cliexpar
178 * @cliexcmd{qos egress map id 0 [ip][4]=4}
179 ?*/
Neale Ranns039cbfe2018-02-27 03:45:38 -0800180VLIB_CLI_COMMAND (qos_egress_map_update_command, static) = {
181 .path = "qos egress map",
182 .short_help = "qos egress map id %d [delete] {[SOURCE][INPUT]=OUTPUT}",
183 .function = qos_egress_map_update_cli,
184 .is_mp_safe = 1,
185};
Neale Ranns039cbfe2018-02-27 03:45:38 -0800186
Neale Ranns5281a902019-07-23 08:16:19 -0700187 u8 *format_qos_egress_map (u8 * s, va_list * args)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800188 {
Neale Ranns5281a902019-07-23 08:16:19 -0700189 qos_egress_map_t *qem = va_arg (*args, qos_egress_map_t *);
190 u32 indent = va_arg (*args, u32);
191 int qs;
192 u32 ii;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800193
Neale Ranns5281a902019-07-23 08:16:19 -0700194 FOR_EACH_QOS_SOURCE (qs)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800195 {
Neale Ranns5281a902019-07-23 08:16:19 -0700196 s = format (s, "%U%U:[",
197 format_white_space, indent, format_qos_source, qs);
198
199 for (ii = 0; ii < ARRAY_LEN (qem->qem_output[qs]) - 1; ii++)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800200 {
Neale Ranns5281a902019-07-23 08:16:19 -0700201 s = format (s, "%d,", qem->qem_output[qs][ii]);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800202 }
Neale Ranns5281a902019-07-23 08:16:19 -0700203 s = format (s, "%d]\n", qem->qem_output[qs][ii]);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800204 }
205
Neale Ranns5281a902019-07-23 08:16:19 -0700206 return (s);
207 }
208
209 static clib_error_t *qos_egress_map_show (vlib_main_t * vm,
210 unformat_input_t * input,
211 vlib_cli_command_t * cmd)
212 {
213 qos_egress_map_id_t map_id;
214 qos_egress_map_t *qem;
215 clib_error_t *error;
216
217 map_id = ~0;
218 qem = NULL;
219 error = NULL;
220
221 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
222 {
223 if (unformat (input, "id %d", &map_id))
224 ;
225 else
226 {
227 error = unformat_parse_error (input);
228 goto done;
229 }
230 }
231
232 if (~0 == map_id)
233 {
234 index_t qemi;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800235
Neale Ranns039cbfe2018-02-27 03:45:38 -0800236 hash_foreach(map_id, qemi, qem_db,
237 ({
238 vlib_cli_output (vm, " Map-ID:%d\n%U",
239 map_id,
240 format_qos_egress_map,
241 pool_elt_at_index(qem_pool, qemi), 2);
242 }));
Neale Ranns5281a902019-07-23 08:16:19 -0700243 }
244 else
245 {
246 qem = qos_egress_map_find_i (map_id);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800247
Neale Ranns5281a902019-07-23 08:16:19 -0700248 if (NULL == qem)
249 {
250 error = clib_error_return (0, "No Map for ID %d", map_id);
251 }
252 else
253 {
254 vlib_cli_output (vm, " Map-ID:%d\n%U",
255 map_id, format_qos_egress_map, qem, 2);
256 }
257 }
Neale Ranns039cbfe2018-02-27 03:45:38 -0800258
Neale Ranns5281a902019-07-23 08:16:19 -0700259 done:
260 return (error);
261 }
Neale Ranns039cbfe2018-02-27 03:45:38 -0800262
263/*?
264 * Show Egress Qos Maps
265 *
266 * @cliexpar
267 * @cliexcmd{show qos egress map}
268 ?*/
Neale Ranns039cbfe2018-02-27 03:45:38 -0800269VLIB_CLI_COMMAND (qos_egress_map_show_command, static) = {
270 .path = "show qos egress map",
271 .short_help = "show qos egress map id %d",
272 .function = qos_egress_map_show,
273 .is_mp_safe = 1,
274};
Neale Ranns039cbfe2018-02-27 03:45:38 -0800275
276/*
277 * fd.io coding-style-patch-verification: ON
278 *
279 * Local Variables:
280 * eval: (c-set-style "gnu")
281 * End:
282 */