udp: fix csum computation when offload disabled
[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_store.h>
24 #include <vnet/qos/qos_mark.h>
25 #include <vnet/qos/qos_egress_map.h>
26
27 #include <vnet/format_fns.h>
28 #include <vnet/qos/qos.api_enum.h>
29 #include <vnet/qos/qos.api_types.h>
30
31 #define REPLY_MSG_ID_BASE msg_id_base
32 #include <vlibapi/api_helper_macros.h>
33
34 static u16 msg_id_base;
35
36 static int
37 qos_source_decode (vl_api_qos_source_t v, qos_source_t * q)
38 {
39   switch (v)
40     {
41     case QOS_API_SOURCE_EXT:
42       *q = QOS_SOURCE_EXT;
43       return 0;
44     case QOS_API_SOURCE_VLAN:
45       *q = QOS_SOURCE_VLAN;
46       return 0;
47     case QOS_API_SOURCE_MPLS:
48       *q = QOS_SOURCE_MPLS;
49       return 0;
50     case QOS_API_SOURCE_IP:
51       *q = QOS_SOURCE_IP;
52       return 0;
53     }
54
55   return (VNET_API_ERROR_INVALID_VALUE);
56 }
57
58 static vl_api_qos_source_t
59 qos_source_encode (qos_source_t q)
60 {
61   return ((vl_api_qos_source_t) q);
62 }
63
64 void
65 vl_api_qos_record_enable_disable_t_handler (vl_api_qos_record_enable_disable_t
66                                             * mp)
67 {
68   vl_api_qos_record_enable_disable_reply_t *rmp;
69   qos_source_t qs;
70   int rv = 0;
71
72   VALIDATE_SW_IF_INDEX (&(mp->record));
73
74   rv = qos_source_decode (mp->record.input_source, &qs);
75
76   if (0 == rv)
77     {
78       if (mp->enable)
79         rv = qos_record_enable (ntohl (mp->record.sw_if_index), qs);
80       else
81         rv = qos_record_disable (ntohl (mp->record.sw_if_index), qs);
82     }
83
84   BAD_SW_IF_INDEX_LABEL;
85   REPLY_MACRO (VL_API_QOS_RECORD_ENABLE_DISABLE_REPLY);
86 }
87
88 typedef struct qos_record_send_walk_ctx_t_
89 {
90   vl_api_registration_t *reg;
91   u32 context;
92 } qos_record_send_walk_ctx_t;
93
94 static walk_rc_t
95 send_qos_record_details (u32 sw_if_index, qos_source_t input_source, void *c)
96 {
97   qos_record_send_walk_ctx_t *ctx;
98   vl_api_qos_record_details_t *mp;
99
100   ctx = c;
101   mp = vl_msg_api_alloc_zero (sizeof (*mp));
102
103   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_RECORD_DETAILS);
104   mp->context = ctx->context;
105   mp->record.sw_if_index = htonl (sw_if_index);
106   mp->record.input_source = qos_source_encode (input_source);
107
108   vl_api_send_msg (ctx->reg, (u8 *) mp);
109
110   return (WALK_CONTINUE);
111 }
112
113 static void
114 vl_api_qos_record_dump_t_handler (vl_api_qos_record_dump_t * mp)
115 {
116   vl_api_registration_t *reg;
117
118   reg = vl_api_client_index_to_registration (mp->client_index);
119   if (!reg)
120     return;
121
122   qos_record_send_walk_ctx_t ctx = {
123     .reg = reg,
124     .context = mp->context,
125   };
126   qos_record_walk (send_qos_record_details, &ctx);
127 }
128
129 void
130 vl_api_qos_store_enable_disable_t_handler (vl_api_qos_store_enable_disable_t
131                                            * mp)
132 {
133   vl_api_qos_store_enable_disable_reply_t *rmp;
134   qos_source_t qs;
135   int rv = 0;
136
137   VALIDATE_SW_IF_INDEX (&(mp->store));
138
139   rv = qos_source_decode (mp->store.input_source, &qs);
140
141   if (0 == rv)
142     {
143       if (mp->enable)
144         rv = qos_store_enable (ntohl (mp->store.sw_if_index), qs,
145                                mp->store.value);
146       else
147         rv = qos_store_disable (ntohl (mp->store.sw_if_index), qs);
148     }
149
150   BAD_SW_IF_INDEX_LABEL;
151   REPLY_MACRO (VL_API_QOS_STORE_ENABLE_DISABLE_REPLY);
152 }
153
154 typedef struct qos_store_send_walk_ctx_t_
155 {
156   vl_api_registration_t *reg;
157   u32 context;
158 } qos_store_send_walk_ctx_t;
159
160 static walk_rc_t
161 send_qos_store_details (u32 sw_if_index,
162                         qos_source_t input_source, qos_bits_t value, void *c)
163 {
164   qos_store_send_walk_ctx_t *ctx;
165   vl_api_qos_store_details_t *mp;
166
167   ctx = c;
168   mp = vl_msg_api_alloc_zero (sizeof (*mp));
169
170   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_STORE_DETAILS);
171   mp->context = ctx->context;
172   mp->store.sw_if_index = htonl (sw_if_index);
173   mp->store.input_source = qos_source_encode (input_source);
174   mp->store.value = value;
175
176   vl_api_send_msg (ctx->reg, (u8 *) mp);
177
178   return (WALK_CONTINUE);
179 }
180
181 static void
182 vl_api_qos_store_dump_t_handler (vl_api_qos_store_dump_t * mp)
183 {
184   vl_api_registration_t *reg;
185
186   reg = vl_api_client_index_to_registration (mp->client_index);
187   if (!reg)
188     return;
189
190   qos_store_send_walk_ctx_t ctx = {
191     .reg = reg,
192     .context = mp->context,
193   };
194   qos_store_walk (send_qos_store_details, &ctx);
195 }
196
197 void
198 vl_api_qos_egress_map_update_t_handler (vl_api_qos_egress_map_update_t * mp)
199 {
200   vl_api_qos_egress_map_update_reply_t *rmp;
201   qos_source_t qs;
202   int rv = 0;
203
204   FOR_EACH_QOS_SOURCE (qs)
205   {
206     qos_egress_map_update (ntohl (mp->map.id), qs,
207                            &mp->map.rows[qs].outputs[0]);
208   }
209
210   REPLY_MACRO (VL_API_QOS_EGRESS_MAP_UPDATE_REPLY);
211 }
212
213 void
214 vl_api_qos_egress_map_delete_t_handler (vl_api_qos_egress_map_delete_t * mp)
215 {
216   vl_api_qos_egress_map_delete_reply_t *rmp;
217   int rv = 0;
218
219   qos_egress_map_delete (ntohl (mp->id));
220
221   REPLY_MACRO (VL_API_QOS_EGRESS_MAP_DELETE_REPLY);
222 }
223
224 typedef struct qos_egress_map_send_walk_ctx_t_
225 {
226   vl_api_registration_t *reg;
227   u32 context;
228 } qos_egress_map_send_walk_ctx_t;
229
230 static walk_rc_t
231 send_qos_egress_map_details (qos_egress_map_id_t id,
232                              const qos_egress_map_t * m, void *c)
233 {
234   qos_egress_map_send_walk_ctx_t *ctx;
235   vl_api_qos_egress_map_details_t *mp;
236   u8 ii;
237
238   ctx = c;
239   mp = vl_msg_api_alloc_zero (sizeof (*mp));
240
241   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_EGRESS_MAP_DETAILS);
242   mp->context = ctx->context;
243   mp->map.id = htonl (id);
244
245   for (ii = 0; ii < 4; ii++)
246     clib_memcpy (mp->map.rows[ii].outputs, m->qem_output[ii], 256);
247
248   vl_api_send_msg (ctx->reg, (u8 *) mp);
249
250   return (WALK_CONTINUE);
251 }
252
253 static void
254 vl_api_qos_egress_map_dump_t_handler (vl_api_qos_egress_map_dump_t * mp)
255 {
256   vl_api_registration_t *reg;
257
258   reg = vl_api_client_index_to_registration (mp->client_index);
259   if (!reg)
260     return;
261
262   qos_egress_map_send_walk_ctx_t ctx = {
263     .reg = reg,
264     .context = mp->context,
265   };
266   qos_egress_map_walk (send_qos_egress_map_details, &ctx);
267 }
268
269 void
270 vl_api_qos_mark_enable_disable_t_handler (vl_api_qos_mark_enable_disable_t *
271                                           mp)
272 {
273   vl_api_qos_mark_enable_disable_reply_t *rmp;
274   qos_source_t qs;
275   int rv = 0;
276
277   rv = qos_source_decode (mp->mark.output_source, &qs);
278
279   if (0 == rv)
280     {
281       if (mp->enable)
282         rv = qos_mark_enable (ntohl (mp->mark.sw_if_index),
283                               qs, ntohl (mp->mark.map_id));
284       else
285         rv = qos_mark_disable (ntohl (mp->mark.sw_if_index), qs);
286     }
287
288   REPLY_MACRO (VL_API_QOS_MARK_ENABLE_DISABLE_REPLY);
289 }
290
291 typedef struct qos_mark_send_walk_ctx_t_
292 {
293   vl_api_registration_t *reg;
294   u32 context;
295 } qos_mark_send_walk_ctx_t;
296
297 static walk_rc_t
298 send_qos_mark_details (u32 sw_if_index,
299                        u32 map_id, qos_source_t output_source, void *c)
300 {
301   qos_mark_send_walk_ctx_t *ctx;
302   vl_api_qos_mark_details_t *mp;
303
304   ctx = c;
305   mp = vl_msg_api_alloc_zero (sizeof (*mp));
306
307   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_MARK_DETAILS);
308   mp->context = ctx->context;
309   mp->mark.sw_if_index = htonl (sw_if_index);
310   mp->mark.output_source = qos_source_encode (output_source);
311   mp->mark.map_id = htonl (map_id);
312
313   vl_api_send_msg (ctx->reg, (u8 *) mp);
314
315   return (WALK_CONTINUE);
316 }
317
318 static void
319 vl_api_qos_mark_dump_t_handler (vl_api_qos_mark_dump_t * mp)
320 {
321   vl_api_registration_t *reg;
322
323   reg = vl_api_client_index_to_registration (mp->client_index);
324   if (!reg)
325     return;
326
327   qos_mark_send_walk_ctx_t ctx = {
328     .reg = reg,
329     .context = mp->context,
330   };
331   qos_mark_walk (send_qos_mark_details, &ctx);
332 }
333
334 #include <vnet/qos/qos.api.c>
335
336 static clib_error_t *
337 qos_api_hookup (vlib_main_t * vm)
338 {
339   /*
340    * Set up the (msg_name, crc, message-id) table
341    */
342   REPLY_MSG_ID_BASE = setup_message_id_table ();
343
344   return 0;
345 }
346
347 VLIB_API_INIT_FUNCTION (qos_api_hookup);
348
349 /*
350  * fd.io coding-style-patch-verification: ON
351  *
352  * Local Variables:
353  * eval: (c-set-style "gnu")
354  * End:
355  */