FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
api_helper_macros.h
Go to the documentation of this file.
1
/*
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
20
#ifndef __api_helper_macros_h__
21
#define __api_helper_macros_h__
22
23
#define f64_endian(a)
24
#define f64_print(a,b)
25
26
#ifndef REPLY_MSG_ID_BASE
27
#define REPLY_MSG_ID_BASE 0
28
#endif
29
30
#define REPLY_MACRO(t) \
31
do { \
32
vl_api_registration_t *rp; \
33
rv = vl_msg_api_pd_handler (mp, rv); \
34
rp = vl_api_client_index_to_registration (mp->client_index); \
35
if (rp == 0) \
36
return; \
37
\
38
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
39
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
40
rmp->context = mp->context; \
41
rmp->retval = ntohl(rv); \
42
\
43
vl_api_send_msg (rp, (u8 *)rmp); \
44
} while(0);
45
46
#define REPLY_MACRO_END(t) \
47
do { \
48
vl_api_registration_t *rp; \
49
rv = vl_msg_api_pd_handler (mp, rv); \
50
rp = vl_api_client_index_to_registration (mp->client_index); \
51
if (rp == 0) \
52
return; \
53
\
54
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
55
rmp->_vl_msg_id = t+(REPLY_MSG_ID_BASE); \
56
rmp->context = mp->context; \
57
rmp->retval = rv; \
58
api_main_t *am = vlibapi_get_main (); \
59
void (*endian_fp) (void *); \
60
endian_fp = am->msg_endian_handlers[t+(REPLY_MSG_ID_BASE)]; \
61
(*endian_fp) (rmp); \
62
vl_api_send_msg (rp, (u8 *)rmp); \
63
} while(0);
64
65
#define REPLY_MACRO2(t, body) \
66
do { \
67
vl_api_registration_t *rp; \
68
rv = vl_msg_api_pd_handler (mp, rv); \
69
rp = vl_api_client_index_to_registration (mp->client_index); \
70
if (rp == 0) \
71
return; \
72
\
73
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
74
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
75
rmp->context = mp->context; \
76
rmp->retval = ntohl(rv); \
77
do {body;} while (0); \
78
vl_api_send_msg (rp, (u8 *)rmp); \
79
} while(0);
80
81
#define REPLY_MACRO2_END(t, body) \
82
do { \
83
vl_api_registration_t *rp; \
84
rv = vl_msg_api_pd_handler (mp, rv); \
85
rp = vl_api_client_index_to_registration (mp->client_index); \
86
if (rp == 0) \
87
return; \
88
\
89
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
90
rmp->_vl_msg_id = t+(REPLY_MSG_ID_BASE); \
91
rmp->context = mp->context; \
92
rmp->retval = rv; \
93
do {body;} while (0); \
94
api_main_t *am = vlibapi_get_main (); \
95
void (*endian_fp) (void *); \
96
endian_fp = am->msg_endian_handlers[t+(REPLY_MSG_ID_BASE)]; \
97
(*endian_fp) (rmp); \
98
vl_api_send_msg (rp, (u8 *)rmp); \
99
} while(0);
100
101
#define REPLY_MACRO2_ZERO(t, body) \
102
do { \
103
vl_api_registration_t *rp; \
104
rv = vl_msg_api_pd_handler (mp, rv); \
105
rp = vl_api_client_index_to_registration (mp->client_index); \
106
if (rp == 0) \
107
return; \
108
\
109
rmp = vl_msg_api_alloc_zero (sizeof (*rmp)); \
110
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
111
rmp->context = mp->context; \
112
rmp->retval = ntohl(rv); \
113
do {body;} while (0); \
114
vl_api_send_msg (rp, (u8 *)rmp); \
115
} while(0);
116
117
#define REPLY_MACRO_DETAILS2(t, body) \
118
do { \
119
vl_api_registration_t *rp; \
120
rv = vl_msg_api_pd_handler (mp, rv); \
121
rp = vl_api_client_index_to_registration (mp->client_index); \
122
if (rp == 0) \
123
return; \
124
\
125
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
126
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
127
rmp->context = mp->context; \
128
do {body;} while (0); \
129
vl_api_send_msg (rp, (u8 *)rmp); \
130
} while(0);
131
132
#define REPLY_MACRO_DETAILS4(t, rp, context, body) \
133
do { \
134
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
135
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
136
rmp->context = context; \
137
do {body;} while (0); \
138
vl_api_send_msg (rp, (u8 *)rmp); \
139
} while(0);
140
141
#define REPLY_MACRO3(t, n, body) \
142
do { \
143
vl_api_registration_t *rp; \
144
rv = vl_msg_api_pd_handler (mp, rv); \
145
rp = vl_api_client_index_to_registration (mp->client_index); \
146
if (rp == 0) \
147
return; \
148
\
149
rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
150
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
151
rmp->context = mp->context; \
152
rmp->retval = ntohl(rv); \
153
do {body;} while (0); \
154
vl_api_send_msg (rp, (u8 *)rmp); \
155
} while(0);
156
157
#define REPLY_MACRO3_ZERO(t, n, body) \
158
do { \
159
vl_api_registration_t *rp; \
160
rv = vl_msg_api_pd_handler (mp, rv); \
161
rp = vl_api_client_index_to_registration (mp->client_index); \
162
if (rp == 0) \
163
return; \
164
\
165
rmp = vl_msg_api_alloc_zero (sizeof (*rmp) + n); \
166
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
167
rmp->context = mp->context; \
168
rmp->retval = ntohl(rv); \
169
do {body;} while (0); \
170
vl_api_send_msg (rp, (u8 *)rmp); \
171
} while(0);
172
173
#define REPLY_MACRO4(t, n, body) \
174
do { \
175
vl_api_registration_t *rp; \
176
u8 is_error = 0; \
177
rv = vl_msg_api_pd_handler (mp, rv); \
178
\
179
rp = vl_api_client_index_to_registration (mp->client_index); \
180
if (rp == 0) \
181
return; \
182
\
183
rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n); \
184
if (!rmp) \
185
{ \
186
/* if there isn't enough memory, try to allocate */
\
187
/* some at least for returning an error */
\
188
rmp = vl_msg_api_alloc (sizeof (*rmp)); \
189
if (!rmp) \
190
return; \
191
\
192
clib_memset (rmp, 0, sizeof (*rmp)); \
193
rv = VNET_API_ERROR_TABLE_TOO_BIG; \
194
is_error = 1; \
195
} \
196
rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \
197
rmp->context = mp->context; \
198
rmp->retval = ntohl(rv); \
199
if (!is_error) \
200
do {body;} while (0); \
201
vl_api_send_msg (rp, (u8 *)rmp); \
202
} while(0);
203
204
#define REPLY_AND_DETAILS_MACRO(t, p, body) \
205
do \
206
{ \
207
if (pool_elts (p) == 0) \
208
{ \
209
REPLY_MACRO (t); \
210
break; \
211
} \
212
vl_api_registration_t *rp; \
213
rp = vl_api_client_index_to_registration (mp->client_index); \
214
if (rp == 0) \
215
return; \
216
u32 cursor = clib_net_to_host_u32 (mp->cursor); \
217
vlib_main_t *vm = vlib_get_main (); \
218
f64 start = vlib_time_now (vm); \
219
if (pool_is_free_index (p, cursor)) \
220
{ \
221
cursor = pool_next_index (p, cursor); \
222
if (cursor == ~0) \
223
rv = VNET_API_ERROR_INVALID_VALUE; \
224
} \
225
while (cursor != ~0) \
226
{ \
227
do \
228
{ \
229
body; \
230
} \
231
while (0); \
232
cursor = pool_next_index (p, cursor); \
233
if (vl_api_process_may_suspend (vm, rp, start)) \
234
{ \
235
if (cursor != ~0) \
236
rv = VNET_API_ERROR_EAGAIN; \
237
break; \
238
} \
239
} \
240
REPLY_MACRO2 (t, ({ rmp->cursor = clib_host_to_net_u32 (cursor); })); \
241
} \
242
while (0);
243
244
#define REPLY_AND_DETAILS_VEC_MACRO(t, v, mp, rmp, rv, body) \
245
do { \
246
vl_api_registration_t *rp; \
247
rp = vl_api_client_index_to_registration (mp->client_index); \
248
if (rp == 0) \
249
return; \
250
u32 cursor = clib_net_to_host_u32 (mp->cursor); \
251
vlib_main_t *vm = vlib_get_main (); \
252
f64 start = vlib_time_now (vm); \
253
if (!v || vec_len (v) == 0) { \
254
cursor = ~0; \
255
rv = VNET_API_ERROR_INVALID_VALUE; \
256
} else if (cursor == ~0) \
257
cursor = 0; \
258
while (cursor != ~0 && cursor < vec_len (v)) { \
259
do {body;} while (0); \
260
++cursor; \
261
if (vl_api_process_may_suspend (vm, rp, start)) { \
262
if (cursor < vec_len (v)) \
263
rv = VNET_API_ERROR_EAGAIN; \
264
break; \
265
} \
266
} \
267
REPLY_MACRO2 (t, ({ \
268
rmp->cursor = clib_host_to_net_u32 (cursor); \
269
})); \
270
} while(0);
271
272
273
/* "trust, but verify" */
274
275
static
inline
uword
276
vnet_sw_if_index_is_api_valid
(
u32
sw_if_index
)
277
{
278
return
vnet_sw_interface_is_api_valid
(
vnet_get_main
(),
sw_if_index
);
279
}
280
281
#define VALIDATE_SW_IF_INDEX(mp) \
282
do { u32 __sw_if_index = ntohl((mp)->sw_if_index); \
283
if (!vnet_sw_if_index_is_api_valid(__sw_if_index)) { \
284
rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
285
goto bad_sw_if_index; \
286
} \
287
} while(0);
288
289
#define BAD_SW_IF_INDEX_LABEL \
290
do { \
291
bad_sw_if_index: \
292
; \
293
} while (0);
294
295
#define VALIDATE_RX_SW_IF_INDEX(mp) \
296
do { u32 __rx_sw_if_index = ntohl((mp)->rx_sw_if_index); \
297
if (!vnet_sw_if_index_is_api_valid(__rx_sw_if_index)) { \
298
rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
299
goto bad_rx_sw_if_index; \
300
} \
301
} while(0);
302
303
#define BAD_RX_SW_IF_INDEX_LABEL \
304
do { \
305
bad_rx_sw_if_index: \
306
; \
307
} while (0);
308
309
#define VALIDATE_TX_SW_IF_INDEX(mp) \
310
do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
311
if (!vnet_sw_if_index_is_api_valid(__tx_sw_if_index)) { \
312
rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
313
goto bad_tx_sw_if_index; \
314
} \
315
} while(0);
316
317
#define BAD_TX_SW_IF_INDEX_LABEL \
318
do { \
319
bad_tx_sw_if_index: \
320
; \
321
} while (0);
322
323
#define VALIDATE_BD_ID(mp) \
324
do { u32 __rx_bd_id = ntohl(mp->bd_id); \
325
if (__rx_bd_id > L2_BD_ID_MAX) { \
326
rv = VNET_API_ERROR_BD_ID_EXCEED_MAX; \
327
goto bad_bd_id; \
328
} \
329
} while(0);
330
331
#define BAD_BD_ID_LABEL \
332
do { \
333
bad_bd_id: \
334
; \
335
} while (0);
336
337
#define pub_sub_handler(lca,UCA) \
338
static void vl_api_want_##lca##_t_handler ( \
339
vl_api_want_##lca##_t *mp) \
340
{ \
341
vpe_api_main_t *vam = &vpe_api_main; \
342
vpe_client_registration_t *rp; \
343
vl_api_want_##lca##_reply_t *rmp; \
344
uword *p; \
345
i32 rv = 0; \
346
\
347
p = hash_get (vam->lca##_registration_hash, mp->client_index); \
348
if (p) { \
349
if (mp->enable_disable) { \
350
clib_warning ("pid %d: already enabled...", ntohl(mp->pid)); \
351
rv = VNET_API_ERROR_INVALID_REGISTRATION; \
352
goto reply; \
353
} else { \
354
rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
355
pool_put (vam->lca##_registrations, rp); \
356
hash_unset (vam->lca##_registration_hash, \
357
mp->client_index); \
358
goto reply; \
359
} \
360
} \
361
if (mp->enable_disable == 0) { \
362
clib_warning ("pid %d: already disabled...", mp->pid); \
363
rv = VNET_API_ERROR_INVALID_REGISTRATION; \
364
goto reply; \
365
} \
366
pool_get (vam->lca##_registrations, rp); \
367
rp->client_index = mp->client_index; \
368
rp->client_pid = mp->pid; \
369
hash_set (vam->lca##_registration_hash, rp->client_index, \
370
rp - vam->lca##_registrations); \
371
\
372
reply: \
373
REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
374
} \
375
\
376
static clib_error_t * vl_api_want_##lca##_t_reaper (u32 client_index) \
377
{ \
378
vpe_api_main_t *vam = &vpe_api_main; \
379
vpe_client_registration_t *rp; \
380
uword *p; \
381
\
382
p = hash_get (vam->lca##_registration_hash, client_index); \
383
if (p) \
384
{ \
385
rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
386
pool_put (vam->lca##_registrations, rp); \
387
hash_unset (vam->lca##_registration_hash, client_index); \
388
} \
389
return (NULL); \
390
} \
391
\
392
VL_MSG_API_REAPER_FUNCTION (vl_api_want_##lca##_t_reaper); \
393
394
#define foreach_registration_hash \
395
_(interface_events) \
396
_(to_netconf_server) \
397
_(from_netconf_server) \
398
_(to_netconf_client) \
399
_(from_netconf_client) \
400
_(oam_events) \
401
_(bfd_events) \
402
_(l2_arp_term_events) \
403
_(ip6_ra_events) \
404
_(dhcp6_pd_reply_events) \
405
_(dhcp6_reply_events) \
406
_(vrrp_vr_events)
407
408
typedef
struct
409
{
410
u32
client_index
;
/* in memclnt registration pool */
411
u32
client_pid
;
412
}
vpe_client_registration_t
;
413
414
typedef
struct
415
{
416
#define _(a) \
417
uword *a##_registration_hash; \
418
vpe_client_registration_t * a##_registrations;
419
foreach_registration_hash
420
#undef _
421
/* notifications happen really early in the game */
422
u8
link_state_process_up
;
423
424
/* convenience */
425
vlib_main_t
*
vlib_main
;
426
vnet_main_t
*
vnet_main
;
427
}
vpe_api_main_t
;
428
429
extern
vpe_api_main_t
vpe_api_main
;
430
431
#endif
/* __api_helper_macros_h__ */
432
433
/*
434
* fd.io coding-style-patch-verification: ON
435
*
436
* Local Variables:
437
* eval: (c-set-style "gnu")
438
* End:
439
*/
foreach_registration_hash
#define foreach_registration_hash
Definition:
api_helper_macros.h:394
vpe_api_main_t::vnet_main
vnet_main_t * vnet_main
Definition:
api_helper_macros.h:426
vpe_api_main_t
Definition:
api_helper_macros.h:414
vpe_api_main_t::vlib_main
vlib_main_t * vlib_main
Definition:
api_helper_macros.h:425
vnet_sw_interface_is_api_valid
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
Definition:
interface_funcs.h:285
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition:
pnat_test_stubs.h:56
vpe_client_registration_t::client_pid
u32 client_pid
Definition:
api_helper_macros.h:411
uword
u64 uword
Definition:
types.h:112
vnet_sw_if_index_is_api_valid
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
Definition:
api_helper_macros.h:276
vnet_main_t
Definition:
vnet.h:76
u32
unsigned int u32
Definition:
types.h:88
vpe_api_main_t::link_state_process_up
foreach_registration_hash u8 link_state_process_up
Definition:
api_helper_macros.h:422
vpe_client_registration_t::client_index
u32 client_index
Definition:
api_helper_macros.h:410
vlib_main_t
Definition:
main.h:102
u8
unsigned char u8
Definition:
types.h:56
vpe_client_registration_t
Definition:
api_helper_macros.h:408
sw_if_index
vl_api_interface_index_t sw_if_index
Definition:
wireguard.api:34
vpe_api_main
vpe_api_main_t vpe_api_main
Definition:
interface_api.c:55
src
vlibapi
api_helper_macros.h
Generated on Sat Jan 8 2022 10:04:36 for FD.io VPP by
1.8.17