Line data Source code
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 30 : qos_source_decode (vl_api_qos_source_t v, qos_source_t * q)
38 : {
39 30 : switch (v)
40 : {
41 0 : case QOS_API_SOURCE_EXT:
42 0 : *q = QOS_SOURCE_EXT;
43 0 : return 0;
44 6 : case QOS_API_SOURCE_VLAN:
45 6 : *q = QOS_SOURCE_VLAN;
46 6 : return 0;
47 4 : case QOS_API_SOURCE_MPLS:
48 4 : *q = QOS_SOURCE_MPLS;
49 4 : return 0;
50 20 : case QOS_API_SOURCE_IP:
51 20 : *q = QOS_SOURCE_IP;
52 20 : return 0;
53 : }
54 :
55 0 : return (VNET_API_ERROR_INVALID_VALUE);
56 : }
57 :
58 : static vl_api_qos_source_t
59 25 : qos_source_encode (qos_source_t q)
60 : {
61 25 : return ((vl_api_qos_source_t) q);
62 : }
63 :
64 : void
65 10 : 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 10 : int rv = 0;
71 :
72 10 : VALIDATE_SW_IF_INDEX (&(mp->record));
73 :
74 10 : rv = qos_source_decode (mp->record.input_source, &qs);
75 :
76 10 : if (0 == rv)
77 : {
78 10 : if (mp->enable)
79 5 : rv = qos_record_enable (ntohl (mp->record.sw_if_index), qs);
80 : else
81 5 : rv = qos_record_disable (ntohl (mp->record.sw_if_index), qs);
82 : }
83 :
84 0 : BAD_SW_IF_INDEX_LABEL;
85 10 : 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 9 : 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 9 : ctx = c;
101 9 : mp = vl_msg_api_alloc_zero (sizeof (*mp));
102 :
103 9 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_RECORD_DETAILS);
104 9 : mp->context = ctx->context;
105 9 : mp->record.sw_if_index = htonl (sw_if_index);
106 9 : mp->record.input_source = qos_source_encode (input_source);
107 :
108 9 : vl_api_send_msg (ctx->reg, (u8 *) mp);
109 :
110 9 : return (WALK_CONTINUE);
111 : }
112 :
113 : static void
114 10 : vl_api_qos_record_dump_t_handler (vl_api_qos_record_dump_t * mp)
115 : {
116 : vl_api_registration_t *reg;
117 :
118 10 : reg = vl_api_client_index_to_registration (mp->client_index);
119 10 : if (!reg)
120 0 : return;
121 :
122 10 : qos_record_send_walk_ctx_t ctx = {
123 : .reg = reg,
124 10 : .context = mp->context,
125 : };
126 10 : qos_record_walk (send_qos_record_details, &ctx);
127 : }
128 :
129 : void
130 2 : 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 2 : int rv = 0;
136 :
137 2 : VALIDATE_SW_IF_INDEX (&(mp->store));
138 :
139 2 : rv = qos_source_decode (mp->store.input_source, &qs);
140 :
141 2 : if (0 == rv)
142 : {
143 2 : if (mp->enable)
144 1 : rv = qos_store_enable (ntohl (mp->store.sw_if_index), qs,
145 1 : mp->store.value);
146 : else
147 1 : rv = qos_store_disable (ntohl (mp->store.sw_if_index), qs);
148 : }
149 :
150 0 : BAD_SW_IF_INDEX_LABEL;
151 2 : 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 1 : 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 1 : ctx = c;
168 1 : mp = vl_msg_api_alloc_zero (sizeof (*mp));
169 :
170 1 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_STORE_DETAILS);
171 1 : mp->context = ctx->context;
172 1 : mp->store.sw_if_index = htonl (sw_if_index);
173 1 : mp->store.input_source = qos_source_encode (input_source);
174 1 : mp->store.value = value;
175 :
176 1 : vl_api_send_msg (ctx->reg, (u8 *) mp);
177 :
178 1 : return (WALK_CONTINUE);
179 : }
180 :
181 : static void
182 2 : vl_api_qos_store_dump_t_handler (vl_api_qos_store_dump_t * mp)
183 : {
184 : vl_api_registration_t *reg;
185 :
186 2 : reg = vl_api_client_index_to_registration (mp->client_index);
187 2 : if (!reg)
188 0 : return;
189 :
190 2 : qos_store_send_walk_ctx_t ctx = {
191 : .reg = reg,
192 2 : .context = mp->context,
193 : };
194 2 : qos_store_walk (send_qos_store_details, &ctx);
195 : }
196 :
197 : void
198 10 : 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 10 : int rv = 0;
203 :
204 50 : FOR_EACH_QOS_SOURCE (qs)
205 : {
206 40 : qos_egress_map_update (ntohl (mp->map.id), qs,
207 40 : &mp->map.rows[qs].outputs[0]);
208 : }
209 :
210 10 : REPLY_MACRO (VL_API_QOS_EGRESS_MAP_UPDATE_REPLY);
211 : }
212 :
213 : void
214 10 : 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 10 : int rv = 0;
218 :
219 10 : qos_egress_map_delete (ntohl (mp->id));
220 :
221 10 : 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 59 : 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 59 : ctx = c;
239 59 : mp = vl_msg_api_alloc_zero (sizeof (*mp));
240 :
241 59 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_EGRESS_MAP_DETAILS);
242 59 : mp->context = ctx->context;
243 59 : mp->map.id = htonl (id);
244 :
245 295 : for (ii = 0; ii < 4; ii++)
246 236 : clib_memcpy (mp->map.rows[ii].outputs, m->qem_output[ii], 256);
247 :
248 59 : vl_api_send_msg (ctx->reg, (u8 *) mp);
249 :
250 59 : return (WALK_CONTINUE);
251 : }
252 :
253 : static void
254 21 : 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 21 : reg = vl_api_client_index_to_registration (mp->client_index);
259 21 : if (!reg)
260 0 : return;
261 :
262 21 : qos_egress_map_send_walk_ctx_t ctx = {
263 : .reg = reg,
264 21 : .context = mp->context,
265 : };
266 21 : qos_egress_map_walk (send_qos_egress_map_details, &ctx);
267 : }
268 :
269 : void
270 18 : 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 18 : int rv = 0;
276 :
277 18 : rv = qos_source_decode (mp->mark.output_source, &qs);
278 :
279 18 : if (0 == rv)
280 : {
281 18 : if (mp->enable)
282 9 : rv = qos_mark_enable (ntohl (mp->mark.sw_if_index),
283 : qs, ntohl (mp->mark.map_id));
284 : else
285 9 : rv = qos_mark_disable (ntohl (mp->mark.sw_if_index), qs);
286 : }
287 :
288 18 : 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 15 : 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 15 : ctx = c;
305 15 : mp = vl_msg_api_alloc_zero (sizeof (*mp));
306 :
307 15 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_QOS_MARK_DETAILS);
308 15 : mp->context = ctx->context;
309 15 : mp->mark.sw_if_index = htonl (sw_if_index);
310 15 : mp->mark.output_source = qos_source_encode (output_source);
311 15 : mp->mark.map_id = htonl (map_id);
312 :
313 15 : vl_api_send_msg (ctx->reg, (u8 *) mp);
314 :
315 15 : return (WALK_CONTINUE);
316 : }
317 :
318 : static void
319 16 : vl_api_qos_mark_dump_t_handler (vl_api_qos_mark_dump_t * mp)
320 : {
321 : vl_api_registration_t *reg;
322 :
323 16 : reg = vl_api_client_index_to_registration (mp->client_index);
324 16 : if (!reg)
325 0 : return;
326 :
327 16 : qos_mark_send_walk_ctx_t ctx = {
328 : .reg = reg,
329 16 : .context = mp->context,
330 : };
331 16 : qos_mark_walk (send_qos_mark_details, &ctx);
332 : }
333 :
334 : #include <vnet/qos/qos.api.c>
335 :
336 : static clib_error_t *
337 575 : qos_api_hookup (vlib_main_t * vm)
338 : {
339 : /*
340 : * Set up the (msg_name, crc, message-id) table
341 : */
342 575 : REPLY_MSG_ID_BASE = setup_message_id_table ();
343 :
344 575 : return 0;
345 : }
346 :
347 19007 : 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 : */
|