qos: QoS dump APIs
[vpp.git] / src / vnet / qos / qos_api.c
1 /*
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)               \
47   _(QOS_RECORD_DUMP, qos_record_dump)                                   \
48   _(QOS_EGRESS_MAP_DELETE, qos_egress_map_delete)                       \
49   _(QOS_EGRESS_MAP_UPDATE, qos_egress_map_update)                       \
50   _(QOS_EGRESS_MAP_DUMP, qos_egress_map_dump)                           \
51   _(QOS_MARK_ENABLE_DISABLE, qos_mark_enable_disable)                   \
52   _(QOS_MARK_DUMP, qos_mark_dump)
53
54 static int
55 qos_source_decode (vl_api_qos_source_t v, qos_source_t * q)
56 {
57   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
76 static vl_api_qos_source_t
77 qos_source_encode (qos_source_t q)
78 {
79   return ((vl_api_qos_source_t) q);
80 }
81
82 void
83 vl_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;
87   qos_source_t qs;
88   int rv = 0;
89
90   VALIDATE_SW_IF_INDEX (&(mp->record));
91
92   rv = qos_source_decode (mp->record.input_source, &qs);
93
94   if (0 == rv)
95     {
96       if (mp->enable)
97         rv = qos_record_enable (ntohl (mp->record.sw_if_index), qs);
98       else
99         rv = qos_record_disable (ntohl (mp->record.sw_if_index), qs);
100     }
101
102   BAD_SW_IF_INDEX_LABEL;
103   REPLY_MACRO (VL_API_QOS_RECORD_ENABLE_DISABLE_REPLY);
104 }
105
106 typedef 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
112 static walk_rc_t
113 send_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
131 static void
132 vl_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
147 void
148 vl_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   {
156     qos_egress_map_update (ntohl (mp->map.id), qs,
157                            &mp->map.rows[qs].outputs[0]);
158   }
159
160   REPLY_MACRO (VL_API_QOS_EGRESS_MAP_UPDATE_REPLY);
161 }
162
163 void
164 vl_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
169   qos_egress_map_delete (ntohl (mp->id));
170
171   REPLY_MACRO (VL_API_QOS_EGRESS_MAP_DELETE_REPLY);
172 }
173
174 typedef 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
180 static walk_rc_t
181 send_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
203 static void
204 vl_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
219 void
220 vl_api_qos_mark_enable_disable_t_handler (vl_api_qos_mark_enable_disable_t *
221                                           mp)
222 {
223   vl_api_qos_mark_enable_disable_reply_t *rmp;
224   qos_source_t qs;
225   int rv = 0;
226
227   rv = qos_source_decode (mp->mark.output_source, &qs);
228
229   if (0 == rv)
230     {
231       if (mp->enable)
232         rv = qos_mark_enable (ntohl (mp->mark.sw_if_index),
233                               qs, ntohl (mp->mark.map_id));
234       else
235         rv = qos_mark_disable (ntohl (mp->mark.sw_if_index), qs);
236     }
237
238   REPLY_MACRO (VL_API_QOS_MARK_ENABLE_DISABLE_REPLY);
239 }
240
241 typedef 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
247 static walk_rc_t
248 send_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
268 static void
269 vl_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
284 #define vl_msg_name_crc_list
285 #include <vnet/qos/qos.api.h>
286 #undef vl_msg_name_crc_list
287
288 static void
289 setup_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
296 static clib_error_t *
297 qos_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
319 VLIB_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  */