FD.io VPP  v20.09-64-g4f7b92f0a
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  {
50  }
51  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
52 }
53 
54 void
56 {
58  bmp = vl_msg_api_alloc (sizeof (*bmp));
59  clib_memset (bmp, 0, sizeof (*bmp));
60 
61  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
62  bmp->client_index = em->my_client_index;
63  bmp->context = ntohl (0xfeedface);
64 
65  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
66 }
67 
68 void
70 {
71  u32 cert_len = test_srv_crt_rsa_len;
74 
75  bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
76  clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
77 
78  bmp->_vl_msg_id = ntohs (VL_API_APP_ADD_CERT_KEY_PAIR);
79  bmp->client_index = em->my_client_index;
80  bmp->context = ntohl (0xfeedface);
81  bmp->cert_len = clib_host_to_net_u16 (cert_len);
82  bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
83  clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len);
84  clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len);
85 
86  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
87 }
88 
89 void
91 {
93  bmp = vl_msg_api_alloc (sizeof (*bmp));
94  clib_memset (bmp, 0, sizeof (*bmp));
95 
96  bmp->_vl_msg_id = ntohs (VL_API_APP_DEL_CERT_KEY_PAIR);
97  bmp->client_index = em->my_client_index;
98  bmp->context = ntohl (0xfeedface);
99  bmp->index = clib_host_to_net_u32 (em->ckpair_index);
100  vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
101 }
102 
103 void
104 echo_send_listen (echo_main_t * em, ip46_address_t * ip)
105 {
106  app_session_evt_t _app_evt, *app_evt = &_app_evt;
108  svm_msg_q_t *mq = em->ctrl_mq;
109 
111  mp = (session_listen_msg_t *) app_evt->evt->data;
112  memset (mp, 0, sizeof (*mp));
113  mp->client_index = em->my_client_index;
114  mp->context = ntohl (0xfeedface);
115  mp->wrk_index = 0;
116  mp->is_ip4 = em->uri_elts.is_ip4;
117  clib_memcpy_fast (&mp->ip, ip, sizeof (mp->ip));
118  mp->port = em->uri_elts.port;
119  mp->proto = em->uri_elts.transport_proto;
120  mp->ckpair_index = em->ckpair_index;
121  mp->crypto_engine = em->crypto_engine;
122  app_send_ctrl_evt_to_vpp (mq, app_evt);
123 }
124 
125 void
127 {
128  app_session_evt_t _app_evt, *app_evt = &_app_evt;
130  svm_msg_q_t *mq = em->ctrl_mq;
131 
133  mp = (session_unlisten_msg_t *) app_evt->evt->data;
134  memset (mp, 0, sizeof (*mp));
135  mp->client_index = em->my_client_index;
136  mp->wrk_index = 0;
137  mp->handle = s->vpp_session_handle;
138  mp->context = 0;
139  app_send_ctrl_evt_to_vpp (mq, app_evt);
140 }
141 
142 void
143 echo_send_connect (echo_main_t * em, void *args)
144 {
145  app_session_evt_t _app_evt, *app_evt = &_app_evt;
148  svm_msg_q_t *mq = em->ctrl_mq;
149 
151  while (em->max_sim_connects <= 0)
152  ;
153 
155  mp = (session_connect_msg_t *) app_evt->evt->data;
156  memset (mp, 0, sizeof (*mp));
157  mp->client_index = em->my_client_index;
158  mp->context = ntohl (a->context);
159  mp->wrk_index = 0;
160  mp->is_ip4 = em->uri_elts.is_ip4;
161  clib_memcpy_fast (&mp->ip, &a->ip, sizeof (mp->ip));
162  clib_memcpy_fast (&mp->lcl_ip, &a->lcl_ip, sizeof (mp->ip));
163  mp->port = em->uri_elts.port;
164  mp->proto = em->uri_elts.transport_proto;
166  mp->ckpair_index = em->ckpair_index;
167  mp->crypto_engine = em->crypto_engine;
168  mp->flags = em->connect_flag;
169  app_send_ctrl_evt_to_vpp (mq, app_evt);
170 }
171 
172 void
174 {
175  echo_session_t *s;
176  app_session_evt_t _app_evt, *app_evt = &_app_evt;
178  svm_msg_q_t *mq = em->ctrl_mq;
180 
182  mp = (session_disconnect_msg_t *) app_evt->evt->data;
183  memset (mp, 0, sizeof (*mp));
184  mp->client_index = em->my_client_index;
185  mp->handle = a->session_handle;
186  app_send_ctrl_evt_to_vpp (mq, app_evt);
187 
188  if (!(s = echo_get_session_from_handle (em, mp->handle)))
189  return;
191 }
192 
193 /*
194  *
195  * Helpers
196  *
197  */
198 
199 int
201 {
202  fifo_segment_create_args_t _a, *a = &_a;
204  int rv;
205 
206  clib_memset (a, 0, sizeof (*a));
207  a->segment_name = (char *) name;
208  a->segment_type = type;
209 
210  if (type == SSVM_SEGMENT_MEMFD)
211  a->memfd_fd = fd;
212 
213  if ((rv = fifo_segment_attach (sm, a)))
214  return rv;
216  return 0;
217 }
218 
219 void
220 echo_segment_handle_add_del (echo_main_t * em, u64 segment_handle, u8 add)
221 {
223  if (add)
224  hash_set (em->shared_segment_handles, segment_handle, 1);
225  else
226  hash_unset (em->shared_segment_handles, segment_handle);
228 }
229 
230 /*
231  *
232  * Binary API callbacks
233  *
234  */
235 
236 static void
239 {
240  echo_main_t *em = &echo_main;
241  if (mp->retval)
242  {
243  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY,
244  "Adding cert and key returned %d",
245  clib_net_to_host_u32 (mp->retval));
246  return;
247  }
248  /* No concurrency here, only bapi thread writes */
249  if (em->state != STATE_ATTACHED_NO_CERT)
250  {
251  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY, "Wrong state");
252  return;
253  }
254  em->ckpair_index = clib_net_to_host_u32 (mp->index);
255  em->state = STATE_ATTACHED;
256 }
257 
258 static void
260  (vl_api_app_del_cert_key_pair_reply_t * mp)
261 {
262  echo_main_t *em = &echo_main;
263  if (mp->retval)
264  {
265  ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_DEL_REPLY,
266  "Delete cert and key returned %d",
267  clib_net_to_host_u32 (mp->retval));
268  return;
269  }
271 }
272 
273 static void
275 {
276  echo_main_t *em = &echo_main;
277  int *fds = 0, i, rv;
278  u32 n_fds = 0;
279  u64 segment_handle;
280  char *segment_name = 0;
281 
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->app_mq)
293  {
294  ECHO_FAIL (ECHO_FAIL_VL_API_NULL_APP_MQ, "NULL app_mq");
295  return;
296  }
297  em->app_mq = uword_to_pointer (mp->app_mq, svm_msg_q_t *);
299 
300  if (mp->n_fds)
301  {
302  vec_validate (fds, mp->n_fds);
303  if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
304  {
305  ECHO_FAIL (ECHO_FAIL_VL_API_RECV_FD_MSG,
306  "vl_socket_client_recv_fd_msg failed");
307  goto failed;
308  }
309 
310  if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
311  if (echo_ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++]))
312  {
313  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
314  "svm_fifo_segment_attach failed on SSVM_SEGMENT_MEMFD");
315  goto failed;
316  }
317 
318  if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
319  {
320  segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
321  rv = echo_ssvm_segment_attach (segment_name,
322  SSVM_SEGMENT_MEMFD, fds[n_fds++]);
323  if (rv != 0)
324  {
325  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
326  "svm_fifo_segment_attach ('%s') "
327  "failed on SSVM_SEGMENT_MEMFD", segment_name);
328  vec_free (segment_name);
329  goto failed;
330  }
331  vec_free (segment_name);
332  }
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  {
341  segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
342  rv = echo_ssvm_segment_attach (segment_name, SSVM_SEGMENT_SHM, -1);
343  if (rv != 0)
344  {
345  ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
346  "svm_fifo_segment_attach ('%s') "
347  "failed on SSVM_SEGMENT_SHM", segment_name);
348  vec_free (segment_name);
349  goto failed;
350  }
351  vec_free (segment_name);
352  }
353  echo_segment_handle_add_del (em, segment_handle, 1 /* add */ );
354  ECHO_LOG (2, "Mapped segment 0x%lx", segment_handle);
355 
357  return;
358 failed:
359  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
360  close (fds[i]);
361  vec_free (fds);
362 }
363 
364 static void
365 vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
366  mp)
367 {
368  if (mp->retval)
369  {
370  ECHO_FAIL (ECHO_FAIL_VL_API_DETACH_REPLY,
371  "app detach returned with err: %d", mp->retval);
372  return;
373  }
375 }
376 
377 #define foreach_quic_echo_msg \
378 _(APP_ATTACH_REPLY, app_attach_reply) \
379 _(APPLICATION_DETACH_REPLY, application_detach_reply) \
380 _(APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply) \
381 _(APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)
382 
383 void
385 {
386 #define _(N,n) \
387  vl_msg_api_set_handlers(VL_API_##N, #n, \
388  vl_api_##n##_t_handler, \
389  vl_noop_handler, \
390  vl_api_##n##_t_endian, \
391  vl_api_##n##_t_print, \
392  sizeof(vl_api_##n##_t), 1);
394 #undef _
395 }
396 
397 /*
398  * fd.io coding-style-patch-verification: ON
399  *
400  * Local Variables:
401  * eval: (c-set-style "gnu")
402  * End:
403  */
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:509
string namespace_id[]
Definition: session.api:41
#define hash_set(h, key, value)
Definition: hash.h:255
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:119
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:103
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:538
#define ntohs(x)
Definition: af_xdp.bpf.c:29
void echo_send_del_cert_key(echo_main_t *em)
Definition: vpp_echo_bapi.c:90
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:69
u16 key_len
Definition: ikev2_types.api:95
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:59
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)
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:85
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:235
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:90
clib_error_t * vl_socket_client_recv_fd_msg(int fds[], int n_fds, u32 wait)
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define foreach_quic_echo_msg
uword * shared_segment_handles
#define ECHO_LOG(lvl, _fmt, _args...)
char * vl_api_from_api_to_new_c_string(vl_api_string_t *astr)
Definition: api_shared.c:1204
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:84
string name[64]
Definition: ip.api:44
static const char test_srv_key_rsa[]
Definition: tls_test.h:49
struct echo_main_t::@665 uri_elts
#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)
Application detach from session layer.
Definition: session.api:77
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:320
ssvm_segment_type_t segment_type
type of segment requested
Definition: fifo_segment.h:82
void echo_send_detach(echo_main_t *em)
Definition: vpp_echo_bapi.c:55
int echo_ssvm_segment_attach(char *name, ssvm_segment_type_t type, int fd)
vl_api_address_t ip
Definition: l2.api:501
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:37
Delete certificate and key.
Definition: session.api:114
int vl_api_vec_to_api_string(const u8 *vec, vl_api_string_t *str)
Definition: api_shared.c:1161
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:86