blob: 966ffcce3954019eec4a98821a1200ce0e2f0e04 [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/vnet.h>
19#include <vlibmemory/api.h>
20#include <vnet/api_errno.h>
21
22#include <vnet/qos/qos_record.h>
23#include <vnet/qos/qos_mark.h>
24#include <vnet/qos/qos_egress_map.h>
25
26#include <vnet/vnet_msg_enum.h>
27
28#define vl_typedefs /* define message structures */
29#include <vnet/vnet_all_api_h.h>
30#undef vl_typedefs
31
32#define vl_endianfun /* define message structures */
33#include <vnet/vnet_all_api_h.h>
34#undef vl_endianfun
35
36/* instantiate all the print functions we know about */
37#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
38#define vl_printfun
39#include <vnet/vnet_all_api_h.h>
40#undef vl_printfun
41
42#include <vlibapi/api_helper_macros.h>
43
44
45#define foreach_qos_api_msg \
46 _(QOS_RECORD_ENABLE_DISABLE, qos_record_enable_disable) \
Neale Ranns5281a902019-07-23 08:16:19 -070047 _(QOS_RECORD_DUMP, qos_record_dump) \
Neale Ranns039cbfe2018-02-27 03:45:38 -080048 _(QOS_EGRESS_MAP_DELETE, qos_egress_map_delete) \
49 _(QOS_EGRESS_MAP_UPDATE, qos_egress_map_update) \
Neale Ranns5281a902019-07-23 08:16:19 -070050 _(QOS_EGRESS_MAP_DUMP, qos_egress_map_dump) \
51 _(QOS_MARK_ENABLE_DISABLE, qos_mark_enable_disable) \
52 _(QOS_MARK_DUMP, qos_mark_dump)
Neale Ranns039cbfe2018-02-27 03:45:38 -080053
Neale Rannsed234e72018-09-05 09:36:05 -070054static int
55qos_source_decode (vl_api_qos_source_t v, qos_source_t * q)
56{
Neale Rannsed234e72018-09-05 09:36:05 -070057 switch (v)
58 {
59 case QOS_API_SOURCE_EXT:
60 *q = QOS_SOURCE_EXT;
61 return 0;
62 case QOS_API_SOURCE_VLAN:
63 *q = QOS_SOURCE_VLAN;
64 return 0;
65 case QOS_API_SOURCE_MPLS:
66 *q = QOS_SOURCE_MPLS;
67 return 0;
68 case QOS_API_SOURCE_IP:
69 *q = QOS_SOURCE_IP;
70 return 0;
71 }
72
73 return (VNET_API_ERROR_INVALID_VALUE);
74}
75
Neale Ranns5281a902019-07-23 08:16:19 -070076static vl_api_qos_source_t
77qos_source_encode (qos_source_t q)
78{
79 return ((vl_api_qos_source_t) q);
80}
81
Neale Ranns039cbfe2018-02-27 03:45:38 -080082void
83vl_api_qos_record_enable_disable_t_handler (vl_api_qos_record_enable_disable_t
84 * mp)
85{
86 vl_api_qos_record_enable_disable_reply_t *rmp;
Neale Rannsed234e72018-09-05 09:36:05 -070087 qos_source_t qs;
Neale Ranns039cbfe2018-02-27 03:45:38 -080088 int rv = 0;
89
Neale Ranns5281a902019-07-23 08:16:19 -070090 VALIDATE_SW_IF_INDEX (&(mp->record));
91
92 rv = qos_source_decode (mp->record.input_source, &qs);
Neale Rannsed234e72018-09-05 09:36:05 -070093
94 if (0 == rv)
Neale Ranns039cbfe2018-02-27 03:45:38 -080095 {
96 if (mp->enable)
Neale Ranns5281a902019-07-23 08:16:19 -070097 rv = qos_record_enable (ntohl (mp->record.sw_if_index), qs);
Neale Ranns039cbfe2018-02-27 03:45:38 -080098 else
Neale Ranns5281a902019-07-23 08:16:19 -070099 rv = qos_record_disable (ntohl (mp->record.sw_if_index), qs);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800100 }
101
Neale Ranns5281a902019-07-23 08:16:19 -0700102 BAD_SW_IF_INDEX_LABEL;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800103 REPLY_MACRO (VL_API_QOS_RECORD_ENABLE_DISABLE_REPLY);
104}
105
Neale Ranns5281a902019-07-23 08:16:19 -0700106typedef struct qos_record_send_walk_ctx_t_
107{
108 vl_api_registration_t *reg;
109 u32 context;
110} qos_record_send_walk_ctx_t;
111
112static walk_rc_t
113send_qos_record_details (u32 sw_if_index, qos_source_t input_source, void *c)
114{
115 qos_record_send_walk_ctx_t *ctx;
116 vl_api_qos_record_details_t *mp;
117
118 ctx = c;
119 mp = vl_msg_api_alloc_zero (sizeof (*mp));
120
121 mp->_vl_msg_id = ntohs (VL_API_QOS_RECORD_DETAILS);
122 mp->context = ctx->context;
123 mp->record.sw_if_index = htonl (sw_if_index);
124 mp->record.input_source = qos_source_encode (input_source);
125
126 vl_api_send_msg (ctx->reg, (u8 *) mp);
127
128 return (WALK_CONTINUE);
129}
130
131static void
132vl_api_qos_record_dump_t_handler (vl_api_qos_record_dump_t * mp)
133{
134 vl_api_registration_t *reg;
135
136 reg = vl_api_client_index_to_registration (mp->client_index);
137 if (!reg)
138 return;
139
140 qos_record_send_walk_ctx_t ctx = {
141 .reg = reg,
142 .context = mp->context,
143 };
144 qos_record_walk (send_qos_record_details, &ctx);
145}
146
Neale Ranns039cbfe2018-02-27 03:45:38 -0800147void
148vl_api_qos_egress_map_update_t_handler (vl_api_qos_egress_map_update_t * mp)
149{
150 vl_api_qos_egress_map_update_reply_t *rmp;
151 qos_source_t qs;
152 int rv = 0;
153
154 FOR_EACH_QOS_SOURCE (qs)
155 {
Neale Ranns5281a902019-07-23 08:16:19 -0700156 qos_egress_map_update (ntohl (mp->map.id), qs,
157 &mp->map.rows[qs].outputs[0]);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800158 }
159
160 REPLY_MACRO (VL_API_QOS_EGRESS_MAP_UPDATE_REPLY);
161}
162
163void
164vl_api_qos_egress_map_delete_t_handler (vl_api_qos_egress_map_delete_t * mp)
165{
166 vl_api_qos_egress_map_delete_reply_t *rmp;
167 int rv = 0;
168
Neale Ranns5281a902019-07-23 08:16:19 -0700169 qos_egress_map_delete (ntohl (mp->id));
Neale Ranns039cbfe2018-02-27 03:45:38 -0800170
171 REPLY_MACRO (VL_API_QOS_EGRESS_MAP_DELETE_REPLY);
172}
173
Neale Ranns5281a902019-07-23 08:16:19 -0700174typedef struct qos_egress_map_send_walk_ctx_t_
175{
176 vl_api_registration_t *reg;
177 u32 context;
178} qos_egress_map_send_walk_ctx_t;
179
180static walk_rc_t
181send_qos_egress_map_details (qos_egress_map_id_t id,
182 const qos_egress_map_t * m, void *c)
183{
184 qos_egress_map_send_walk_ctx_t *ctx;
185 vl_api_qos_egress_map_details_t *mp;
186 u8 ii;
187
188 ctx = c;
189 mp = vl_msg_api_alloc_zero (sizeof (*mp));
190
191 mp->_vl_msg_id = ntohs (VL_API_QOS_EGRESS_MAP_DETAILS);
192 mp->context = ctx->context;
193 mp->map.id = htonl (id);
194
195 for (ii = 0; ii < 4; ii++)
196 clib_memcpy (mp->map.rows[ii].outputs, m->qem_output[ii], 256);
197
198 vl_api_send_msg (ctx->reg, (u8 *) mp);
199
200 return (WALK_CONTINUE);
201}
202
203static void
204vl_api_qos_egress_map_dump_t_handler (vl_api_qos_egress_map_dump_t * mp)
205{
206 vl_api_registration_t *reg;
207
208 reg = vl_api_client_index_to_registration (mp->client_index);
209 if (!reg)
210 return;
211
212 qos_egress_map_send_walk_ctx_t ctx = {
213 .reg = reg,
214 .context = mp->context,
215 };
216 qos_egress_map_walk (send_qos_egress_map_details, &ctx);
217}
218
Neale Ranns039cbfe2018-02-27 03:45:38 -0800219void
Neale Ranns5281a902019-07-23 08:16:19 -0700220vl_api_qos_mark_enable_disable_t_handler (vl_api_qos_mark_enable_disable_t *
221 mp)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800222{
223 vl_api_qos_mark_enable_disable_reply_t *rmp;
Neale Rannsed234e72018-09-05 09:36:05 -0700224 qos_source_t qs;
Neale Ranns039cbfe2018-02-27 03:45:38 -0800225 int rv = 0;
226
Neale Ranns5281a902019-07-23 08:16:19 -0700227 rv = qos_source_decode (mp->mark.output_source, &qs);
Neale Rannsed234e72018-09-05 09:36:05 -0700228
229 if (0 == rv)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800230 {
231 if (mp->enable)
Neale Ranns5281a902019-07-23 08:16:19 -0700232 rv = qos_mark_enable (ntohl (mp->mark.sw_if_index),
233 qs, ntohl (mp->mark.map_id));
Neale Ranns039cbfe2018-02-27 03:45:38 -0800234 else
Neale Ranns5281a902019-07-23 08:16:19 -0700235 rv = qos_mark_disable (ntohl (mp->mark.sw_if_index), qs);
Neale Ranns039cbfe2018-02-27 03:45:38 -0800236 }
237
238 REPLY_MACRO (VL_API_QOS_MARK_ENABLE_DISABLE_REPLY);
239}
240
Neale Ranns5281a902019-07-23 08:16:19 -0700241typedef struct qos_mark_send_walk_ctx_t_
242{
243 vl_api_registration_t *reg;
244 u32 context;
245} qos_mark_send_walk_ctx_t;
246
247static walk_rc_t
248send_qos_mark_details (u32 sw_if_index,
249 u32 map_id, qos_source_t output_source, void *c)
250{
251 qos_mark_send_walk_ctx_t *ctx;
252 vl_api_qos_mark_details_t *mp;
253
254 ctx = c;
255 mp = vl_msg_api_alloc_zero (sizeof (*mp));
256
257 mp->_vl_msg_id = ntohs (VL_API_QOS_MARK_DETAILS);
258 mp->context = ctx->context;
259 mp->mark.sw_if_index = htonl (sw_if_index);
260 mp->mark.output_source = qos_source_encode (output_source);
261 mp->mark.map_id = htonl (map_id);
262
263 vl_api_send_msg (ctx->reg, (u8 *) mp);
264
265 return (WALK_CONTINUE);
266}
267
268static void
269vl_api_qos_mark_dump_t_handler (vl_api_qos_mark_dump_t * mp)
270{
271 vl_api_registration_t *reg;
272
273 reg = vl_api_client_index_to_registration (mp->client_index);
274 if (!reg)
275 return;
276
277 qos_mark_send_walk_ctx_t ctx = {
278 .reg = reg,
279 .context = mp->context,
280 };
281 qos_mark_walk (send_qos_mark_details, &ctx);
282}
283
Neale Ranns039cbfe2018-02-27 03:45:38 -0800284#define vl_msg_name_crc_list
285#include <vnet/qos/qos.api.h>
286#undef vl_msg_name_crc_list
287
288static void
289setup_message_id_table (api_main_t * am)
290{
291#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
292 foreach_vl_msg_name_crc_qos;
293#undef _
294}
295
296static clib_error_t *
297qos_api_hookup (vlib_main_t * vm)
298{
299 api_main_t *am = &api_main;
300
301#define _(N,n) \
302 vl_msg_api_set_handlers(VL_API_##N, #n, \
303 vl_api_##n##_t_handler, \
304 vl_noop_handler, \
305 vl_api_##n##_t_endian, \
306 vl_api_##n##_t_print, \
307 sizeof(vl_api_##n##_t), 1);
308 foreach_qos_api_msg;
309#undef _
310
311 /*
312 * Set up the (msg_name, crc, message-id) table
313 */
314 setup_message_id_table (am);
315
316 return 0;
317}
318
319VLIB_API_INIT_FUNCTION (qos_api_hookup);
320
321/*
322 * fd.io coding-style-patch-verification: ON
323 *
324 * Local Variables:
325 * eval: (c-set-style "gnu")
326 * End:
327 */