blob: 6b5b37ae7464c10a09151bce55b692766d6bc15f [file] [log] [blame]
Dave Barachaff70772016-10-31 11:59:07 -04001/*
2 *------------------------------------------------------------------
3 * api_helper_macros.h - message handler helper macros
4 *
5 * Copyright (c) 2016 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
Dave Barachaff70772016-10-31 11:59:07 -040020#ifndef __api_helper_macros_h__
21#define __api_helper_macros_h__
22
23#define f64_endian(a)
24#define f64_print(a,b)
25
Eyal Bari0856b972017-03-15 14:54:19 +020026#ifndef REPLY_MSG_ID_BASE
27#define REPLY_MSG_ID_BASE 0
28#endif
29
Mohsin Kazmi342a5d42021-11-29 13:00:04 +010030#define _NATIVE_TO_NETWORK(t, rmp) \
31 api_main_t *am = vlibapi_get_main (); \
32 void (*endian_fp) (void *); \
33 endian_fp = am->msg_endian_handlers[t + (REPLY_MSG_ID_BASE)]; \
34 (*endian_fp) (rmp);
35
Klement Sekera0eb83f42021-12-02 16:36:34 +000036#define REPLY_MACRO(msg) \
37 do \
38 { \
39 STATIC_ASSERT ( \
40 msg##_IS_CONSTANT_SIZE, \
41 "REPLY_MACRO can only be used with constant size messages, " \
42 "use REPLY_MACRO[3|4]* instead"); \
43 vl_api_registration_t *rp; \
44 rp = vl_api_client_index_to_registration (mp->client_index); \
45 if (rp == 0) \
46 return; \
47 \
48 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
49 rmp->_vl_msg_id = htons (msg + (REPLY_MSG_ID_BASE)); \
50 rmp->context = mp->context; \
51 rmp->retval = ntohl (rv); \
52 \
53 vl_api_send_msg (rp, (u8 *) rmp); \
54 } \
55 while (0);
Dave Barachaff70772016-10-31 11:59:07 -040056
Mohsin Kazmi342a5d42021-11-29 13:00:04 +010057#define REPLY_MACRO_END(t) \
58 do \
59 { \
60 vl_api_registration_t *rp; \
61 rp = vl_api_client_index_to_registration (mp->client_index); \
62 if (rp == 0) \
63 return; \
64 \
65 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
66 rmp->_vl_msg_id = t + (REPLY_MSG_ID_BASE); \
67 rmp->context = mp->context; \
68 rmp->retval = rv; \
69 _NATIVE_TO_NETWORK (t, rmp); \
70 vl_api_send_msg (rp, (u8 *) rmp); \
71 } \
72 while (0);
Ole Troanbad67922020-08-24 12:22:01 +020073
Klement Sekera0eb83f42021-12-02 16:36:34 +000074#define REPLY_MACRO2(t, body) \
75 do \
76 { \
77 STATIC_ASSERT ( \
78 t##_IS_CONSTANT_SIZE, \
79 "REPLY_MACRO2 can only be used with constant size messages, " \
80 "use REPLY_MACRO[3|4]* instead"); \
81 vl_api_registration_t *rp; \
82 rp = vl_api_client_index_to_registration (mp->client_index); \
83 if (rp == 0) \
84 return; \
85 \
86 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
87 rmp->_vl_msg_id = htons ((t) + (REPLY_MSG_ID_BASE)); \
88 rmp->context = mp->context; \
89 rmp->retval = ntohl (rv); \
90 do \
91 { \
92 body; \
93 } \
94 while (0); \
95 vl_api_send_msg (rp, (u8 *) rmp); \
96 } \
97 while (0);
Dave Barachaff70772016-10-31 11:59:07 -040098
Mohsin Kazmi342a5d42021-11-29 13:00:04 +010099#define REPLY_MACRO2_END(t, body) \
100 do \
101 { \
102 vl_api_registration_t *rp; \
103 rp = vl_api_client_index_to_registration (mp->client_index); \
104 if (rp == 0) \
105 return; \
106 \
107 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
108 rmp->_vl_msg_id = t + (REPLY_MSG_ID_BASE); \
109 rmp->context = mp->context; \
110 rmp->retval = rv; \
111 do \
112 { \
113 body; \
114 } \
115 while (0); \
116 _NATIVE_TO_NETWORK (t, rmp); \
117 vl_api_send_msg (rp, (u8 *) rmp); \
118 } \
119 while (0);
Ole Troane796a182020-05-18 11:14:05 +0200120
Paul Vinciguerraf24de172020-01-27 18:42:25 -0500121#define REPLY_MACRO2_ZERO(t, body) \
122do { \
123 vl_api_registration_t *rp; \
Paul Vinciguerraf24de172020-01-27 18:42:25 -0500124 rp = vl_api_client_index_to_registration (mp->client_index); \
125 if (rp == 0) \
126 return; \
127 \
128 rmp = vl_msg_api_alloc_zero (sizeof (*rmp)); \
129 rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
130 rmp->context = mp->context; \
131 rmp->retval = ntohl(rv); \
132 do {body;} while (0); \
133 vl_api_send_msg (rp, (u8 *)rmp); \
134} while(0);
135
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100136#define REPLY_MACRO2_ZERO_END(t, body) \
137 do \
138 { \
139 vl_api_registration_t *rp; \
140 rp = vl_api_client_index_to_registration (mp->client_index); \
141 if (rp == 0) \
142 return; \
143 \
144 rmp = vl_msg_api_alloc_zero (sizeof (*rmp)); \
145 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
146 rmp->context = mp->context; \
147 rmp->retval = rv; \
148 do \
149 { \
150 body; \
151 } \
152 while (0); \
153 _NATIVE_TO_NETWORK (t, rmp); \
154 vl_api_send_msg (rp, (u8 *) rmp); \
155 } \
156 while (0);
157
Ole Troan2a1ca782019-09-19 01:08:30 +0200158#define REPLY_MACRO_DETAILS2(t, body) \
159do { \
160 vl_api_registration_t *rp; \
Ole Troan2a1ca782019-09-19 01:08:30 +0200161 rp = vl_api_client_index_to_registration (mp->client_index); \
162 if (rp == 0) \
163 return; \
164 \
165 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
166 rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
167 rmp->context = mp->context; \
168 do {body;} while (0); \
169 vl_api_send_msg (rp, (u8 *)rmp); \
170} while(0);
171
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100172#define REPLY_MACRO_DETAILS2_END(t, body) \
173 do \
174 { \
175 vl_api_registration_t *rp; \
176 rp = vl_api_client_index_to_registration (mp->client_index); \
177 if (rp == 0) \
178 return; \
179 \
180 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
181 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
182 rmp->context = mp->context; \
183 do \
184 { \
185 body; \
186 } \
187 while (0); \
188 _NATIVE_TO_NETWORK (t, rmp); \
189 vl_api_send_msg (rp, (u8 *) rmp); \
190 } \
191 while (0);
192
Ole Troanf5db3712020-05-20 15:47:06 +0200193#define REPLY_MACRO_DETAILS4(t, rp, context, body) \
194do { \
195 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
196 rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
197 rmp->context = context; \
198 do {body;} while (0); \
199 vl_api_send_msg (rp, (u8 *)rmp); \
200} while(0);
201
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100202#define REPLY_MACRO_DETAILS4_END(t, rp, context, body) \
203 do \
204 { \
205 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
206 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
207 rmp->context = context; \
208 do \
209 { \
210 body; \
211 } \
212 while (0); \
213 _NATIVE_TO_NETWORK (t, rmp); \
214 vl_api_send_msg (rp, (u8 *) rmp); \
215 } \
216 while (0);
217
218#define REPLY_MACRO_DETAILS5(t, n, rp, context, body) \
219 do \
220 { \
221 rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
222 rmp->_vl_msg_id = htons ((t) + (REPLY_MSG_ID_BASE)); \
223 rmp->context = context; \
224 do \
225 { \
226 body; \
227 } \
228 while (0); \
229 vl_api_send_msg (rp, (u8 *) rmp); \
230 } \
231 while (0);
232
233#define REPLY_MACRO_DETAILS5_END(t, n, rp, context, body) \
234 do \
235 { \
236 rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
237 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
238 rmp->context = context; \
239 do \
240 { \
241 body; \
242 } \
243 while (0); \
244 _NATIVE_TO_NETWORK (t, rmp); \
245 vl_api_send_msg (rp, (u8 *) rmp); \
246 } \
247 while (0);
248
Klement Sekera0eb83f42021-12-02 16:36:34 +0000249#define REPLY_MACRO3(t, n, body) \
250 do \
251 { \
252 vl_api_registration_t *rp; \
253 rp = vl_api_client_index_to_registration (mp->client_index); \
254 if (rp == 0) \
255 return; \
256 \
257 rmp = vl_msg_api_alloc (sizeof (*rmp) + (n)); \
258 rmp->_vl_msg_id = htons ((t) + (REPLY_MSG_ID_BASE)); \
259 rmp->context = mp->context; \
260 rmp->retval = ntohl (rv); \
261 do \
262 { \
263 body; \
264 } \
265 while (0); \
266 vl_api_send_msg (rp, (u8 *) rmp); \
267 } \
268 while (0);
Dave Barachaff70772016-10-31 11:59:07 -0400269
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100270#define REPLY_MACRO3_END(t, n, body) \
271 do \
272 { \
273 vl_api_registration_t *rp; \
274 rp = vl_api_client_index_to_registration (mp->client_index); \
275 if (rp == 0) \
276 return; \
277 \
278 rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
279 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
280 rmp->context = mp->context; \
281 rmp->retval = rv; \
282 do \
283 { \
284 body; \
285 } \
286 while (0); \
287 _NATIVE_TO_NETWORK (t, rmp); \
288 vl_api_send_msg (rp, (u8 *) rmp); \
289 } \
290 while (0);
291
Paul Vinciguerraf24de172020-01-27 18:42:25 -0500292#define REPLY_MACRO3_ZERO(t, n, body) \
293do { \
294 vl_api_registration_t *rp; \
Paul Vinciguerraf24de172020-01-27 18:42:25 -0500295 rp = vl_api_client_index_to_registration (mp->client_index); \
296 if (rp == 0) \
297 return; \
298 \
299 rmp = vl_msg_api_alloc_zero (sizeof (*rmp) + n); \
300 rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
301 rmp->context = mp->context; \
302 rmp->retval = ntohl(rv); \
303 do {body;} while (0); \
304 vl_api_send_msg (rp, (u8 *)rmp); \
305} while(0);
306
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100307#define REPLY_MACRO3_ZERO_END(t, n, body) \
308 do \
309 { \
310 vl_api_registration_t *rp; \
311 rp = vl_api_client_index_to_registration (mp->client_index); \
312 if (rp == 0) \
313 return; \
314 \
315 rmp = vl_msg_api_alloc_zero (sizeof (*rmp) + n); \
316 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
317 rmp->context = mp->context; \
318 rmp->retval = rv; \
319 do \
320 { \
321 body; \
322 } \
323 while (0); \
324 _NATIVE_TO_NETWORK (t, rmp); \
325 vl_api_send_msg (rp, (u8 *) rmp); \
326 } \
327 while (0);
328
Dave Barach59b25652017-09-10 15:04:27 -0400329#define REPLY_MACRO4(t, n, body) \
330do { \
331 vl_api_registration_t *rp; \
332 u8 is_error = 0; \
Dave Barach59b25652017-09-10 15:04:27 -0400333 \
334 rp = vl_api_client_index_to_registration (mp->client_index); \
335 if (rp == 0) \
336 return; \
337 \
338 rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n); \
339 if (!rmp) \
340 { \
341 /* if there isn't enough memory, try to allocate */ \
342 /* some at least for returning an error */ \
343 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
344 if (!rmp) \
345 return; \
346 \
Dave Barachb7b92992018-10-17 10:38:51 -0400347 clib_memset (rmp, 0, sizeof (*rmp)); \
Dave Barach59b25652017-09-10 15:04:27 -0400348 rv = VNET_API_ERROR_TABLE_TOO_BIG; \
349 is_error = 1; \
350 } \
351 rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
352 rmp->context = mp->context; \
353 rmp->retval = ntohl(rv); \
354 if (!is_error) \
355 do {body;} while (0); \
Florin Corase86a8ed2018-01-05 03:20:25 -0800356 vl_api_send_msg (rp, (u8 *)rmp); \
Dave Barachaff70772016-10-31 11:59:07 -0400357} while(0);
358
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100359#define REPLY_MACRO4_END(t, n, body) \
360 do \
361 { \
362 vl_api_registration_t *rp; \
363 u8 is_error = 0; \
364 \
365 rp = vl_api_client_index_to_registration (mp->client_index); \
366 if (rp == 0) \
367 return; \
368 \
369 rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n); \
370 if (!rmp) \
371 { \
372 /* if there isn't enough memory, try to allocate */ \
373 /* some at least for returning an error */ \
374 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
375 if (!rmp) \
376 return; \
377 \
378 clib_memset (rmp, 0, sizeof (*rmp)); \
379 rv = VNET_API_ERROR_TABLE_TOO_BIG; \
380 is_error = 1; \
381 } \
382 rmp->_vl_msg_id = ((t) + (REPLY_MSG_ID_BASE)); \
383 rmp->context = mp->context; \
384 rmp->retval = rv; \
385 if (!is_error) \
386 do \
387 { \
388 body; \
389 } \
390 while (0); \
391 _NATIVE_TO_NETWORK (t, rmp); \
392 vl_api_send_msg (rp, (u8 *) rmp); \
393 } \
394 while (0);
395
Neale Ranns44db1ca2020-12-24 09:16:09 +0000396#define REPLY_AND_DETAILS_MACRO(t, p, body) \
397 do \
398 { \
399 if (pool_elts (p) == 0) \
400 { \
401 REPLY_MACRO (t); \
402 break; \
403 } \
404 vl_api_registration_t *rp; \
405 rp = vl_api_client_index_to_registration (mp->client_index); \
406 if (rp == 0) \
407 return; \
408 u32 cursor = clib_net_to_host_u32 (mp->cursor); \
409 vlib_main_t *vm = vlib_get_main (); \
410 f64 start = vlib_time_now (vm); \
411 if (pool_is_free_index (p, cursor)) \
412 { \
413 cursor = pool_next_index (p, cursor); \
414 if (cursor == ~0) \
415 rv = VNET_API_ERROR_INVALID_VALUE; \
416 } \
417 while (cursor != ~0) \
418 { \
419 do \
420 { \
421 body; \
422 } \
423 while (0); \
424 cursor = pool_next_index (p, cursor); \
425 if (vl_api_process_may_suspend (vm, rp, start)) \
426 { \
427 if (cursor != ~0) \
428 rv = VNET_API_ERROR_EAGAIN; \
429 break; \
430 } \
431 } \
432 REPLY_MACRO2 (t, ({ rmp->cursor = clib_host_to_net_u32 (cursor); })); \
433 } \
434 while (0);
Ole Troanf5db3712020-05-20 15:47:06 +0200435
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100436#define REPLY_AND_DETAILS_MACRO_END(t, p, body) \
437 do \
438 { \
439 if (pool_elts (p) == 0) \
440 { \
441 REPLY_MACRO_END (t); \
442 break; \
443 } \
444 vl_api_registration_t *rp; \
445 rp = vl_api_client_index_to_registration (mp->client_index); \
446 if (rp == 0) \
447 return; \
448 u32 cursor = mp->cursor; \
449 vlib_main_t *vm = vlib_get_main (); \
450 f64 start = vlib_time_now (vm); \
451 if (pool_is_free_index (p, cursor)) \
452 { \
453 cursor = pool_next_index (p, cursor); \
454 if (cursor == ~0) \
455 rv = VNET_API_ERROR_INVALID_VALUE; \
456 } \
457 while (cursor != ~0) \
458 { \
459 do \
460 { \
461 body; \
462 } \
463 while (0); \
464 cursor = pool_next_index (p, cursor); \
465 if (vl_api_process_may_suspend (vm, rp, start)) \
466 { \
467 if (cursor != ~0) \
468 rv = VNET_API_ERROR_EAGAIN; \
469 break; \
470 } \
471 } \
472 REPLY_MACRO2_END (t, ({ rmp->cursor = cursor; })); \
473 } \
474 while (0);
475
Jon Loeligerc0b19542020-05-11 08:43:51 -0500476#define REPLY_AND_DETAILS_VEC_MACRO(t, v, mp, rmp, rv, body) \
477do { \
478 vl_api_registration_t *rp; \
479 rp = vl_api_client_index_to_registration (mp->client_index); \
480 if (rp == 0) \
481 return; \
482 u32 cursor = clib_net_to_host_u32 (mp->cursor); \
483 vlib_main_t *vm = vlib_get_main (); \
484 f64 start = vlib_time_now (vm); \
485 if (!v || vec_len (v) == 0) { \
486 cursor = ~0; \
487 rv = VNET_API_ERROR_INVALID_VALUE; \
488 } else if (cursor == ~0) \
489 cursor = 0; \
490 while (cursor != ~0 && cursor < vec_len (v)) { \
491 do {body;} while (0); \
492 ++cursor; \
493 if (vl_api_process_may_suspend (vm, rp, start)) { \
494 if (cursor < vec_len (v)) \
495 rv = VNET_API_ERROR_EAGAIN; \
496 break; \
497 } \
498 } \
499 REPLY_MACRO2 (t, ({ \
500 rmp->cursor = clib_host_to_net_u32 (cursor); \
501 })); \
502} while(0);
503
Mohsin Kazmi342a5d42021-11-29 13:00:04 +0100504#define REPLY_AND_DETAILS_VEC_MACRO_END(t, v, mp, rmp, rv, body) \
505 do \
506 { \
507 vl_api_registration_t *rp; \
508 rp = vl_api_client_index_to_registration (mp->client_index); \
509 if (rp == 0) \
510 return; \
511 u32 cursor = mp->cursor; \
512 vlib_main_t *vm = vlib_get_main (); \
513 f64 start = vlib_time_now (vm); \
514 if (!v || vec_len (v) == 0) \
515 { \
516 cursor = ~0; \
517 rv = VNET_API_ERROR_INVALID_VALUE; \
518 } \
519 else if (cursor == ~0) \
520 cursor = 0; \
521 while (cursor != ~0 && cursor < vec_len (v)) \
522 { \
523 do \
524 { \
525 body; \
526 } \
527 while (0); \
528 ++cursor; \
529 if (vl_api_process_may_suspend (vm, rp, start)) \
530 { \
531 if (cursor < vec_len (v)) \
532 rv = VNET_API_ERROR_EAGAIN; \
533 break; \
534 } \
535 } \
536 REPLY_MACRO2_END (t, ({ rmp->cursor = cursor; })); \
537 } \
538 while (0);
Jon Loeligerc0b19542020-05-11 08:43:51 -0500539
Dave Barachaff70772016-10-31 11:59:07 -0400540/* "trust, but verify" */
Florin Coras248210c2021-09-14 18:54:45 -0700541#define vnet_sw_if_index_is_api_valid(sw_if_index) \
542 vnet_sw_interface_is_api_valid (vnet_get_main (), sw_if_index)
Eyal Bari1c82cd42017-03-14 14:39:51 +0200543
Dave Barachaff70772016-10-31 11:59:07 -0400544#define VALIDATE_SW_IF_INDEX(mp) \
Neale Ranns947ea622018-06-07 23:48:20 -0700545 do { u32 __sw_if_index = ntohl((mp)->sw_if_index); \
Eyal Bari1c82cd42017-03-14 14:39:51 +0200546 if (!vnet_sw_if_index_is_api_valid(__sw_if_index)) { \
Dave Barachaff70772016-10-31 11:59:07 -0400547 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
548 goto bad_sw_if_index; \
549 } \
550} while(0);
551
Mohsin Kazmia4abdac2021-11-25 16:02:24 +0100552#define VALIDATE_SW_IF_INDEX_END(mp) \
553 do \
554 { \
555 if (!vnet_sw_if_index_is_api_valid ((mp)->sw_if_index)) \
556 { \
557 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
558 goto bad_sw_if_index; \
559 } \
560 } \
561 while (0);
562
Dave Barachaff70772016-10-31 11:59:07 -0400563#define BAD_SW_IF_INDEX_LABEL \
564do { \
565bad_sw_if_index: \
566 ; \
567} while (0);
568
569#define VALIDATE_RX_SW_IF_INDEX(mp) \
Neale Ranns947ea622018-06-07 23:48:20 -0700570 do { u32 __rx_sw_if_index = ntohl((mp)->rx_sw_if_index); \
Eyal Bari1c82cd42017-03-14 14:39:51 +0200571 if (!vnet_sw_if_index_is_api_valid(__rx_sw_if_index)) { \
Dave Barachaff70772016-10-31 11:59:07 -0400572 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
573 goto bad_rx_sw_if_index; \
574 } \
575} while(0);
576
Mohsin Kazmia4abdac2021-11-25 16:02:24 +0100577#define VALIDATE_RX_SW_IF_INDEX_END(mp) \
578 do \
579 { \
580 if (!vnet_sw_if_index_is_api_valid ((mp)->rx_sw_if_index)) \
581 { \
582 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
583 goto bad_rx_sw_if_index; \
584 } \
585 } \
586 while (0);
587
Dave Barachaff70772016-10-31 11:59:07 -0400588#define BAD_RX_SW_IF_INDEX_LABEL \
589do { \
590bad_rx_sw_if_index: \
591 ; \
592} while (0);
593
594#define VALIDATE_TX_SW_IF_INDEX(mp) \
595 do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
Eyal Bari1c82cd42017-03-14 14:39:51 +0200596 if (!vnet_sw_if_index_is_api_valid(__tx_sw_if_index)) { \
Dave Barachaff70772016-10-31 11:59:07 -0400597 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
598 goto bad_tx_sw_if_index; \
599 } \
600} while(0);
601
Mohsin Kazmia4abdac2021-11-25 16:02:24 +0100602#define VALIDATE_TX_SW_IF_INDEX_END(mp) \
603 do \
604 { \
605 if (!vnet_sw_if_index_is_api_valid (mp->tx_sw_if_index)) \
606 { \
607 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
608 goto bad_tx_sw_if_index; \
609 } \
610 } \
611 while (0);
612
Dave Barachaff70772016-10-31 11:59:07 -0400613#define BAD_TX_SW_IF_INDEX_LABEL \
614do { \
615bad_tx_sw_if_index: \
616 ; \
617} while (0);
618
John Lo97934772017-05-18 22:26:47 -0400619#define VALIDATE_BD_ID(mp) \
620 do { u32 __rx_bd_id = ntohl(mp->bd_id); \
621 if (__rx_bd_id > L2_BD_ID_MAX) { \
622 rv = VNET_API_ERROR_BD_ID_EXCEED_MAX; \
623 goto bad_bd_id; \
624 } \
625} while(0);
626
Mohsin Kazmia4abdac2021-11-25 16:02:24 +0100627#define VALIDATE_BD_ID_END(mp) \
628 do \
629 { \
630 if (mp->bd_id > L2_BD_ID_MAX) \
631 { \
632 rv = VNET_API_ERROR_BD_ID_EXCEED_MAX; \
633 goto bad_bd_id; \
634 } \
635 } \
636 while (0);
637
John Lo97934772017-05-18 22:26:47 -0400638#define BAD_BD_ID_LABEL \
639do { \
640bad_bd_id: \
641 ; \
642} while (0);
643
Klement Sekera0eb83f42021-12-02 16:36:34 +0000644#define pub_sub_handler(lca, UCA) \
645 static void vl_api_want_##lca##_t_handler (vl_api_want_##lca##_t *mp) \
646 { \
647 vpe_api_main_t *vam = &vpe_api_main; \
648 vpe_client_registration_t *rp; \
649 vl_api_want_##lca##_reply_t *rmp; \
650 uword *p; \
651 i32 rv = 0; \
652 \
653 p = hash_get (vam->lca##_registration_hash, mp->client_index); \
654 if (p) \
655 { \
656 if (mp->enable_disable) \
657 { \
658 clib_warning ("pid %d: already enabled...", ntohl (mp->pid)); \
659 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
660 goto reply; \
661 } \
662 else \
663 { \
664 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
665 pool_put (vam->lca##_registrations, rp); \
666 hash_unset (vam->lca##_registration_hash, mp->client_index); \
667 goto reply; \
668 } \
669 } \
670 if (mp->enable_disable == 0) \
671 { \
672 clib_warning ("pid %d: already disabled...", mp->pid); \
673 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
674 goto reply; \
675 } \
676 pool_get (vam->lca##_registrations, rp); \
677 rp->client_index = mp->client_index; \
678 rp->client_pid = mp->pid; \
679 hash_set (vam->lca##_registration_hash, rp->client_index, \
680 rp - vam->lca##_registrations); \
681 \
682 reply: \
683 REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
684 } \
685 \
686 static clib_error_t *vl_api_want_##lca##_t_reaper (u32 client_index) \
687 { \
688 vpe_api_main_t *vam = &vpe_api_main; \
689 vpe_client_registration_t *rp; \
690 uword *p; \
691 \
692 p = hash_get (vam->lca##_registration_hash, client_index); \
693 if (p) \
694 { \
695 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
696 pool_put (vam->lca##_registrations, rp); \
697 hash_unset (vam->lca##_registration_hash, client_index); \
698 } \
699 return (NULL); \
700 } \
701 \
702 VL_MSG_API_REAPER_FUNCTION (vl_api_want_##lca##_t_reaper);
Dave Barach6d963c22016-12-05 09:50:05 -0500703
704#define foreach_registration_hash \
705_(interface_events) \
706_(to_netconf_server) \
707_(from_netconf_server) \
708_(to_netconf_client) \
709_(from_netconf_client) \
Klement Sekera0e3c0de2016-09-29 14:43:44 +0200710_(oam_events) \
Eyal Bari20197482017-09-13 12:29:08 +0300711_(bfd_events) \
Neale Rannscbe25aa2019-09-30 10:53:31 +0000712_(l2_arp_term_events) \
Juraj Sloboda81119e82018-05-25 14:02:20 +0200713_(ip6_ra_events) \
Juraj Slobodadd3b8f72018-05-04 14:20:06 +0200714_(dhcp6_pd_reply_events) \
Matthew Smith78f487e2020-10-08 11:11:27 -0500715_(dhcp6_reply_events) \
716_(vrrp_vr_events)
Dave Barach6d963c22016-12-05 09:50:05 -0500717
Dave Barach6d963c22016-12-05 09:50:05 -0500718typedef struct
719{
720 u32 client_index; /* in memclnt registration pool */
721 u32 client_pid;
722} vpe_client_registration_t;
723
Dave Barach6d963c22016-12-05 09:50:05 -0500724typedef struct
725{
Neale Rannscbe25aa2019-09-30 10:53:31 +0000726#define _(a) \
727 uword *a##_registration_hash; \
728 vpe_client_registration_t * a##_registrations;
Dave Barach6d963c22016-12-05 09:50:05 -0500729 foreach_registration_hash
730#undef _
731 /* notifications happen really early in the game */
732 u8 link_state_process_up;
733
Dave Barach6d963c22016-12-05 09:50:05 -0500734 /* convenience */
735 vlib_main_t *vlib_main;
Florin Coras248210c2021-09-14 18:54:45 -0700736 struct vnet_main_t *vnet_main;
Dave Barach6d963c22016-12-05 09:50:05 -0500737} vpe_api_main_t;
738
739extern vpe_api_main_t vpe_api_main;
740
Dave Barachaff70772016-10-31 11:59:07 -0400741#endif /* __api_helper_macros_h__ */
742
743/*
744 * fd.io coding-style-patch-verification: ON
745 *
746 * Local Variables:
747 * eval: (c-set-style "gnu")
748 * End:
749 */