FD.io VPP  v19.08.1-401-g8e4ed521a
Vector Packet Processing
vpp_echo_bapi.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdio.h>
17 #include <signal.h>
18 
20 
21 /*
22  *
23  * Binary API Messages
24  *
25  */
26 
27 void
29 {
33 
34  bmp = vl_msg_api_alloc (sizeof (*bmp));
35  clib_memset (bmp, 0, sizeof (*bmp));
36 
37  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
38  bmp->client_index = em->my_client_index;
39  bmp->context = ntohl (0xfeedface);
40  bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
41  bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ADD_SEGMENT;
45  bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20;
46  bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20;
48  if (em->appns_id)
49  {
50  bmp->namespace_id_len = vec_len (em->appns_id);
52  bmp->namespace_id_len);
55  }
56  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
57 
58  cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + test_srv_crt_rsa_len);
59  clib_memset (cert_mp, 0, sizeof (*cert_mp));
60  cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD);
61  cert_mp->client_index = em->my_client_index;
62  cert_mp->context = ntohl (0xfeedface);
63  cert_mp->cert_len = clib_host_to_net_u16 (test_srv_crt_rsa_len);
65  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cert_mp);
66 
67  key_mp = vl_msg_api_alloc (sizeof (*key_mp) + test_srv_key_rsa_len);
68  clib_memset (key_mp, 0, sizeof (*key_mp) + test_srv_key_rsa_len);
69  key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD);
70  key_mp->client_index = em->my_client_index;
71  key_mp->context = ntohl (0xfeedface);
72  key_mp->key_len = clib_host_to_net_u16 (test_srv_key_rsa_len);
74  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & key_mp);
75 }
76 
77 void
79 {
81  bmp = vl_msg_api_alloc (sizeof (*bmp));
82  clib_memset (bmp, 0, sizeof (*bmp));
83 
84  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
85  bmp->client_index = em->my_client_index;
86  bmp->context = ntohl (0xfeedface);
87  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
88 }
89 
90 void
92 {
93  vl_api_bind_uri_t *bmp;
94  bmp = vl_msg_api_alloc (sizeof (*bmp));
95  clib_memset (bmp, 0, sizeof (*bmp));
96 
97  bmp->_vl_msg_id = ntohs (VL_API_BIND_URI);
98  bmp->client_index = em->my_client_index;
99  bmp->context = ntohl (0xfeedface);
100  memcpy (bmp->uri, em->uri, vec_len (em->uri));
101  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
102 }
103 
104 void
106 {
107  vl_api_unbind_uri_t *ump;
108 
109  ump = vl_msg_api_alloc (sizeof (*ump));
110  clib_memset (ump, 0, sizeof (*ump));
111 
112  ump->_vl_msg_id = ntohs (VL_API_UNBIND_URI);
113  ump->client_index = em->my_client_index;
114  memcpy (ump->uri, em->uri, vec_len (em->uri));
115  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & ump);
116 }
117 
118 void
119 echo_send_connect (u8 * uri, u32 opaque)
120 {
121  echo_main_t *em = &echo_main;
123  cmp = vl_msg_api_alloc (sizeof (*cmp));
124  clib_memset (cmp, 0, sizeof (*cmp));
125  cmp->_vl_msg_id = ntohs (VL_API_CONNECT_URI);
126  cmp->client_index = em->my_client_index;
127  cmp->context = ntohl (opaque);
128  memcpy (cmp->uri, uri, vec_len (uri));
129  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cmp);
130 }
131 
132 void
134 {
135  echo_main_t *em = &echo_main;
137  dmp = vl_msg_api_alloc (sizeof (*dmp));
138  clib_memset (dmp, 0, sizeof (*dmp));
139  dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
140  dmp->client_index = em->my_client_index;
141  dmp->handle = handle;
142  ECHO_LOG (1, "Disconnect session 0x%lx", dmp->handle);
143  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & dmp);
144 }
145 
146 /*
147  *
148  * Helpers
149  *
150  */
151 
152 static int
154 {
155  fifo_segment_create_args_t _a, *a = &_a;
157  int rv;
158 
159  clib_memset (a, 0, sizeof (*a));
160  a->segment_name = (char *) name;
161  a->segment_type = type;
162 
163  if (type == SSVM_SEGMENT_MEMFD)
164  a->memfd_fd = fd;
165 
166  if ((rv = fifo_segment_attach (sm, a)))
167  return rv;
169  return 0;
170 }
171 
172 static inline void
173 echo_segment_handle_add_del (echo_main_t * em, u64 segment_handle, u8 add)
174 {
176  if (add)
177  hash_set (em->shared_segment_handles, segment_handle, 1);
178  else
179  hash_unset (em->shared_segment_handles, segment_handle);
181 }
182 
183 /*
184  *
185  * Binary API callbacks
186  *
187  */
188 
189 static void
191  mp)
192 {
193  echo_main_t *em = &echo_main;
194  int *fds = 0, i;
195  u32 n_fds = 0;
196  u64 segment_handle;
197  segment_handle = clib_net_to_host_u64 (mp->segment_handle);
198  ECHO_LOG (1, "Attached returned app %u", htons (mp->app_index));
199 
200  if (mp->retval)
201  {
202  ECHO_FAIL (ECHO_FAIL_VL_API_APP_ATTACH, "attach failed: %U",
203  format_api_error, clib_net_to_host_u32 (mp->retval));
204  return;
205  }
206 
207  if (mp->segment_name_length == 0)
208  {
209  ECHO_FAIL (ECHO_FAIL_VL_API_MISSING_SEGMENT_NAME,
210  "segment_name_length zero");
211  return;
212  }
213 
216  svm_msg_q_t *);
217 
218  if (mp->n_fds)
219  {
220  vec_validate (fds, mp->n_fds);
221  if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
222  {
223  ECHO_FAIL (ECHO_FAIL_VL_API_RECV_FD_MSG,
224  "vl_socket_client_recv_fd_msg failed");
225  goto failed;
226  }
227 
228  if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
229  if (ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++]))
230  {
231  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
232  "svm_fifo_segment_attach failed on SSVM_SEGMENT_MEMFD");
233  goto failed;
234  }
235 
236  if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
237  if (ssvm_segment_attach ((char *) mp->segment_name,
238  SSVM_SEGMENT_MEMFD, fds[n_fds++]))
239  {
240  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
241  "svm_fifo_segment_attach ('%s') "
242  "failed on SSVM_SEGMENT_MEMFD", mp->segment_name);
243  goto failed;
244  }
245  if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
247 
248  vec_free (fds);
249  }
250  else
251  {
253  -1))
254  {
255  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
256  "svm_fifo_segment_attach ('%s') "
257  "failed on SSVM_SEGMENT_SHM", mp->segment_name);
258  return;
259  }
260  }
261  echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
262  ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle);
263 
264  em->state = STATE_ATTACHED;
265  return;
266 failed:
267  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
268  close (fds[i]);
269  vec_free (fds);
270 }
271 
272 static void
273 vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
274  mp)
275 {
276  if (mp->retval)
277  {
278  ECHO_FAIL (ECHO_FAIL_VL_API_DETACH_REPLY,
279  "app detach returned with err: %d", mp->retval);
280  return;
281  }
283 }
284 
285 
286 static void
288 {
289  echo_main_t *em = &echo_main;
290  u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle);
291  echo_segment_handle_add_del (em, segment_handle, 0 /* add */ );
292  ECHO_LOG (1, "Unmaped segment 0x%lx", segment_handle);
293 }
294 
295 static void
297 {
299  fifo_segment_create_args_t _a, *a = &_a;
300  echo_main_t *em = &echo_main;
301  int *fds = 0, i;
302  char *seg_name = (char *) mp->segment_name;
303  u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle);
304 
305  if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
306  {
307  vec_validate (fds, 1);
308  if (vl_socket_client_recv_fd_msg (fds, 1, 5))
309  {
310  ECHO_FAIL (ECHO_FAIL_VL_API_RECV_FD_MSG,
311  "vl_socket_client_recv_fd_msg failed");
312  goto failed;
313  }
314 
315  if (ssvm_segment_attach (seg_name, SSVM_SEGMENT_MEMFD, fds[0]))
316  {
317  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
318  "svm_fifo_segment_attach ('%s') "
319  "failed on SSVM_SEGMENT_MEMFD", seg_name);
320  goto failed;
321  }
322  vec_free (fds);
323  }
324  else
325  {
326  clib_memset (a, 0, sizeof (*a));
327  a->segment_name = seg_name;
328  a->segment_size = mp->segment_size;
329  /* Attach to the segment vpp created */
330  if (fifo_segment_attach (sm, a))
331  {
332  ECHO_FAIL (ECHO_FAIL_VL_API_FIFO_SEG_ATTACH,
333  "fifo_segment_attach ('%s') failed", seg_name);
334  goto failed;
335  }
336  }
337  echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
338  ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle);
339  return;
340 
341 failed:
342  for (i = 0; i < vec_len (fds); i++)
343  close (fds[i]);
344  vec_free (fds);
345 }
346 
347 static void
348 vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp)
349 {
350  if (mp->retval)
351  {
352  ECHO_FAIL (ECHO_FAIL_VL_API_BIND_URI_REPLY, "bind failed: %U",
353  format_api_error, clib_net_to_host_u32 (mp->retval));
354  }
355 }
356 
357 static void
358 vl_api_unbind_uri_reply_t_handler (vl_api_unbind_uri_reply_t * mp)
359 {
360  echo_session_t *listen_session;
361  echo_main_t *em = &echo_main;
362  if (mp->retval != 0)
363  {
364  ECHO_FAIL (ECHO_FAIL_VL_API_UNBIND_REPLY, "unbind_uri returned %d",
365  ntohl (mp->retval));
366  return;
367  }
368  listen_session = pool_elt_at_index (em->sessions, em->listen_session_index);
369  em->proto_cb_vft->cleanup_cb (listen_session, 0 /* parent_died */ );
371 }
372 
373 static void
375  mp)
376 {
377  echo_main_t *em = &echo_main;
378  echo_session_t *s;
379 
380  if (mp->retval)
381  {
382  ECHO_FAIL (ECHO_FAIL_VL_API_DISCONNECT_SESSION_REPLY,
383  "vpp complained about disconnect: %d", ntohl (mp->retval));
384  return;
385  }
386 
387  ECHO_LOG (1, "Got disonnected reply for session 0x%lx", mp->handle);
388  if (!(s = echo_get_session_from_handle (em, mp->handle)))
389  return;
391 }
392 
393 static void
395  (vl_api_application_tls_cert_add_reply_t * mp)
396 {
397  if (mp->retval)
398  ECHO_FAIL (ECHO_FAIL_VL_API_TLS_CERT_ADD_REPLY,
399  "failed to add application tls cert");
400 }
401 
402 static void
404  (vl_api_application_tls_key_add_reply_t * mp)
405 {
406  if (mp->retval)
407  ECHO_FAIL (ECHO_FAIL_VL_API_TLS_KEY_ADD_REPLY,
408  "failed to add application tls key");
409 }
410 
411 static void
412 vl_api_connect_uri_reply_t_handler (vl_api_connect_uri_reply_t * mp)
413 {
414  echo_main_t *em = &echo_main;
415  if (mp->retval && (em->proto_cb_vft->connected_cb))
417  mp->context, 1 /* is_failed */ );
418 }
419 
420 #define foreach_quic_echo_msg \
421 _(BIND_URI_REPLY, bind_uri_reply) \
422 _(UNBIND_URI_REPLY, unbind_uri_reply) \
423 _(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
424 _(APPLICATION_ATTACH_REPLY, application_attach_reply) \
425 _(APPLICATION_DETACH_REPLY, application_detach_reply) \
426 _(MAP_ANOTHER_SEGMENT, map_another_segment) \
427 _(UNMAP_SEGMENT, unmap_segment) \
428 _(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \
429 _(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \
430 _(CONNECT_URI_REPLY, connect_uri_reply) \
431 
432 void
434 {
435 #define _(N,n) \
436  vl_msg_api_set_handlers(VL_API_##N, #n, \
437  vl_api_##n##_t_handler, \
438  vl_noop_handler, \
439  vl_api_##n##_t_endian, \
440  vl_api_##n##_t_print, \
441  sizeof(vl_api_##n##_t), 1);
443 #undef _
444 }
445 
446 /*
447  * fd.io coding-style-patch-verification: ON
448  *
449  * Local Variables:
450  * eval: (c-set-style "gnu")
451  * End:
452  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
#define hash_set(h, key, value)
Definition: hash.h:255
static void vl_api_disconnect_session_reply_t_handler(vl_api_disconnect_session_reply_t *mp)
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:102
static void vl_api_connect_uri_reply_t_handler(vl_api_connect_uri_reply_t *mp)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:80
u32 listen_session_index
static void vl_api_unbind_uri_reply_t_handler(vl_api_unbind_uri_reply_t *mp)
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:538
echo_session_t * sessions
Application add TLS key.
Definition: session.api:131
static void echo_segment_handle_add_del(echo_main_t *em, u64 segment_handle, u8 add)
svm_queue_t * vl_input_queue
unsigned long u64
Definition: types.h:89
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
static void vl_api_application_tls_cert_add_reply_t_handler(vl_api_application_tls_cert_add_reply_t *mp)
static u8 * format_api_error(u8 *s, va_list *args)
Definition: api_main.c:12
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
int i
echo_main_t echo_main
Definition: vpp_echo.c:24
volatile connection_state_t state
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
void echo_send_disconnect_session(u64 handle, u32 opaque)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void vl_api_application_attach_reply_t_handler(vl_api_application_attach_reply_t *mp)
void(* connected_cb)(session_connected_bundled_msg_t *mp, u32 session_index, u8 is_failed)
enum ssvm_segment_type_ ssvm_segment_type_t
void echo_send_attach(echo_main_t *em)
Definition: vpp_echo_bapi.c:28
static const u32 test_srv_key_rsa_len
Definition: tls_test.h:77
static int ssvm_segment_attach(char *name, ssvm_segment_type_t type, int fd)
clib_spinlock_t segment_handles_lock
#define ECHO_FAIL(fail, _fmt, _args...)
unsigned int u32
Definition: types.h:88
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
char * segment_name
segment name
Definition: fifo_segment.h:68
static void vl_api_map_another_segment_t_handler(vl_api_map_another_segment_t *mp)
vl_api_fib_path_type_t type
Definition: fib_types.api:123
int fifo_segment_attach(fifo_segment_main_t *sm, fifo_segment_create_args_t *a)
Attach as slave to a fifo segment.
Definition: fifo_segment.c:99
vpp->client unmap shared memory segment
Definition: session.api:174
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
client->vpp, attach application to session layer WILL BE DEPRECATED POST 20.01
Definition: session.api:28
void(* cleanup_cb)(echo_session_t *s, u8 parent_died)
void echo_api_hookup(echo_main_t *em)
static void vl_api_application_detach_reply_t_handler(vl_api_application_detach_reply_t *mp)
Unbind a given URI WILL BE DEPRECATED POST 20.01
Definition: session.api:204
static const char test_srv_crt_rsa[]
Definition: tls_test.h:23
fifo_segment_main_t segment_main
u8 name[64]
Definition: memclnt.api:152
u32 segment_size
size of the segment
Definition: fifo_segment.h:66
void echo_send_connect(u8 *uri, u32 opaque)
clib_error_t * vl_socket_client_recv_fd_msg(int fds[], int n_fds, u32 wait)
svm_msg_q_t * our_event_queue
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
#define foreach_quic_echo_msg
uword * shared_segment_handles
#define ECHO_LOG(lvl, _fmt, _args...)
int memfd_fd
fd for memfd segments
Definition: fifo_segment.h:67
Application attach reply WILL BE DEPRECATED POST 20.01
Definition: session.api:52
static const char test_srv_key_rsa[]
Definition: tls_test.h:49
void(* disconnected_reply_cb)(echo_session_t *s)
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
client->vpp, attach application to session layer WILL BE DEPRECATED POST 20.01
Definition: session.api:144
void echo_send_unbind(echo_main_t *em)
vpp->client, please map an additional shared memory segment
Definition: session.api:159
echo_session_t * echo_get_session_from_handle(echo_main_t *em, u64 handle)
void svm_msg_q_set_consumer_eventfd(svm_msg_q_t *mq, int fd)
Set event fd for queue consumer.
#define clib_max(x, y)
Definition: clib.h:288
static void vl_api_bind_uri_reply_t_handler(vl_api_bind_uri_reply_t *mp)
ssvm_segment_type_t segment_type
type of segment requested
Definition: fifo_segment.h:65
void echo_send_detach(echo_main_t *em)
Definition: vpp_echo_bapi.c:78
bidirectional disconnect API WILL BE DEPRECATED POST 20.01
Definition: session.api:236
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Bind to a given URI WILL BE DEPRECATED POST 20.01
Definition: session.api:189
void echo_send_listen(echo_main_t *em)
Definition: vpp_echo_bapi.c:91
static void vl_api_application_tls_key_add_reply_t_handler(vl_api_application_tls_key_add_reply_t *mp)
Application add TLS certificate.
Definition: session.api:117
echo_proto_cb_vft_t * proto_cb_vft
static void vl_api_unmap_segment_t_handler(vl_api_unmap_segment_t *mp)
Connect to a given URI WILL BE DEPRECATED POST 20.01
Definition: session.api:221
bidirectional disconnect reply API WILL BE DEPRECATED POST 20.01
Definition: session.api:250
static const u32 test_srv_crt_rsa_len
Definition: tls_test.h:47
u32 * new_segment_indices
return vec of new seg indices
Definition: fifo_segment.h:69