FD.io VPP  v17.01-9-ge7dcee4
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 
21 #ifndef __api_helper_macros_h__
22 #define __api_helper_macros_h__
23 
24 #define f64_endian(a)
25 #define f64_print(a,b)
26 
27 #define REPLY_MACRO(t) \
28 do { \
29  unix_shared_memory_queue_t * q; \
30  rv = vl_msg_api_pd_handler (mp, rv); \
31  q = vl_api_client_index_to_input_queue (mp->client_index); \
32  if (!q) \
33  return; \
34  \
35  rmp = vl_msg_api_alloc (sizeof (*rmp)); \
36  rmp->_vl_msg_id = ntohs((t)); \
37  rmp->context = mp->context; \
38  rmp->retval = ntohl(rv); \
39  \
40  vl_msg_api_send_shmem (q, (u8 *)&rmp); \
41 } while(0);
42 
43 #define REPLY_MACRO2(t, body) \
44 do { \
45  unix_shared_memory_queue_t * q; \
46  rv = vl_msg_api_pd_handler (mp, rv); \
47  q = vl_api_client_index_to_input_queue (mp->client_index); \
48  if (!q) \
49  return; \
50  \
51  rmp = vl_msg_api_alloc (sizeof (*rmp)); \
52  rmp->_vl_msg_id = ntohs((t)); \
53  rmp->context = mp->context; \
54  rmp->retval = ntohl(rv); \
55  do {body;} while (0); \
56  vl_msg_api_send_shmem (q, (u8 *)&rmp); \
57 } while(0);
58 
59 #define REPLY_MACRO3(t, n, body) \
60 do { \
61  unix_shared_memory_queue_t * q; \
62  rv = vl_msg_api_pd_handler (mp, rv); \
63  q = vl_api_client_index_to_input_queue (mp->client_index); \
64  if (!q) \
65  return; \
66  \
67  rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
68  rmp->_vl_msg_id = ntohs((t)); \
69  rmp->context = mp->context; \
70  rmp->retval = ntohl(rv); \
71  do {body;} while (0); \
72  vl_msg_api_send_shmem (q, (u8 *)&rmp); \
73 } while(0);
74 
75 #define REPLY_MACRO4(t, n, body) \
76 do { \
77  unix_shared_memory_queue_t * q; \
78  u8 is_error = 0; \
79  rv = vl_msg_api_pd_handler (mp, rv); \
80  q = vl_api_client_index_to_input_queue (mp->client_index); \
81  if (!q) \
82  return; \
83  \
84  rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n); \
85  if (!rmp) \
86  { \
87  /* if there isn't enough memory, try to allocate */ \
88  /* some at least for returning an error */ \
89  rmp = vl_msg_api_alloc (sizeof (*rmp)); \
90  if (!rmp) \
91  return; \
92  \
93  memset (rmp, 0, sizeof (*rmp)); \
94  rv = VNET_API_ERROR_TABLE_TOO_BIG; \
95  is_error = 1; \
96  } \
97  rmp->_vl_msg_id = ntohs((t)); \
98  rmp->context = mp->context; \
99  rmp->retval = ntohl(rv); \
100  if (!is_error) \
101  do {body;} while (0); \
102  vl_msg_api_send_shmem (q, (u8 *)&rmp); \
103 } while(0);
104 
105 /* "trust, but verify" */
106 
107 #define VALIDATE_SW_IF_INDEX(mp) \
108  do { u32 __sw_if_index = ntohl(mp->sw_if_index); \
109  vnet_main_t *__vnm = vnet_get_main(); \
110  if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
111  __sw_if_index)) { \
112  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
113  goto bad_sw_if_index; \
114  } \
115 } while(0);
116 
117 #define BAD_SW_IF_INDEX_LABEL \
118 do { \
119 bad_sw_if_index: \
120  ; \
121 } while (0);
122 
123 #define VALIDATE_RX_SW_IF_INDEX(mp) \
124  do { u32 __rx_sw_if_index = ntohl(mp->rx_sw_if_index); \
125  vnet_main_t *__vnm = vnet_get_main(); \
126  if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
127  __rx_sw_if_index)) { \
128  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
129  goto bad_rx_sw_if_index; \
130  } \
131 } while(0);
132 
133 #define BAD_RX_SW_IF_INDEX_LABEL \
134 do { \
135 bad_rx_sw_if_index: \
136  ; \
137 } while (0);
138 
139 #define VALIDATE_TX_SW_IF_INDEX(mp) \
140  do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
141  vnet_main_t *__vnm = vnet_get_main(); \
142  if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
143  __tx_sw_if_index)) { \
144  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
145  goto bad_tx_sw_if_index; \
146  } \
147 } while(0);
148 
149 #define BAD_TX_SW_IF_INDEX_LABEL \
150 do { \
151 bad_tx_sw_if_index: \
152  ; \
153 } while (0);
154 
155 #define pub_sub_handler(lca,UCA) \
156 static void vl_api_want_##lca##_t_handler ( \
157  vl_api_want_##lca##_t *mp) \
158 { \
159  vpe_api_main_t *vam = &vpe_api_main; \
160  vpe_client_registration_t *rp; \
161  vl_api_want_##lca##_reply_t *rmp; \
162  uword *p; \
163  i32 rv = 0; \
164  \
165  p = hash_get (vam->lca##_registration_hash, mp->client_index); \
166  if (p) { \
167  if (mp->enable_disable) { \
168  clib_warning ("pid %d: already enabled...", mp->pid); \
169  rv = VNET_API_ERROR_INVALID_REGISTRATION; \
170  goto reply; \
171  } else { \
172  rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
173  pool_put (vam->lca##_registrations, rp); \
174  hash_unset (vam->lca##_registration_hash, \
175  mp->client_index); \
176  goto reply; \
177  } \
178  } \
179  if (mp->enable_disable == 0) { \
180  clib_warning ("pid %d: already disabled...", mp->pid); \
181  rv = VNET_API_ERROR_INVALID_REGISTRATION; \
182  goto reply; \
183  } \
184  pool_get (vam->lca##_registrations, rp); \
185  rp->client_index = mp->client_index; \
186  rp->client_pid = mp->pid; \
187  hash_set (vam->lca##_registration_hash, rp->client_index, \
188  rp - vam->lca##_registrations); \
189  \
190 reply: \
191  REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
192 }
193 
194 #define foreach_registration_hash \
195 _(interface_events) \
196 _(to_netconf_server) \
197 _(from_netconf_server) \
198 _(to_netconf_client) \
199 _(from_netconf_client) \
200 _(oam_events) \
201 _(bfd_events)
202 
203 /* WARNING: replicated in vpp/stats.h */
204 typedef struct
205 {
206  u32 client_index; /* in memclnt registration pool */
209 
210 struct _vl_api_ip4_arp_event;
211 struct _vl_api_ip6_nd_event;
212 
213 typedef struct
214 {
215 #define _(a) uword *a##_registration_hash; \
216  vpe_client_registration_t * a##_registrations;
218 #undef _
219  /* notifications happen really early in the game */
221 
222  /* ip4 arp event registration pool */
223  struct _vl_api_ip4_arp_event *arp_events;
224 
225  /* ip6 nd event registration pool */
226  struct _vl_api_ip6_nd_event *nd_events;
227 
228  /* convenience */
232 
234 
235 #endif /* __api_helper_macros_h__ */
236 
237 /*
238  * fd.io coding-style-patch-verification: ON
239  *
240  * Local Variables:
241  * eval: (c-set-style "gnu")
242  * End:
243  */
vnet_main_t * vnet_main
vlib_main_t * vlib_main
struct _vl_api_ip4_arp_event * arp_events
struct _vl_api_ip6_nd_event * nd_events
foreach_registration_hash u8 link_state_process_up
unsigned int u32
Definition: types.h:88
unsigned char u8
Definition: types.h:56
vpe_api_main_t vpe_api_main
Definition: api.c:324
#define foreach_registration_hash