FD.io VPP  v20.01-48-g3e0dafb74
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 {
31  bmp = vl_msg_api_alloc (sizeof (*bmp));
32  clib_memset (bmp, 0, sizeof (*bmp));
33 
34  bmp->_vl_msg_id = ntohs (VL_API_APP_ATTACH);
35  bmp->client_index = em->my_client_index;
36  bmp->context = ntohl (0xfeedface);
37  bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
38  bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ADD_SEGMENT;
42  bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20;
43  bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20;
45  if (em->appns_id)
46  {
47  bmp->namespace_id_len = vec_len (em->appns_id);
49  bmp->namespace_id_len);
52  }
53  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
54 }
55 
56 void
58 {
60  bmp = vl_msg_api_alloc (sizeof (*bmp));
61  clib_memset (bmp, 0, sizeof (*bmp));
62 
63  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
64  bmp->client_index = em->my_client_index;
65  bmp->context = ntohl (0xfeedface);
66 
67  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
68 }
69 
70 void
72 {
73  u32 cert_len = test_srv_crt_rsa_len;
74  u32 key_len = test_srv_key_rsa_len;
76 
77  bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
78  clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
79 
80  bmp->_vl_msg_id = ntohs (VL_API_APP_ADD_CERT_KEY_PAIR);
81  bmp->client_index = em->my_client_index;
82  bmp->context = ntohl (0xfeedface);
83  bmp->cert_len = clib_host_to_net_u16 (cert_len);
84  bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
85  clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len);
86  clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len);
87 
88  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
89 }
90 
91 void
93 {
95  bmp = vl_msg_api_alloc (sizeof (*bmp));
96  clib_memset (bmp, 0, sizeof (*bmp));
97 
98  bmp->_vl_msg_id = ntohs (VL_API_APP_DEL_CERT_KEY_PAIR);
99  bmp->client_index = em->my_client_index;
100  bmp->context = ntohl (0xfeedface);
101  bmp->index = clib_host_to_net_u32 (em->ckpair_index);
102  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
103 }
104 
105 void
106 echo_send_listen (echo_main_t * em, ip46_address_t * ip)
107 {
108  app_session_evt_t _app_evt, *app_evt = &_app_evt;
110  svm_msg_q_t *mq = em->ctrl_mq;
111 
113  mp = (session_listen_msg_t *) app_evt->evt->data;
114  memset (mp, 0, sizeof (*mp));
115  mp->client_index = em->my_client_index;
116  mp->context = ntohl (0xfeedface);
117  mp->wrk_index = 0;
118  mp->is_ip4 = em->uri_elts.is_ip4;
119  clib_memcpy_fast (&mp->ip, ip, sizeof (mp->ip));
120  mp->port = em->uri_elts.port;
121  mp->proto = em->uri_elts.transport_proto;
122  mp->ckpair_index = em->ckpair_index;
123  mp->crypto_engine = em->crypto_engine;
124  app_send_ctrl_evt_to_vpp (mq, app_evt);
125 }
126 
127 void
129 {
130  app_session_evt_t _app_evt, *app_evt = &_app_evt;
132  svm_msg_q_t *mq = em->ctrl_mq;
133 
135  mp = (session_unlisten_msg_t *) app_evt->evt->data;
136  memset (mp, 0, sizeof (*mp));
137  mp->client_index = em->my_client_index;
138  mp->wrk_index = 0;
139  mp->handle = s->vpp_session_handle;
140  mp->context = 0;
141  app_send_ctrl_evt_to_vpp (mq, app_evt);
142 }
143 
144 void
145 echo_send_connect (echo_main_t * em, void *args)
146 {
147  app_session_evt_t _app_evt, *app_evt = &_app_evt;
150  svm_msg_q_t *mq = em->ctrl_mq;
151 
153  while (em->max_sim_connects <= 0)
154  ;
155 
157  mp = (session_connect_msg_t *) app_evt->evt->data;
158  memset (mp, 0, sizeof (*mp));
159  mp->client_index = em->my_client_index;
160  mp->context = ntohl (a->context);
161  mp->wrk_index = 0;
162  mp->is_ip4 = em->uri_elts.is_ip4;
163  clib_memcpy_fast (&mp->ip, &a->ip, sizeof (mp->ip));
164  clib_memcpy_fast (&mp->lcl_ip, &a->lcl_ip, sizeof (mp->ip));
165  mp->port = em->uri_elts.port;
166  mp->proto = em->uri_elts.transport_proto;
168  mp->ckpair_index = em->ckpair_index;
169  mp->crypto_engine = em->crypto_engine;
170  mp->flags = em->connect_flag;
171  app_send_ctrl_evt_to_vpp (mq, app_evt);
172 }
173 
174 void
176 {
177  echo_session_t *s;
178  app_session_evt_t _app_evt, *app_evt = &_app_evt;
180  svm_msg_q_t *mq = em->ctrl_mq;
182 
184  mp = (session_disconnect_msg_t *) app_evt->evt->data;
185  memset (mp, 0, sizeof (*mp));
186  mp->client_index = em->my_client_index;
187  mp->handle = a->session_handle;
188  app_send_ctrl_evt_to_vpp (mq, app_evt);
189 
190  if (!(s = echo_get_session_from_handle (em, mp->handle)))
191  return;
193 }
194 
195 /*
196  *
197  * Helpers
198  *
199  */
200 
201 int
203 {
204  fifo_segment_create_args_t _a, *a = &_a;
206  int rv;
207 
208  clib_memset (a, 0, sizeof (*a));
209  a->segment_name = (char *) name;
210  a->segment_type = type;
211 
212  if (type == SSVM_SEGMENT_MEMFD)
213  a->memfd_fd = fd;
214 
215  if ((rv = fifo_segment_attach (sm, a)))
216  return rv;
218  return 0;
219 }
220 
221 void
222 echo_segment_handle_add_del (echo_main_t * em, u64 segment_handle, u8 add)
223 {
225  if (add)
226  hash_set (em->shared_segment_handles, segment_handle, 1);
227  else
228  hash_unset (em->shared_segment_handles, segment_handle);
230 }
231 
232 /*
233  *
234  * Binary API callbacks
235  *
236  */
237 
238 static void
241 {
242  echo_main_t *em = &echo_main;
243  if (mp->retval)
244  {
245  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY,
246  "Adding cert and key returned %d",
247  clib_net_to_host_u32 (mp->retval));
248  return;
249  }
250  /* No concurrency here, only bapi thread writes */
251  if (em->state != STATE_ATTACHED_NO_CERT)
252  {
253  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY, "Wrong state");
254  return;
255  }
256  em->ckpair_index = clib_net_to_host_u32 (mp->index);
257  em->state = STATE_ATTACHED;
258 }
259 
260 static void
262  (vl_api_app_del_cert_key_pair_reply_t * mp)
263 {
264  echo_main_t *em = &echo_main;
265  if (mp->retval)
266  {
267  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_DEL_REPLY,
268  "Delete cert and key returned %d",
269  clib_net_to_host_u32 (mp->retval));
270  return;
271  }
273 }
274 
275 static void
277 {
278  echo_main_t *em = &echo_main;
279  int *fds = 0, i;
280  u32 n_fds = 0;
281  u64 segment_handle;
282  segment_handle = clib_net_to_host_u64 (mp->segment_handle);
283  ECHO_LOG (2, "Attached returned app %u", htons (mp->app_index));
284 
285  if (mp->retval)
286  {
287  ECHO_FAIL (ECHO_FAIL_VL_API_APP_ATTACH, "attach failed: %U",
288  format_api_error, clib_net_to_host_u32 (mp->retval));
289  return;
290  }
291 
292  if (mp->segment_name_length == 0)
293  {
294  ECHO_FAIL (ECHO_FAIL_VL_API_MISSING_SEGMENT_NAME,
295  "segment_name_length zero");
296  return;
297  }
298 
299  if (!mp->app_mq)
300  {
301  ECHO_FAIL (ECHO_FAIL_VL_API_NULL_APP_MQ, "NULL app_mq");
302  return;
303  }
304  em->app_mq = uword_to_pointer (mp->app_mq, svm_msg_q_t *);
306 
307  if (mp->n_fds)
308  {
309  vec_validate (fds, mp->n_fds);
310  if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
311  {
312  ECHO_FAIL (ECHO_FAIL_VL_API_RECV_FD_MSG,
313  "vl_socket_client_recv_fd_msg failed");
314  goto failed;
315  }
316 
317  if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
318  if (echo_ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++]))
319  {
320  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
321  "svm_fifo_segment_attach failed on SSVM_SEGMENT_MEMFD");
322  goto failed;
323  }
324 
325  if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
326  if (echo_ssvm_segment_attach ((char *) mp->segment_name,
327  SSVM_SEGMENT_MEMFD, fds[n_fds++]))
328  {
329  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
330  "svm_fifo_segment_attach ('%s') "
331  "failed on SSVM_SEGMENT_MEMFD", mp->segment_name);
332  goto failed;
333  }
334  if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
335  svm_msg_q_set_consumer_eventfd (em->app_mq, fds[n_fds++]);
336 
337  vec_free (fds);
338  }
339  else
340  {
342  ((char *) mp->segment_name, SSVM_SEGMENT_SHM, -1))
343  {
344  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
345  "svm_fifo_segment_attach ('%s') "
346  "failed on SSVM_SEGMENT_SHM", mp->segment_name);
347  return;
348  }
349  }
350  echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
351  ECHO_LOG (2, "Mapped segment 0x%lx", segment_handle);
352 
354  return;
355 failed:
356  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
357  close (fds[i]);
358  vec_free (fds);
359 }
360 
361 static void
362 vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
363  mp)
364 {
365  if (mp->retval)
366  {
367  ECHO_FAIL (ECHO_FAIL_VL_API_DETACH_REPLY,
368  "app detach returned with err: %d", mp->retval);
369  return;
370  }
372 }
373 
374 #define foreach_quic_echo_msg \
375 _(APP_ATTACH_REPLY, app_attach_reply) \
376 _(APPLICATION_DETACH_REPLY, application_detach_reply) \
377 _(APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply) \
378 _(APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)
379 
380 void
382 {
383 #define _(N,n) \
384  vl_msg_api_set_handlers(VL_API_##N, #n, \
385  vl_api_##n##_t_handler, \
386  vl_noop_handler, \
387  vl_api_##n##_t_endian, \
388  vl_api_##n##_t_print, \
389  sizeof(vl_api_##n##_t), 1);
391 #undef _
392 }
393 
394 /*
395  * fd.io coding-style-patch-verification: ON
396  *
397  * Local Variables:
398  * eval: (c-set-style "gnu")
399  * End:
400  */
svm_msg_q_t * ctrl_mq
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
#define hash_set(h, key, value)
Definition: hash.h:255
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:102
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:80
static void vl_api_app_add_cert_key_pair_reply_t_handler(vl_api_app_add_cert_key_pair_reply_t *mp)
Add certificate and key.
Definition: session.api:132
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:538
void echo_send_del_cert_key(echo_main_t *em)
Definition: vpp_echo_bapi.c:92
svm_queue_t * vl_input_queue
unsigned long u64
Definition: types.h:89
ip46_address_t ip
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
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)
void echo_send_add_cert_key(echo_main_t *em)
Definition: vpp_echo_bapi.c:71
int i
echo_main_t echo_main
Definition: vpp_echo.c:24
ip46_address_t lcl_ip
volatile connection_state_t state
volatile int max_sim_connects
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
foreach_app_session_field u64 vpp_session_handle
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
enum ssvm_segment_type_ ssvm_segment_type_t
static void app_alloc_ctrl_evt_to_vpp(svm_msg_q_t *mq, app_session_evt_t *app_evt, u8 evt_type)
void echo_send_attach(echo_main_t *em)
Definition: vpp_echo_bapi.c:28
Application attach reply.
Definition: session.api:96
static const u32 test_srv_key_rsa_len
Definition: tls_test.h:77
void echo_send_unbind(echo_main_t *em, echo_session_t *s)
struct echo_main_t::@573 uri_elts
clib_spinlock_t segment_handles_lock
void echo_send_disconnect_session(echo_main_t *em, void *args)
#define ECHO_FAIL(fail, _fmt, _args...)
unsigned int u32
Definition: types.h:88
static void vl_api_app_del_cert_key_pair_reply_t_handler(vl_api_app_del_cert_key_pair_reply_t *mp)
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
char * segment_name
segment name
Definition: fifo_segment.h:80
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:179
void echo_api_hookup(echo_main_t *em)
static void vl_api_application_detach_reply_t_handler(vl_api_application_detach_reply_t *mp)
static const char test_srv_crt_rsa[]
Definition: tls_test.h:23
fifo_segment_main_t segment_main
svm_msg_q_t * app_mq
#define clib_atomic_sub_fetch(a, b)
Definition: atomics.h:31
static void app_send_ctrl_evt_to_vpp(svm_msg_q_t *mq, app_session_evt_t *app_evt)
Add certificate and key.
Definition: session.api:119
clib_error_t * vl_socket_client_recv_fd_msg(int fds[], int n_fds, u32 wait)
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
#define foreach_quic_echo_msg
uword * shared_segment_handles
#define ECHO_LOG(lvl, _fmt, _args...)
static void vl_api_app_attach_reply_t_handler(vl_api_app_attach_reply_t *mp)
int memfd_fd
fd for memfd segments
Definition: fifo_segment.h:79
string name[64]
Definition: ip.api:44
static const char test_srv_key_rsa[]
Definition: tls_test.h:49
#define uword_to_pointer(u, type)
Definition: types.h:136
void echo_segment_handle_add_del(echo_main_t *em, u64 segment_handle, u8 add)
client->vpp, attach application to session layer WILL BE DEPRECATED POST 20.01
Definition: session.api:184
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
ssvm_segment_type_t segment_type
type of segment requested
Definition: fifo_segment.h:77
void echo_send_detach(echo_main_t *em)
Definition: vpp_echo_bapi.c:57
int echo_ssvm_segment_attach(char *name, ssvm_segment_type_t type, int fd)
vl_api_address_t ip
Definition: l2.api:490
void(* sent_disconnect_cb)(echo_session_t *s)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
echo_proto_cb_vft_t * proto_cb_vft
void echo_send_listen(echo_main_t *em, ip46_address_t *ip)
void echo_send_connect(echo_main_t *em, void *args)
Application attach to session layer.
Definition: session.api:72
Delete certificate and key.
Definition: session.api:143
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:81