api: split api generated files
[vpp.git] / src / vlibapi / api_helper_macros.h
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_MACRO2(t, body)                                           \
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 = htons((t)+(REPLY_MSG_ID_BASE));                   \
56     rmp->context = mp->context;                                         \
57     rmp->retval = ntohl(rv);                                            \
58     do {body;} while (0);                                               \
59     vl_api_send_msg (rp, (u8 *)rmp);                                    \
60 } while(0);
61
62 #define REPLY_MACRO_DETAILS2(t, body)                                   \
63 do {                                                                    \
64     vl_api_registration_t *rp;                                          \
65     rv = vl_msg_api_pd_handler (mp, rv);                                \
66     rp = vl_api_client_index_to_registration (mp->client_index);        \
67     if (rp == 0)                                                        \
68       return;                                                           \
69                                                                         \
70     rmp = vl_msg_api_alloc (sizeof (*rmp));                             \
71     rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE));                   \
72     rmp->context = mp->context;                                         \
73     do {body;} while (0);                                               \
74     vl_api_send_msg (rp, (u8 *)rmp);                                    \
75 } while(0);
76
77 #define REPLY_MACRO3(t, n, body)                                        \
78 do {                                                                    \
79     vl_api_registration_t *rp;                                          \
80     rv = vl_msg_api_pd_handler (mp, rv);                                \
81     rp = vl_api_client_index_to_registration (mp->client_index);        \
82     if (rp == 0)                                                        \
83       return;                                                           \
84                                                                         \
85     rmp = vl_msg_api_alloc (sizeof (*rmp) + n);                         \
86     rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE));                   \
87     rmp->context = mp->context;                                         \
88     rmp->retval = ntohl(rv);                                            \
89     do {body;} while (0);                                               \
90     vl_api_send_msg (rp, (u8 *)rmp);                                    \
91 } while(0);
92
93 #define REPLY_MACRO4(t, n, body)                                        \
94 do {                                                                    \
95     vl_api_registration_t *rp;                                          \
96     u8 is_error = 0;                                                    \
97     rv = vl_msg_api_pd_handler (mp, rv);                                \
98                                                                         \
99     rp = vl_api_client_index_to_registration (mp->client_index);        \
100     if (rp == 0)                                                        \
101       return;                                                           \
102                                                                         \
103     rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n);                 \
104     if (!rmp)                                                           \
105       {                                                                 \
106         /* if there isn't enough memory, try to allocate */             \
107         /* some at least for returning an error */                      \
108         rmp = vl_msg_api_alloc (sizeof (*rmp));                         \
109         if (!rmp)                                                       \
110           return;                                                       \
111                                                                         \
112         clib_memset (rmp, 0, sizeof (*rmp));                                 \
113         rv = VNET_API_ERROR_TABLE_TOO_BIG;                              \
114         is_error = 1;                                                   \
115       }                                                                 \
116     rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE));                   \
117     rmp->context = mp->context;                                         \
118     rmp->retval = ntohl(rv);                                            \
119     if (!is_error)                                                      \
120       do {body;} while (0);                                             \
121     vl_api_send_msg (rp, (u8 *)rmp);                                    \
122 } while(0);
123
124 /* "trust, but verify" */
125
126 static inline uword
127 vnet_sw_if_index_is_api_valid (u32 sw_if_index)
128 {
129   return vnet_sw_interface_is_api_valid (vnet_get_main (), sw_if_index);
130 }
131
132 #define VALIDATE_SW_IF_INDEX(mp)                                \
133  do { u32 __sw_if_index = ntohl((mp)->sw_if_index);             \
134     if (!vnet_sw_if_index_is_api_valid(__sw_if_index)) {        \
135         rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
136         goto bad_sw_if_index;                                   \
137     }                                                           \
138 } while(0);
139
140 #define BAD_SW_IF_INDEX_LABEL                   \
141 do {                                            \
142 bad_sw_if_index:                                \
143     ;                                           \
144 } while (0);
145
146 #define VALIDATE_RX_SW_IF_INDEX(mp)                             \
147  do { u32 __rx_sw_if_index = ntohl((mp)->rx_sw_if_index);       \
148     if (!vnet_sw_if_index_is_api_valid(__rx_sw_if_index)) {     \
149         rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
150         goto bad_rx_sw_if_index;                                \
151     }                                                           \
152 } while(0);
153
154 #define BAD_RX_SW_IF_INDEX_LABEL                \
155 do {                                            \
156 bad_rx_sw_if_index:                             \
157     ;                                           \
158 } while (0);
159
160 #define VALIDATE_TX_SW_IF_INDEX(mp)                             \
161  do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index);         \
162     if (!vnet_sw_if_index_is_api_valid(__tx_sw_if_index)) {     \
163         rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
164         goto bad_tx_sw_if_index;                                \
165     }                                                           \
166 } while(0);
167
168 #define BAD_TX_SW_IF_INDEX_LABEL                \
169 do {                                            \
170 bad_tx_sw_if_index:                             \
171     ;                                           \
172 } while (0);
173
174 #define VALIDATE_BD_ID(mp)                      \
175  do { u32 __rx_bd_id = ntohl(mp->bd_id);        \
176     if (__rx_bd_id > L2_BD_ID_MAX) {            \
177         rv = VNET_API_ERROR_BD_ID_EXCEED_MAX;   \
178         goto bad_bd_id;                         \
179     }                                           \
180 } while(0);
181
182 #define BAD_BD_ID_LABEL                         \
183 do {                                            \
184 bad_bd_id:                                      \
185     ;                                           \
186 } while (0);
187
188 #define pub_sub_handler(lca,UCA)                                        \
189 static void vl_api_want_##lca##_t_handler (                             \
190     vl_api_want_##lca##_t *mp)                                          \
191 {                                                                       \
192     vpe_api_main_t *vam = &vpe_api_main;                                \
193     vpe_client_registration_t *rp;                                      \
194     vl_api_want_##lca##_reply_t *rmp;                                   \
195     uword *p;                                                           \
196     i32 rv = 0;                                                         \
197                                                                         \
198     p = hash_get (vam->lca##_registration_hash, mp->client_index);      \
199     if (p) {                                                            \
200         if (mp->enable_disable) {                                       \
201             clib_warning ("pid %d: already enabled...", ntohl(mp->pid)); \
202             rv = VNET_API_ERROR_INVALID_REGISTRATION;                   \
203             goto reply;                                                 \
204         } else {                                                        \
205             rp = pool_elt_at_index (vam->lca##_registrations, p[0]);    \
206             pool_put (vam->lca##_registrations, rp);                    \
207             hash_unset (vam->lca##_registration_hash,                   \
208                 mp->client_index);                                      \
209             goto reply;                                                 \
210         }                                                               \
211     }                                                                   \
212     if (mp->enable_disable == 0) {                                      \
213         clib_warning ("pid %d: already disabled...", mp->pid);          \
214         rv = VNET_API_ERROR_INVALID_REGISTRATION;                       \
215         goto reply;                                                     \
216     }                                                                   \
217     pool_get (vam->lca##_registrations, rp);                            \
218     rp->client_index = mp->client_index;                                \
219     rp->client_pid = mp->pid;                                           \
220     hash_set (vam->lca##_registration_hash, rp->client_index,           \
221               rp - vam->lca##_registrations);                           \
222                                                                         \
223 reply:                                                                  \
224     REPLY_MACRO (VL_API_WANT_##UCA##_REPLY);                            \
225 }                                                                       \
226                                                                         \
227 static clib_error_t * vl_api_want_##lca##_t_reaper (u32 client_index)   \
228 {                                                                       \
229     vpe_api_main_t *vam = &vpe_api_main;                                \
230     vpe_client_registration_t *rp;                                      \
231     uword *p;                                                           \
232                                                                         \
233     p = hash_get (vam->lca##_registration_hash, client_index);          \
234     if (p)                                                              \
235       {                                                                 \
236         rp = pool_elt_at_index (vam->lca##_registrations, p[0]);        \
237         pool_put (vam->lca##_registrations, rp);                        \
238         hash_unset (vam->lca##_registration_hash, client_index);        \
239       }                                                                 \
240     return (NULL);                                                      \
241 }                                                                       \
242                                                                         \
243 VL_MSG_API_REAPER_FUNCTION (vl_api_want_##lca##_t_reaper);              \
244
245 #define foreach_registration_hash               \
246 _(interface_events)                             \
247 _(to_netconf_server)                            \
248 _(from_netconf_server)                          \
249 _(to_netconf_client)                            \
250 _(from_netconf_client)                          \
251 _(oam_events)                                   \
252 _(bfd_events)                                   \
253 _(wc_ip6_nd_events)                             \
254 _(wc_ip4_arp_events)                            \
255 _(ip6_ra_events)                                \
256 _(dhcp6_pd_reply_events)                        \
257 _(dhcp6_reply_events)
258
259 typedef struct
260 {
261   u32 client_index;             /* in memclnt registration pool */
262   u32 client_pid;
263 } vpe_client_registration_t;
264
265 struct _vl_api_ip4_arp_event;
266 struct _vl_api_ip6_nd_event;
267
268 typedef struct
269 {
270 #define _(a) uword *a##_registration_hash;              \
271     vpe_client_registration_t * a##_registrations;
272   foreach_registration_hash
273 #undef _
274     /* notifications happen really early in the game */
275   u8 link_state_process_up;
276
277   /* ip4 arp event registration pool */
278   struct _vl_api_ip4_arp_event *arp_events;
279
280   /* ip6 nd event registration pool */
281   struct _vl_api_ip6_nd_event *nd_events;
282
283   /* convenience */
284   vlib_main_t *vlib_main;
285   vnet_main_t *vnet_main;
286 } vpe_api_main_t;
287
288 extern vpe_api_main_t vpe_api_main;
289
290 #endif /* __api_helper_macros_h__ */
291
292 /*
293  * fd.io coding-style-patch-verification: ON
294  *
295  * Local Variables:
296  * eval: (c-set-style "gnu")
297  * End:
298  */