blob: 435a414d0979e756b39317da818ecd7afbaa9a34 [file] [log] [blame]
Dave Barach68b0fb02017-02-28 15:15:56 -05001/*
2 * Copyright (c) 2016 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>
Florin Coras90a63982017-12-19 04:50:01 -080018
19#include <vnet/session/application_interface.h>
Dave Barach68b0fb02017-02-28 15:15:56 -050020#include <svm/svm_fifo_segment.h>
21#include <vlibmemory/api.h>
Florin Coras90a63982017-12-19 04:50:01 -080022
Dave Barach68b0fb02017-02-28 15:15:56 -050023#include <vpp/api/vpe_msg_enum.h>
24
Florin Corase04c2992017-03-01 08:17:34 -080025#define vl_typedefs /* define message structures */
Dave Barach68b0fb02017-02-28 15:15:56 -050026#include <vpp/api/vpe_all_api_h.h>
27#undef vl_typedefs
28
29/* declare message handlers for each api */
30
Florin Corase04c2992017-03-01 08:17:34 -080031#define vl_endianfun /* define message structures */
Dave Barach68b0fb02017-02-28 15:15:56 -050032#include <vpp/api/vpe_all_api_h.h>
33#undef vl_endianfun
34
35/* instantiate all the print functions we know about */
36#define vl_print(handle, ...)
37#define vl_printfun
38#include <vpp/api/vpe_all_api_h.h>
39#undef vl_printfun
40
Florin Corasa849b7b2018-05-18 00:41:55 -070041#define TCP_ECHO_DBG 0
42#define DBG(_fmt,_args...) \
43 if (TCP_ECHO_DBG) \
44 clib_warning (_fmt, _args)
45
Dave Barach68b0fb02017-02-28 15:15:56 -050046typedef struct
47{
Florin Coras9e47ac52019-01-24 23:22:37 -080048 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
49#define _(type, name) type name;
50 foreach_app_session_field
51#undef _
Florin Corasa5464812017-04-19 13:00:05 -070052 u64 vpp_session_handle;
Florin Corasa849b7b2018-05-18 00:41:55 -070053 u64 bytes_sent;
54 u64 bytes_to_send;
55 volatile u64 bytes_received;
56 volatile u64 bytes_to_receive;
Florin Corasf03a59a2017-06-09 21:07:32 -070057 f64 start;
Florin Coras9e47ac52019-01-24 23:22:37 -080058} echo_session_t;
Dave Barach68b0fb02017-02-28 15:15:56 -050059
60typedef enum
61{
62 STATE_START,
Florin Corasa5464812017-04-19 13:00:05 -070063 STATE_ATTACHED,
Florin Coras52207f12018-07-12 14:48:06 -070064 STATE_LISTEN,
Dave Barach68b0fb02017-02-28 15:15:56 -050065 STATE_READY,
66 STATE_DISCONNECTING,
Florin Corasa849b7b2018-05-18 00:41:55 -070067 STATE_FAILED,
68 STATE_DETACHED
Dave Barach68b0fb02017-02-28 15:15:56 -050069} connection_state_t;
70
71typedef struct
72{
73 /* vpe input queue */
Florin Corase86a8ed2018-01-05 03:20:25 -080074 svm_queue_t *vl_input_queue;
Dave Barach68b0fb02017-02-28 15:15:56 -050075
76 /* API client handle */
77 u32 my_client_index;
78
79 /* The URI we're playing with */
Florin Corase04c2992017-03-01 08:17:34 -080080 u8 *uri;
Dave Barach68b0fb02017-02-28 15:15:56 -050081
82 /* Session pool */
Florin Coras9e47ac52019-01-24 23:22:37 -080083 echo_session_t *sessions;
Dave Barach68b0fb02017-02-28 15:15:56 -050084
85 /* Hash table for disconnect processing */
Florin Corase04c2992017-03-01 08:17:34 -080086 uword *session_index_by_vpp_handles;
Dave Barach68b0fb02017-02-28 15:15:56 -050087
88 /* intermediate rx buffer */
Florin Corase04c2992017-03-01 08:17:34 -080089 u8 *rx_buf;
Dave Barach68b0fb02017-02-28 15:15:56 -050090
91 /* URI for slave's connect */
Florin Corase04c2992017-03-01 08:17:34 -080092 u8 *connect_uri;
Dave Barach68b0fb02017-02-28 15:15:56 -050093
94 u32 connected_session_index;
95
96 int i_am_master;
97
98 /* drop all packets */
Florin Coras8e43d042018-05-04 15:46:57 -070099 int no_return;
Dave Barach68b0fb02017-02-28 15:15:56 -0500100
101 /* Our event queue */
Florin Coras3c2fed52018-07-04 04:15:05 -0700102 svm_msg_q_t *our_event_queue;
Dave Barach68b0fb02017-02-28 15:15:56 -0500103
Florin Coras90a63982017-12-19 04:50:01 -0800104 u8 *socket_name;
105
Dave Barach68b0fb02017-02-28 15:15:56 -0500106 pid_t my_pid;
107
108 /* For deadman timers */
109 clib_time_t clib_time;
110
111 /* State of the connection, shared between msg RX thread and main thread */
112 volatile connection_state_t state;
113
114 /* Signal variables */
115 volatile int time_to_stop;
116 volatile int time_to_print_stats;
117
118 u32 configured_segment_size;
119
120 /* VNET_API_ERROR_FOO -> "Foo" hash table */
Florin Corase04c2992017-03-01 08:17:34 -0800121 uword *error_string_by_error_number;
Dave Barach68b0fb02017-02-28 15:15:56 -0500122
123 u8 *connect_test_data;
Florin Corasa849b7b2018-05-18 00:41:55 -0700124 pthread_t *client_thread_handles;
125 u32 *thread_args;
Florin Corase04c2992017-03-01 08:17:34 -0800126 u32 client_bytes_received;
127 u8 test_return_packets;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700128 u64 bytes_to_send;
Florin Coras8e43d042018-05-04 15:46:57 -0700129 u32 fifo_size;
Florin Corase04c2992017-03-01 08:17:34 -0800130
Florin Corasa849b7b2018-05-18 00:41:55 -0700131 u32 n_clients;
132 u64 tx_total;
133 u64 rx_total;
134
135 volatile u32 n_clients_connected;
136 volatile u32 n_active_clients;
137
138
Florin Coras90a63982017-12-19 04:50:01 -0800139 /** Flag that decides if socket, instead of svm, api is used to connect to
140 * vpp. If sock api is used, shm binary api is subsequently bootstrapped
141 * and all other messages are exchanged using shm IPC. */
142 u8 use_sock_api;
143
Florin Corasadc74d72018-12-02 13:36:00 -0800144 svm_fifo_segment_main_t segment_main;
Florin Corasb384b542018-01-15 01:08:33 -0800145} echo_main_t;
Dave Barach68b0fb02017-02-28 15:15:56 -0500146
Florin Corasb384b542018-01-15 01:08:33 -0800147echo_main_t echo_main;
Dave Barach68b0fb02017-02-28 15:15:56 -0500148
149#if CLIB_DEBUG > 0
150#define NITER 10000
151#else
152#define NITER 4000000
153#endif
154
Florin Corasa5464812017-04-19 13:00:05 -0700155static u8 *
156format_api_error (u8 * s, va_list * args)
157{
Florin Corasb384b542018-01-15 01:08:33 -0800158 echo_main_t *em = &echo_main;
Florin Corasa5464812017-04-19 13:00:05 -0700159 i32 error = va_arg (*args, u32);
160 uword *p;
161
Florin Corasb384b542018-01-15 01:08:33 -0800162 p = hash_get (em->error_string_by_error_number, -error);
Florin Corasa5464812017-04-19 13:00:05 -0700163
164 if (p)
165 s = format (s, "%s", p[0]);
166 else
167 s = format (s, "%d", error);
168 return s;
169}
170
171static void
Florin Corasb384b542018-01-15 01:08:33 -0800172init_error_string_table (echo_main_t * em)
Florin Corasa5464812017-04-19 13:00:05 -0700173{
Florin Corasb384b542018-01-15 01:08:33 -0800174 em->error_string_by_error_number = hash_create (0, sizeof (uword));
Florin Corasa5464812017-04-19 13:00:05 -0700175
Florin Corasb384b542018-01-15 01:08:33 -0800176#define _(n,v,s) hash_set (em->error_string_by_error_number, -v, s);
Florin Corasa5464812017-04-19 13:00:05 -0700177 foreach_vnet_api_error;
178#undef _
179
Florin Corasb384b542018-01-15 01:08:33 -0800180 hash_set (em->error_string_by_error_number, 99, "Misc");
Florin Corasa5464812017-04-19 13:00:05 -0700181}
182
Florin Coras52207f12018-07-12 14:48:06 -0700183static void handle_mq_event (session_event_t * e);
184
185static int
Florin Corasb384b542018-01-15 01:08:33 -0800186wait_for_state_change (echo_main_t * em, connection_state_t state)
Dave Barach68b0fb02017-02-28 15:15:56 -0500187{
Florin Coras52207f12018-07-12 14:48:06 -0700188 svm_msg_q_msg_t msg;
189 session_event_t *e;
190 f64 timeout;
191
Dave Barach68b0fb02017-02-28 15:15:56 -0500192#if CLIB_DEBUG > 0
193#define TIMEOUT 600.0
194#else
195#define TIMEOUT 600.0
196#endif
197
Florin Coras52207f12018-07-12 14:48:06 -0700198 timeout = clib_time_now (&em->clib_time) + TIMEOUT;
Dave Barach68b0fb02017-02-28 15:15:56 -0500199
Florin Corasb384b542018-01-15 01:08:33 -0800200 while (clib_time_now (&em->clib_time) < timeout)
Dave Barach68b0fb02017-02-28 15:15:56 -0500201 {
Florin Corasb384b542018-01-15 01:08:33 -0800202 if (em->state == state)
Florin Corase04c2992017-03-01 08:17:34 -0800203 return 0;
Florin Corasb384b542018-01-15 01:08:33 -0800204 if (em->state == STATE_FAILED)
Dave Barach68b0fb02017-02-28 15:15:56 -0500205 return -1;
Florin Corasb384b542018-01-15 01:08:33 -0800206 if (em->time_to_stop == 1)
Florin Corasf03a59a2017-06-09 21:07:32 -0700207 return 0;
Florin Coras99368312018-08-02 10:45:44 -0700208 if (!em->our_event_queue || em->state < STATE_ATTACHED)
Florin Coras52207f12018-07-12 14:48:06 -0700209 continue;
210
211 if (svm_msg_q_sub (em->our_event_queue, &msg, SVM_Q_NOWAIT, 0))
212 continue;
213 e = svm_msg_q_msg_data (em->our_event_queue, &msg);
214 handle_mq_event (e);
215 svm_msg_q_free_msg (em->our_event_queue, &msg);
Dave Barach68b0fb02017-02-28 15:15:56 -0500216 }
Florin Corasa849b7b2018-05-18 00:41:55 -0700217 clib_warning ("timeout waiting for state %d", state);
Dave Barach68b0fb02017-02-28 15:15:56 -0500218 return -1;
219}
220
Florin Coras6cf30ad2017-04-04 23:08:23 -0700221void
Florin Corasb384b542018-01-15 01:08:33 -0800222application_send_attach (echo_main_t * em)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700223{
224 vl_api_application_attach_t *bmp;
Florin Corase3e2f072018-03-04 07:24:30 -0800225 vl_api_application_tls_cert_add_t *cert_mp;
226 vl_api_application_tls_key_add_t *key_mp;
227
Florin Coras6cf30ad2017-04-04 23:08:23 -0700228 bmp = vl_msg_api_alloc (sizeof (*bmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400229 clib_memset (bmp, 0, sizeof (*bmp));
Florin Coras6cf30ad2017-04-04 23:08:23 -0700230
231 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
Florin Corasb384b542018-01-15 01:08:33 -0800232 bmp->client_index = em->my_client_index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700233 bmp->context = ntohl (0xfeedface);
Florin Coras52207f12018-07-12 14:48:06 -0700234 bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
235 bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ADD_SEGMENT;
Dave Barach10d8cc62017-05-30 09:30:07 -0400236 bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 16;
Florin Coras8e43d042018-05-04 15:46:57 -0700237 bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = em->fifo_size;
238 bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = em->fifo_size;
Florin Corasff6e7692017-12-11 04:59:01 -0800239 bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20;
240 bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20;
Florin Corasa849b7b2018-05-18 00:41:55 -0700241 bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = 256;
Florin Corasb384b542018-01-15 01:08:33 -0800242 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
Florin Corase3e2f072018-03-04 07:24:30 -0800243
244 cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + test_srv_crt_rsa_len);
Dave Barachb7b92992018-10-17 10:38:51 -0400245 clib_memset (cert_mp, 0, sizeof (*cert_mp));
Florin Corase3e2f072018-03-04 07:24:30 -0800246 cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD);
247 cert_mp->client_index = em->my_client_index;
248 cert_mp->context = ntohl (0xfeedface);
249 cert_mp->cert_len = clib_host_to_net_u16 (test_srv_crt_rsa_len);
Dave Barach178cf492018-11-13 16:34:13 -0500250 clib_memcpy_fast (cert_mp->cert, test_srv_crt_rsa, test_srv_crt_rsa_len);
Florin Corase3e2f072018-03-04 07:24:30 -0800251 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cert_mp);
252
253 key_mp = vl_msg_api_alloc (sizeof (*key_mp) + test_srv_key_rsa_len);
Dave Barachb7b92992018-10-17 10:38:51 -0400254 clib_memset (key_mp, 0, sizeof (*key_mp) + test_srv_key_rsa_len);
Florin Corase3e2f072018-03-04 07:24:30 -0800255 key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD);
256 key_mp->client_index = em->my_client_index;
257 key_mp->context = ntohl (0xfeedface);
258 key_mp->key_len = clib_host_to_net_u16 (test_srv_key_rsa_len);
Dave Barach178cf492018-11-13 16:34:13 -0500259 clib_memcpy_fast (key_mp->key, test_srv_key_rsa, test_srv_key_rsa_len);
Florin Corase3e2f072018-03-04 07:24:30 -0800260 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & key_mp);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700261}
262
Florin Coras52207f12018-07-12 14:48:06 -0700263static int
Florin Corasb384b542018-01-15 01:08:33 -0800264application_attach (echo_main_t * em)
Florin Corasa5464812017-04-19 13:00:05 -0700265{
Florin Corasb384b542018-01-15 01:08:33 -0800266 application_send_attach (em);
267 if (wait_for_state_change (em, STATE_ATTACHED))
Florin Corasa5464812017-04-19 13:00:05 -0700268 {
269 clib_warning ("timeout waiting for STATE_ATTACHED");
270 return -1;
271 }
272 return 0;
273}
274
Florin Coras6cf30ad2017-04-04 23:08:23 -0700275void
Florin Corasb384b542018-01-15 01:08:33 -0800276application_detach (echo_main_t * em)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700277{
278 vl_api_application_detach_t *bmp;
279 bmp = vl_msg_api_alloc (sizeof (*bmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400280 clib_memset (bmp, 0, sizeof (*bmp));
Florin Coras6cf30ad2017-04-04 23:08:23 -0700281
282 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
Florin Corasb384b542018-01-15 01:08:33 -0800283 bmp->client_index = em->my_client_index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700284 bmp->context = ntohl (0xfeedface);
Florin Corasb384b542018-01-15 01:08:33 -0800285 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
286
Florin Corasa849b7b2018-05-18 00:41:55 -0700287 DBG ("%s", "Sent detach");
Florin Corasb384b542018-01-15 01:08:33 -0800288}
289
290static int
Florin Coras99368312018-08-02 10:45:44 -0700291ssvm_segment_attach (char *name, ssvm_segment_type_t type, int fd)
Florin Corasb384b542018-01-15 01:08:33 -0800292{
293 svm_fifo_segment_create_args_t _a, *a = &_a;
Florin Corasadc74d72018-12-02 13:36:00 -0800294 svm_fifo_segment_main_t *sm = &echo_main.segment_main;
Florin Corasb384b542018-01-15 01:08:33 -0800295 int rv;
296
Dave Barachb7b92992018-10-17 10:38:51 -0400297 clib_memset (a, 0, sizeof (*a));
Florin Corasb384b542018-01-15 01:08:33 -0800298 a->segment_name = (char *) name;
Florin Corasb384b542018-01-15 01:08:33 -0800299 a->segment_type = type;
300
301 if (type == SSVM_SEGMENT_MEMFD)
Florin Coras99368312018-08-02 10:45:44 -0700302 a->memfd_fd = fd;
Florin Corasb384b542018-01-15 01:08:33 -0800303
Florin Corasadc74d72018-12-02 13:36:00 -0800304 if ((rv = svm_fifo_segment_attach (sm, a)))
Florin Corasb384b542018-01-15 01:08:33 -0800305 {
306 clib_warning ("svm_fifo_segment_attach ('%s') failed", name);
307 return rv;
308 }
309
Florin Coras99368312018-08-02 10:45:44 -0700310 vec_reset_length (a->new_segment_indices);
Florin Corasb384b542018-01-15 01:08:33 -0800311 return 0;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700312}
313
314static void
315vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
316 mp)
317{
Florin Corasb384b542018-01-15 01:08:33 -0800318 echo_main_t *em = &echo_main;
Florin Coras99368312018-08-02 10:45:44 -0700319 int *fds = 0;
320 u32 n_fds = 0;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700321
322 if (mp->retval)
323 {
Florin Corasa5464812017-04-19 13:00:05 -0700324 clib_warning ("attach failed: %U", format_api_error,
325 clib_net_to_host_u32 (mp->retval));
Florin Coras99368312018-08-02 10:45:44 -0700326 goto failed;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700327 }
328
329 if (mp->segment_name_length == 0)
330 {
331 clib_warning ("segment_name_length zero");
Florin Coras99368312018-08-02 10:45:44 -0700332 goto failed;
Florin Corasb384b542018-01-15 01:08:33 -0800333 }
334
335 ASSERT (mp->app_event_queue_address);
336 em->our_event_queue = uword_to_pointer (mp->app_event_queue_address,
Florin Coras3c2fed52018-07-04 04:15:05 -0700337 svm_msg_q_t *);
Florin Coras99368312018-08-02 10:45:44 -0700338
339 if (mp->n_fds)
340 {
341 vec_validate (fds, mp->n_fds);
342 vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5);
343
344 if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
345 if (ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++]))
346 goto failed;
347
348 if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
349 if (ssvm_segment_attach ((char *) mp->segment_name,
350 SSVM_SEGMENT_MEMFD, fds[n_fds++]))
351 goto failed;
352
353 if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
354 svm_msg_q_set_consumer_eventfd (em->our_event_queue, fds[n_fds++]);
355
356 vec_free (fds);
357 }
358 else
359 {
360 if (ssvm_segment_attach ((char *) mp->segment_name, SSVM_SEGMENT_SHM,
361 -1))
362 goto failed;
363 }
364
Florin Corasb384b542018-01-15 01:08:33 -0800365 em->state = STATE_ATTACHED;
Florin Coras99368312018-08-02 10:45:44 -0700366 return;
367failed:
368 em->state = STATE_FAILED;
369 return;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700370}
371
372static void
373vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
374 mp)
375{
376 if (mp->retval)
377 clib_warning ("detach returned with err: %d", mp->retval);
Florin Corasa849b7b2018-05-18 00:41:55 -0700378 echo_main.state = STATE_DETACHED;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700379}
380
Dave Barach68b0fb02017-02-28 15:15:56 -0500381static void
Dave Barach68b0fb02017-02-28 15:15:56 -0500382stop_signal (int signum)
383{
Florin Corasb384b542018-01-15 01:08:33 -0800384 echo_main_t *um = &echo_main;
Dave Barach68b0fb02017-02-28 15:15:56 -0500385
386 um->time_to_stop = 1;
387}
388
389static void
390stats_signal (int signum)
391{
Florin Corasb384b542018-01-15 01:08:33 -0800392 echo_main_t *um = &echo_main;
Dave Barach68b0fb02017-02-28 15:15:56 -0500393
394 um->time_to_print_stats = 1;
395}
396
397static clib_error_t *
398setup_signal_handlers (void)
399{
400 signal (SIGINT, stats_signal);
401 signal (SIGQUIT, stop_signal);
402 signal (SIGTERM, stop_signal);
403
404 return 0;
405}
406
407void
408vlib_cli_output (struct vlib_main_t *vm, char *fmt, ...)
409{
410 clib_warning ("BUG");
411}
412
413int
414connect_to_vpp (char *name)
415{
Florin Corasb384b542018-01-15 01:08:33 -0800416 echo_main_t *em = &echo_main;
Dave Barach68b0fb02017-02-28 15:15:56 -0500417 api_main_t *am = &api_main;
418
Florin Corasb384b542018-01-15 01:08:33 -0800419 if (em->use_sock_api)
Florin Coras90a63982017-12-19 04:50:01 -0800420 {
Florin Corasb384b542018-01-15 01:08:33 -0800421 if (vl_socket_client_connect ((char *) em->socket_name, name,
Florin Coras90a63982017-12-19 04:50:01 -0800422 0 /* default rx, tx buffer */ ))
Florin Corasb384b542018-01-15 01:08:33 -0800423 {
424 clib_warning ("socket connect failed");
425 return -1;
426 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500427
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +0100428 if (vl_socket_client_init_shm (0, 1 /* want_pthread */ ))
Florin Corasb384b542018-01-15 01:08:33 -0800429 {
430 clib_warning ("init shm api failed");
431 return -1;
432 }
Florin Coras90a63982017-12-19 04:50:01 -0800433 }
434 else
435 {
436 if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
Florin Corasb384b542018-01-15 01:08:33 -0800437 {
438 clib_warning ("shmem connect failed");
439 return -1;
440 }
Florin Coras90a63982017-12-19 04:50:01 -0800441 }
Florin Corasb384b542018-01-15 01:08:33 -0800442 em->vl_input_queue = am->shmem_hdr->vl_input_queue;
443 em->my_client_index = am->my_client_index;
Dave Barach68b0fb02017-02-28 15:15:56 -0500444 return 0;
445}
446
Florin Coras90a63982017-12-19 04:50:01 -0800447void
Florin Corasb384b542018-01-15 01:08:33 -0800448disconnect_from_vpp (echo_main_t * em)
Florin Coras90a63982017-12-19 04:50:01 -0800449{
Florin Corasb384b542018-01-15 01:08:33 -0800450 if (em->use_sock_api)
Florin Coras90a63982017-12-19 04:50:01 -0800451 vl_socket_client_disconnect ();
452 else
453 vl_client_disconnect_from_vlib ();
454}
455
Dave Barach68b0fb02017-02-28 15:15:56 -0500456static void
Florin Corase04c2992017-03-01 08:17:34 -0800457vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
Dave Barach68b0fb02017-02-28 15:15:56 -0500458{
Florin Corasadc74d72018-12-02 13:36:00 -0800459 svm_fifo_segment_main_t *sm = &echo_main.segment_main;
Dave Barach68b0fb02017-02-28 15:15:56 -0500460 svm_fifo_segment_create_args_t _a, *a = &_a;
461 int rv;
462
Dave Barachb7b92992018-10-17 10:38:51 -0400463 clib_memset (a, 0, sizeof (*a));
Dave Barach68b0fb02017-02-28 15:15:56 -0500464 a->segment_name = (char *) mp->segment_name;
465 a->segment_size = mp->segment_size;
466 /* Attach to the segment vpp created */
Florin Corasadc74d72018-12-02 13:36:00 -0800467 rv = svm_fifo_segment_attach (sm, a);
Dave Barach68b0fb02017-02-28 15:15:56 -0500468 if (rv)
469 {
470 clib_warning ("svm_fifo_segment_attach ('%s') failed",
Florin Corase04c2992017-03-01 08:17:34 -0800471 mp->segment_name);
Dave Barach68b0fb02017-02-28 15:15:56 -0500472 return;
473 }
474 clib_warning ("Mapped new segment '%s' size %d", mp->segment_name,
Florin Corase04c2992017-03-01 08:17:34 -0800475 mp->segment_size);
Dave Barach68b0fb02017-02-28 15:15:56 -0500476}
477
478static void
Florin Coras9e47ac52019-01-24 23:22:37 -0800479session_print_stats (echo_main_t * em, echo_session_t * session)
Florin Corasf03a59a2017-06-09 21:07:32 -0700480{
481 f64 deltat;
482 u64 bytes;
483
Florin Corasb384b542018-01-15 01:08:33 -0800484 deltat = clib_time_now (&em->clib_time) - session->start;
485 bytes = em->i_am_master ? session->bytes_received : em->bytes_to_send;
Florin Corasf03a59a2017-06-09 21:07:32 -0700486 fformat (stdout, "Finished in %.6f\n", deltat);
487 fformat (stdout, "%.4f Gbit/second\n", (bytes * 8.0) / deltat / 1e9);
488}
489
490static void
Florin Coras9e47ac52019-01-24 23:22:37 -0800491test_recv_bytes (echo_session_t * s, u8 * rx_buf, u32 n_read)
Dave Barach68b0fb02017-02-28 15:15:56 -0500492{
Florin Corasa849b7b2018-05-18 00:41:55 -0700493 int i;
494 for (i = 0; i < n_read; i++)
495 {
496 if (rx_buf[i] != ((s->bytes_received + i) & 0xff))
497 {
498 clib_warning ("error at byte %lld, 0x%x not 0x%x",
499 s->bytes_received + i, rx_buf[i],
500 ((s->bytes_received + i) & 0xff));
501 }
502 }
503}
Dave Barach68b0fb02017-02-28 15:15:56 -0500504
Florin Corasa849b7b2018-05-18 00:41:55 -0700505static void
Florin Coras9e47ac52019-01-24 23:22:37 -0800506recv_data_chunk (echo_main_t * em, echo_session_t * s, u8 * rx_buf)
Florin Corasa849b7b2018-05-18 00:41:55 -0700507{
Florin Coras9e47ac52019-01-24 23:22:37 -0800508 int n_to_read, n_read;
Dave Barach68b0fb02017-02-28 15:15:56 -0500509
Florin Coras9e47ac52019-01-24 23:22:37 -0800510 n_to_read = svm_fifo_max_dequeue (s->rx_fifo);
511 if (!n_to_read)
512 return;
Florin Coras6792ec02017-03-13 03:49:51 -0700513
Dave Barach68b0fb02017-02-28 15:15:56 -0500514 do
515 {
Florin Coras9e47ac52019-01-24 23:22:37 -0800516 n_read = app_recv_stream ((app_session_t *) s, rx_buf,
517 vec_len (rx_buf));
518
519 if (n_read > 0)
520 {
521 if (em->test_return_packets)
522 test_recv_bytes (s, rx_buf, n_read);
523
524 n_to_read -= n_read;
525
526 s->bytes_received += n_read;
527 s->bytes_to_receive -= n_read;
528 }
529 else
Florin Corasa849b7b2018-05-18 00:41:55 -0700530 break;
Dave Barach68b0fb02017-02-28 15:15:56 -0500531 }
Florin Corasa849b7b2018-05-18 00:41:55 -0700532 while (n_to_read > 0);
Dave Barach68b0fb02017-02-28 15:15:56 -0500533}
534
535void
Florin Coras9e47ac52019-01-24 23:22:37 -0800536client_handle_rx (echo_main_t * em, session_event_t * e, u8 * rx_buf)
Dave Barach68b0fb02017-02-28 15:15:56 -0500537{
Florin Coras9e47ac52019-01-24 23:22:37 -0800538 echo_session_t *s;
Dave Barach68b0fb02017-02-28 15:15:56 -0500539
Florin Corasa849b7b2018-05-18 00:41:55 -0700540 s = pool_elt_at_index (em->sessions, e->fifo->client_session_index);
Florin Coras9e47ac52019-01-24 23:22:37 -0800541 recv_data_chunk (em, s, rx_buf);
Florin Corasa849b7b2018-05-18 00:41:55 -0700542}
543
544static void
Florin Coras9e47ac52019-01-24 23:22:37 -0800545send_data_chunk (echo_main_t * em, echo_session_t * s)
Florin Corasa849b7b2018-05-18 00:41:55 -0700546{
547 u64 test_buf_len, bytes_this_chunk, test_buf_offset;
Florin Corasa849b7b2018-05-18 00:41:55 -0700548 u8 *test_data = em->connect_test_data;
Florin Coras9e47ac52019-01-24 23:22:37 -0800549 int n_sent;
Florin Corasa849b7b2018-05-18 00:41:55 -0700550
551 test_buf_len = vec_len (test_data);
552 test_buf_offset = s->bytes_sent % test_buf_len;
553 bytes_this_chunk = clib_min (test_buf_len - test_buf_offset,
554 s->bytes_to_send);
Florin Corasa849b7b2018-05-18 00:41:55 -0700555
Florin Coras9e47ac52019-01-24 23:22:37 -0800556 n_sent = app_send_stream ((app_session_t *) s, test_data + test_buf_offset,
557 bytes_this_chunk, 0);
Florin Corasa849b7b2018-05-18 00:41:55 -0700558
Florin Coras9e47ac52019-01-24 23:22:37 -0800559 if (n_sent > 0)
Dave Barach68b0fb02017-02-28 15:15:56 -0500560 {
Florin Coras9e47ac52019-01-24 23:22:37 -0800561 s->bytes_to_send -= n_sent;
562 s->bytes_sent += n_sent;
Dave Barach68b0fb02017-02-28 15:15:56 -0500563 }
564}
565
Florin Corasa849b7b2018-05-18 00:41:55 -0700566/*
567 * Rx/Tx polling thread per connection
568 */
Florin Corase04c2992017-03-01 08:17:34 -0800569static void *
Florin Corasa849b7b2018-05-18 00:41:55 -0700570client_thread_fn (void *arg)
571{
572 echo_main_t *em = &echo_main;
573 static u8 *rx_buf = 0;
574 u32 session_index = *(u32 *) arg;
Florin Coras9e47ac52019-01-24 23:22:37 -0800575 echo_session_t *s;
Florin Corasa849b7b2018-05-18 00:41:55 -0700576
577 vec_validate (rx_buf, 1 << 20);
578
579 while (!em->time_to_stop && em->state != STATE_READY)
580 ;
581
582 s = pool_elt_at_index (em->sessions, session_index);
583 while (!em->time_to_stop)
584 {
Florin Coras9e47ac52019-01-24 23:22:37 -0800585 send_data_chunk (em, s);
586 recv_data_chunk (em, s, rx_buf);
Florin Corasa849b7b2018-05-18 00:41:55 -0700587 if (!s->bytes_to_send && !s->bytes_to_receive)
588 break;
589 }
590
591 DBG ("session %d done", session_index);
592 em->tx_total += s->bytes_sent;
593 em->rx_total += s->bytes_received;
594 em->n_active_clients--;
595
596 pthread_exit (0);
597}
598
599/*
600 * Rx thread that handles all connections.
601 *
602 * Not used.
603 */
604void *
Florin Corase04c2992017-03-01 08:17:34 -0800605client_rx_thread_fn (void *arg)
Dave Barach68b0fb02017-02-28 15:15:56 -0500606{
Florin Coras52207f12018-07-12 14:48:06 -0700607 session_event_t _e, *e = &_e;
Florin Corasb384b542018-01-15 01:08:33 -0800608 echo_main_t *em = &echo_main;
Florin Corasa849b7b2018-05-18 00:41:55 -0700609 static u8 *rx_buf = 0;
Florin Coras3c2fed52018-07-04 04:15:05 -0700610 svm_msg_q_msg_t msg;
Dave Barach68b0fb02017-02-28 15:15:56 -0500611
Florin Corasa849b7b2018-05-18 00:41:55 -0700612 vec_validate (rx_buf, 1 << 20);
613
614 while (!em->time_to_stop && em->state != STATE_READY)
615 ;
616
617 while (!em->time_to_stop)
Dave Barach68b0fb02017-02-28 15:15:56 -0500618 {
Florin Coras3c2fed52018-07-04 04:15:05 -0700619 svm_msg_q_sub (em->our_event_queue, &msg, SVM_Q_WAIT, 0);
620 e = svm_msg_q_msg_data (em->our_event_queue, &msg);
Dave Barach68b0fb02017-02-28 15:15:56 -0500621 switch (e->event_type)
Florin Corase04c2992017-03-01 08:17:34 -0800622 {
Florin Corasa5464812017-04-19 13:00:05 -0700623 case FIFO_EVENT_APP_RX:
Florin Coras9e47ac52019-01-24 23:22:37 -0800624 client_handle_rx (em, e, rx_buf);
Florin Corase04c2992017-03-01 08:17:34 -0800625 break;
Florin Corase04c2992017-03-01 08:17:34 -0800626 default:
627 clib_warning ("unknown event type %d", e->event_type);
628 break;
629 }
Florin Coras3c2fed52018-07-04 04:15:05 -0700630 svm_msg_q_free_msg (em->our_event_queue, &msg);
Dave Barach68b0fb02017-02-28 15:15:56 -0500631 }
Florin Corase04c2992017-03-01 08:17:34 -0800632 pthread_exit (0);
Dave Barach68b0fb02017-02-28 15:15:56 -0500633}
634
Florin Coras52207f12018-07-12 14:48:06 -0700635void
636client_send_connect (echo_main_t * em)
637{
638 vl_api_connect_uri_t *cmp;
639 cmp = vl_msg_api_alloc (sizeof (*cmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400640 clib_memset (cmp, 0, sizeof (*cmp));
Florin Coras52207f12018-07-12 14:48:06 -0700641
642 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_URI);
643 cmp->client_index = em->my_client_index;
644 cmp->context = ntohl (0xfeedface);
645 memcpy (cmp->uri, em->connect_uri, vec_len (em->connect_uri));
646 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cmp);
647}
648
649void
Florin Coras9e47ac52019-01-24 23:22:37 -0800650client_send_disconnect (echo_main_t * em, echo_session_t * s)
Florin Coras52207f12018-07-12 14:48:06 -0700651{
652 vl_api_disconnect_session_t *dmp;
653 dmp = vl_msg_api_alloc (sizeof (*dmp));
Dave Barachb7b92992018-10-17 10:38:51 -0400654 clib_memset (dmp, 0, sizeof (*dmp));
Florin Coras52207f12018-07-12 14:48:06 -0700655 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
656 dmp->client_index = em->my_client_index;
657 dmp->handle = s->vpp_session_handle;
658 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & dmp);
659}
660
661int
Florin Coras9e47ac52019-01-24 23:22:37 -0800662client_disconnect (echo_main_t * em, echo_session_t * s)
Florin Coras52207f12018-07-12 14:48:06 -0700663{
664 client_send_disconnect (em, s);
665 pool_put (em->sessions, s);
Dave Barachb7b92992018-10-17 10:38:51 -0400666 clib_memset (s, 0xfe, sizeof (*s));
Florin Coras52207f12018-07-12 14:48:06 -0700667 return 0;
668}
669
Dave Barach68b0fb02017-02-28 15:15:56 -0500670static void
Florin Coras9e47ac52019-01-24 23:22:37 -0800671session_bound_handler (session_bound_msg_t * mp)
672{
673 echo_main_t *em = &echo_main;
674
675 if (mp->retval)
676 {
677 clib_warning ("bind failed: %U", format_api_error,
678 clib_net_to_host_u32 (mp->retval));
679 em->state = STATE_FAILED;
680 return;
681 }
682
683 clib_warning ("listening on %U:%u", format_ip46_address, mp->lcl_ip,
684 mp->lcl_is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, mp->lcl_port);
685 em->state = STATE_READY;
686}
687
688static void
Florin Coras52207f12018-07-12 14:48:06 -0700689session_accepted_handler (session_accepted_msg_t * mp)
690{
691 app_session_evt_t _app_evt, *app_evt = &_app_evt;
692 session_accepted_reply_msg_t *rmp;
693 svm_fifo_t *rx_fifo, *tx_fifo;
694 echo_main_t *em = &echo_main;
Florin Coras9e47ac52019-01-24 23:22:37 -0800695 echo_session_t *session;
Florin Coras52207f12018-07-12 14:48:06 -0700696 static f64 start_time;
697 u32 session_index;
698 u8 *ip_str;
699
700 if (start_time == 0.0)
701 start_time = clib_time_now (&em->clib_time);
702
703 ip_str = format (0, "%U", format_ip46_address, &mp->ip, mp->is_ip4);
704 clib_warning ("Accepted session from: %s:%d", ip_str,
705 clib_net_to_host_u16 (mp->port));
706
707 /* Allocate local session and set it up */
708 pool_get (em->sessions, session);
709 session_index = session - em->sessions;
710
711 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
712 rx_fifo->client_session_index = session_index;
713 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
714 tx_fifo->client_session_index = session_index;
715
Florin Coras9e47ac52019-01-24 23:22:37 -0800716 session->rx_fifo = rx_fifo;
717 session->tx_fifo = tx_fifo;
Florin Coras52207f12018-07-12 14:48:06 -0700718 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
719 svm_msg_q_t *);
720
721 /* Add it to lookup table */
722 hash_set (em->session_index_by_vpp_handles, mp->handle, session_index);
723
724 em->state = STATE_READY;
725
726 /* Stats printing */
727 if (pool_elts (em->sessions) && (pool_elts (em->sessions) % 20000) == 0)
728 {
729 f64 now = clib_time_now (&em->clib_time);
730 fformat (stdout, "%d active sessions in %.2f seconds, %.2f/sec...\n",
731 pool_elts (em->sessions), now - start_time,
732 (f64) pool_elts (em->sessions) / (now - start_time));
733 }
734
735 /*
736 * Send accept reply to vpp
737 */
738 app_alloc_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt,
739 SESSION_CTRL_EVT_ACCEPTED_REPLY);
740 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
741 rmp->handle = mp->handle;
742 rmp->context = mp->context;
743 app_send_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt);
744
745 session->bytes_received = 0;
746 session->start = clib_time_now (&em->clib_time);
747}
748
749static void
750session_connected_handler (session_connected_msg_t * mp)
Dave Barach68b0fb02017-02-28 15:15:56 -0500751{
Florin Corasb384b542018-01-15 01:08:33 -0800752 echo_main_t *em = &echo_main;
Florin Coras9e47ac52019-01-24 23:22:37 -0800753 echo_session_t *session;
Dave Barach68b0fb02017-02-28 15:15:56 -0500754 u32 session_index;
755 svm_fifo_t *rx_fifo, *tx_fifo;
756 int rv;
757
758 if (mp->retval)
759 {
Florin Corasa5464812017-04-19 13:00:05 -0700760 clib_warning ("connection failed with code: %U", format_api_error,
761 clib_net_to_host_u32 (mp->retval));
Florin Corasb384b542018-01-15 01:08:33 -0800762 em->state = STATE_FAILED;
Dave Barach68b0fb02017-02-28 15:15:56 -0500763 return;
764 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500765
766 /*
767 * Setup session
768 */
769
Florin Corasb384b542018-01-15 01:08:33 -0800770 pool_get (em->sessions, session);
Dave Barachb7b92992018-10-17 10:38:51 -0400771 clib_memset (session, 0, sizeof (*session));
Florin Corasb384b542018-01-15 01:08:33 -0800772 session_index = session - em->sessions;
Dave Barach68b0fb02017-02-28 15:15:56 -0500773
Damjan Marion7bee80c2017-04-26 15:32:12 +0200774 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
Dave Barach68b0fb02017-02-28 15:15:56 -0500775 rx_fifo->client_session_index = session_index;
Damjan Marion7bee80c2017-04-26 15:32:12 +0200776 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
Dave Barach68b0fb02017-02-28 15:15:56 -0500777 tx_fifo->client_session_index = session_index;
778
Florin Coras9e47ac52019-01-24 23:22:37 -0800779 session->rx_fifo = rx_fifo;
780 session->tx_fifo = tx_fifo;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700781 session->vpp_session_handle = mp->handle;
Florin Corasb384b542018-01-15 01:08:33 -0800782 session->start = clib_time_now (&em->clib_time);
Florin Corasa849b7b2018-05-18 00:41:55 -0700783 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
Florin Coras3c2fed52018-07-04 04:15:05 -0700784 svm_msg_q_t *);
Dave Barach68b0fb02017-02-28 15:15:56 -0500785
Florin Corasb384b542018-01-15 01:08:33 -0800786 hash_set (em->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corase04c2992017-03-01 08:17:34 -0800787
Florin Corasa849b7b2018-05-18 00:41:55 -0700788 /*
789 * Start RX thread
790 */
791 em->thread_args[em->n_clients_connected] = session_index;
792 rv = pthread_create (&em->client_thread_handles[em->n_clients_connected],
793 NULL /*attr */ , client_thread_fn,
794 (void *) &em->thread_args[em->n_clients_connected]);
Florin Corase04c2992017-03-01 08:17:34 -0800795 if (rv)
796 {
797 clib_warning ("pthread_create returned %d", rv);
Florin Corasa849b7b2018-05-18 00:41:55 -0700798 return;
Florin Coras6792ec02017-03-13 03:49:51 -0700799 }
800
Florin Corasa849b7b2018-05-18 00:41:55 -0700801 em->n_clients_connected += 1;
802 clib_warning ("session %u (0x%llx) connected with local ip %U port %d",
803 session_index, mp->handle, format_ip46_address, mp->lcl_ip,
804 mp->is_ip4, clib_net_to_host_u16 (mp->lcl_port));
Florin Corase04c2992017-03-01 08:17:34 -0800805}
806
Florin Coras52207f12018-07-12 14:48:06 -0700807static void
808session_disconnected_handler (session_disconnected_msg_t * mp)
Florin Corase04c2992017-03-01 08:17:34 -0800809{
Florin Coras52207f12018-07-12 14:48:06 -0700810 app_session_evt_t _app_evt, *app_evt = &_app_evt;
811 session_disconnected_reply_msg_t *rmp;
812 echo_main_t *em = &echo_main;
Florin Coras9e47ac52019-01-24 23:22:37 -0800813 echo_session_t *session = 0;
Florin Coras52207f12018-07-12 14:48:06 -0700814 uword *p;
815 int rv = 0;
Florin Corase04c2992017-03-01 08:17:34 -0800816
Florin Coras52207f12018-07-12 14:48:06 -0700817 p = hash_get (em->session_index_by_vpp_handles, mp->handle);
Florin Coras3d0fadc2018-07-17 05:35:47 -0700818 if (!p)
Florin Coras52207f12018-07-12 14:48:06 -0700819 {
820 clib_warning ("couldn't find session key %llx", mp->handle);
Florin Coras3d0fadc2018-07-17 05:35:47 -0700821 return;
Florin Coras52207f12018-07-12 14:48:06 -0700822 }
823
Florin Coras3d0fadc2018-07-17 05:35:47 -0700824 session = pool_elt_at_index (em->sessions, p[0]);
825 hash_unset (em->session_index_by_vpp_handles, mp->handle);
826 pool_put (em->sessions, session);
827
Florin Coras52207f12018-07-12 14:48:06 -0700828 app_alloc_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt,
829 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
830 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
831 rmp->retval = rv;
832 rmp->handle = mp->handle;
833 rmp->context = mp->context;
834 app_send_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt);
835
Florin Coras3d0fadc2018-07-17 05:35:47 -0700836 session_print_stats (em, session);
Florin Corase04c2992017-03-01 08:17:34 -0800837}
838
Florin Coras52207f12018-07-12 14:48:06 -0700839static void
840session_reset_handler (session_reset_msg_t * mp)
Florin Corase04c2992017-03-01 08:17:34 -0800841{
Florin Coras52207f12018-07-12 14:48:06 -0700842 app_session_evt_t _app_evt, *app_evt = &_app_evt;
843 echo_main_t *em = &echo_main;
844 session_reset_reply_msg_t *rmp;
Florin Coras9e47ac52019-01-24 23:22:37 -0800845 echo_session_t *session = 0;
Florin Coras52207f12018-07-12 14:48:06 -0700846 uword *p;
847 int rv = 0;
848
849 p = hash_get (em->session_index_by_vpp_handles, mp->handle);
850
851 if (p)
852 {
853 session = pool_elt_at_index (em->sessions, p[0]);
854 clib_warning ("got reset");
855 /* Cleanup later */
856 em->time_to_stop = 1;
857 }
858 else
859 {
860 clib_warning ("couldn't find session key %llx", mp->handle);
861 return;
862 }
863
864 app_alloc_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt,
865 SESSION_CTRL_EVT_RESET_REPLY);
866 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
867 rmp->retval = rv;
868 rmp->handle = mp->handle;
869 app_send_ctrl_evt_to_vpp (session->vpp_evt_q, app_evt);
Florin Corase04c2992017-03-01 08:17:34 -0800870}
871
Florin Coras52207f12018-07-12 14:48:06 -0700872static void
873handle_mq_event (session_event_t * e)
Florin Corasa5464812017-04-19 13:00:05 -0700874{
Florin Coras52207f12018-07-12 14:48:06 -0700875 switch (e->event_type)
876 {
Florin Coras9e47ac52019-01-24 23:22:37 -0800877 case SESSION_CTRL_EVT_BOUND:
878 session_bound_handler ((session_bound_msg_t *) e->data);
879 break;
Florin Coras52207f12018-07-12 14:48:06 -0700880 case SESSION_CTRL_EVT_ACCEPTED:
881 session_accepted_handler ((session_accepted_msg_t *) e->data);
882 break;
883 case SESSION_CTRL_EVT_CONNECTED:
884 session_connected_handler ((session_connected_msg_t *) e->data);
885 break;
886 case SESSION_CTRL_EVT_DISCONNECTED:
887 session_disconnected_handler ((session_disconnected_msg_t *) e->data);
888 break;
889 case SESSION_CTRL_EVT_RESET:
890 session_reset_handler ((session_reset_msg_t *) e->data);
891 break;
892 default:
893 clib_warning ("unhandled %u", e->event_type);
894 }
Florin Corasa5464812017-04-19 13:00:05 -0700895}
896
Florin Corase04c2992017-03-01 08:17:34 -0800897static void
Florin Corasa849b7b2018-05-18 00:41:55 -0700898clients_run (echo_main_t * em)
Florin Corase04c2992017-03-01 08:17:34 -0800899{
Florin Corasa849b7b2018-05-18 00:41:55 -0700900 f64 start_time, deltat, timeout = 100.0;
Florin Coras3c2fed52018-07-04 04:15:05 -0700901 svm_msg_q_msg_t msg;
Florin Coras52207f12018-07-12 14:48:06 -0700902 session_event_t *e;
Florin Coras9e47ac52019-01-24 23:22:37 -0800903 echo_session_t *s;
Florin Corase04c2992017-03-01 08:17:34 -0800904 int i;
905
Florin Corase04c2992017-03-01 08:17:34 -0800906 /* Init test data */
Florin Coras8e43d042018-05-04 15:46:57 -0700907 vec_validate (em->connect_test_data, 1024 * 1024 - 1);
Florin Corasb384b542018-01-15 01:08:33 -0800908 for (i = 0; i < vec_len (em->connect_test_data); i++)
909 em->connect_test_data[i] = i & 0xff;
Florin Corase04c2992017-03-01 08:17:34 -0800910
Florin Corasa849b7b2018-05-18 00:41:55 -0700911 /*
912 * Attach and connect the clients
913 */
914 if (application_attach (em))
915 return;
Florin Corase04c2992017-03-01 08:17:34 -0800916
Florin Corasa849b7b2018-05-18 00:41:55 -0700917 for (i = 0; i < em->n_clients; i++)
918 client_send_connect (em);
919
920 start_time = clib_time_now (&em->clib_time);
921 while (em->n_clients_connected < em->n_clients
922 && (clib_time_now (&em->clib_time) - start_time < timeout)
923 && em->state != STATE_FAILED)
Florin Coras52207f12018-07-12 14:48:06 -0700924
925 {
926 svm_msg_q_sub (em->our_event_queue, &msg, SVM_Q_WAIT, 0);
927 e = svm_msg_q_msg_data (em->our_event_queue, &msg);
928 handle_mq_event (e);
929 svm_msg_q_free_msg (em->our_event_queue, &msg);
930 }
Florin Corasa849b7b2018-05-18 00:41:55 -0700931
932 if (em->n_clients_connected != em->n_clients)
933 {
934 clib_warning ("failed to initialize all connections");
935 return;
936 }
937
938 /*
939 * Initialize connections
940 */
941 for (i = 0; i < em->n_clients; i++)
942 {
943 s = pool_elt_at_index (em->sessions, i);
944 s->bytes_to_send = em->bytes_to_send;
945 if (!em->no_return)
946 s->bytes_to_receive = em->bytes_to_send;
947 }
948 em->n_active_clients = em->n_clients_connected;
949
950 /*
951 * Wait for client threads to send the data
952 */
953 start_time = clib_time_now (&em->clib_time);
954 em->state = STATE_READY;
955 while (em->n_active_clients)
Florin Coras3c2fed52018-07-04 04:15:05 -0700956 if (!svm_msg_q_is_empty (em->our_event_queue))
957 {
958 if (svm_msg_q_sub (em->our_event_queue, &msg, SVM_Q_WAIT, 0))
959 {
960 clib_warning ("svm msg q returned");
Florin Coras52207f12018-07-12 14:48:06 -0700961 continue;
Florin Coras3c2fed52018-07-04 04:15:05 -0700962 }
Florin Coras52207f12018-07-12 14:48:06 -0700963 e = svm_msg_q_msg_data (em->our_event_queue, &msg);
964 if (e->event_type != FIFO_EVENT_APP_RX)
965 handle_mq_event (e);
966 svm_msg_q_free_msg (em->our_event_queue, &msg);
Florin Coras3c2fed52018-07-04 04:15:05 -0700967 }
Florin Corasa849b7b2018-05-18 00:41:55 -0700968
969 for (i = 0; i < em->n_clients; i++)
970 {
971 s = pool_elt_at_index (em->sessions, i);
972 client_disconnect (em, s);
973 }
974
975 /*
976 * Stats and detach
977 */
978 deltat = clib_time_now (&em->clib_time) - start_time;
979 fformat (stdout, "%lld bytes (%lld mbytes, %lld gbytes) in %.2f seconds\n",
980 em->tx_total, em->tx_total / (1ULL << 20),
981 em->tx_total / (1ULL << 30), deltat);
982 fformat (stdout, "%.4f Gbit/second\n", (em->tx_total * 8.0) / deltat / 1e9);
983
Florin Corasb384b542018-01-15 01:08:33 -0800984 application_detach (em);
Florin Corase04c2992017-03-01 08:17:34 -0800985}
986
987static void
988vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp)
989{
Florin Corasb384b542018-01-15 01:08:33 -0800990 echo_main_t *em = &echo_main;
Florin Corase04c2992017-03-01 08:17:34 -0800991
992 if (mp->retval)
993 {
flyingeagle23a07779f2017-04-26 20:22:04 +0800994 clib_warning ("bind failed: %U", format_api_error,
Florin Corasa5464812017-04-19 13:00:05 -0700995 clib_net_to_host_u32 (mp->retval));
Florin Corasb384b542018-01-15 01:08:33 -0800996 em->state = STATE_FAILED;
Florin Corase04c2992017-03-01 08:17:34 -0800997 return;
998 }
999
Florin Corasb384b542018-01-15 01:08:33 -08001000 em->state = STATE_READY;
Dave Barach68b0fb02017-02-28 15:15:56 -05001001}
1002
Dave Barach68b0fb02017-02-28 15:15:56 -05001003static void
Florin Corase04c2992017-03-01 08:17:34 -08001004vl_api_unbind_uri_reply_t_handler (vl_api_unbind_uri_reply_t * mp)
Dave Barach68b0fb02017-02-28 15:15:56 -05001005{
Florin Corasb384b542018-01-15 01:08:33 -08001006 echo_main_t *em = &echo_main;
Dave Barach68b0fb02017-02-28 15:15:56 -05001007
1008 if (mp->retval != 0)
Florin Corase04c2992017-03-01 08:17:34 -08001009 clib_warning ("returned %d", ntohl (mp->retval));
Dave Barach68b0fb02017-02-28 15:15:56 -05001010
Florin Corasb384b542018-01-15 01:08:33 -08001011 em->state = STATE_START;
Dave Barach68b0fb02017-02-28 15:15:56 -05001012}
1013
Florin Coras6cf30ad2017-04-04 23:08:23 -07001014u8 *
1015format_ip4_address (u8 * s, va_list * args)
1016{
1017 u8 *a = va_arg (*args, u8 *);
1018 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1019}
1020
1021u8 *
1022format_ip6_address (u8 * s, va_list * args)
1023{
1024 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1025 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1026
1027 i_max_n_zero = ARRAY_LEN (a->as_u16);
1028 max_n_zeros = 0;
1029 i_first_zero = i_max_n_zero;
1030 n_zeros = 0;
1031 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1032 {
1033 u32 is_zero = a->as_u16[i] == 0;
1034 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1035 {
1036 i_first_zero = i;
1037 n_zeros = 0;
1038 }
1039 n_zeros += is_zero;
1040 if ((!is_zero && n_zeros > max_n_zeros)
1041 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1042 {
1043 i_max_n_zero = i_first_zero;
1044 max_n_zeros = n_zeros;
1045 i_first_zero = ARRAY_LEN (a->as_u16);
1046 n_zeros = 0;
1047 }
1048 }
1049
1050 last_double_colon = 0;
1051 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1052 {
1053 if (i == i_max_n_zero && max_n_zeros > 1)
1054 {
1055 s = format (s, "::");
1056 i += max_n_zeros - 1;
1057 last_double_colon = 1;
1058 }
1059 else
1060 {
1061 s = format (s, "%s%x",
1062 (last_double_colon || i == 0) ? "" : ":",
1063 clib_net_to_host_u16 (a->as_u16[i]));
1064 last_double_colon = 0;
1065 }
1066 }
1067
1068 return s;
1069}
1070
1071/* Format an IP46 address. */
1072u8 *
1073format_ip46_address (u8 * s, va_list * args)
1074{
1075 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1076 ip46_type_t type = va_arg (*args, ip46_type_t);
1077 int is_ip4 = 1;
1078
1079 switch (type)
1080 {
1081 case IP46_TYPE_ANY:
1082 is_ip4 = ip46_address_is_ip4 (ip46);
1083 break;
1084 case IP46_TYPE_IP4:
1085 is_ip4 = 1;
1086 break;
1087 case IP46_TYPE_IP6:
1088 is_ip4 = 0;
1089 break;
1090 }
1091
1092 return is_ip4 ?
1093 format (s, "%U", format_ip4_address, &ip46->ip4) :
1094 format (s, "%U", format_ip6_address, &ip46->ip6);
1095}
1096
Dave Barach68b0fb02017-02-28 15:15:56 -05001097static void
Florin Coras9e47ac52019-01-24 23:22:37 -08001098server_handle_rx (echo_main_t * em, session_event_t * e)
Dave Barach68b0fb02017-02-28 15:15:56 -05001099{
Florin Coras9e47ac52019-01-24 23:22:37 -08001100 int n_read, max_dequeue, n_sent;
1101 u32 offset, to_dequeue;
1102 echo_session_t *s;
Florin Corase04c2992017-03-01 08:17:34 -08001103
Florin Coras9e47ac52019-01-24 23:22:37 -08001104 s = pool_elt_at_index (em->sessions, e->fifo->client_session_index);
Florin Corase04c2992017-03-01 08:17:34 -08001105
Florin Coras9e47ac52019-01-24 23:22:37 -08001106 /* Clear event only once. Otherwise, if we do it in the loop by calling
1107 * app_recv_stream, we may end up with a lot of unhandled rx events on the
1108 * message queue */
1109 svm_fifo_unset_event (s->rx_fifo);
Florin Coras6792ec02017-03-13 03:49:51 -07001110
Florin Coras9e47ac52019-01-24 23:22:37 -08001111 max_dequeue = svm_fifo_max_dequeue (s->rx_fifo);
Florin Corasa849b7b2018-05-18 00:41:55 -07001112 if (PREDICT_FALSE (!max_dequeue))
1113 return;
Florin Coras6792ec02017-03-13 03:49:51 -07001114
Florin Corase04c2992017-03-01 08:17:34 -08001115 do
1116 {
Florin Coras9e47ac52019-01-24 23:22:37 -08001117 /* The options here are to limit ourselves to max_dequeue or read
1118 * even the data that was enqueued while we were dequeueing and which
1119 * now has an rx event in the mq. Either of the two work. */
1120 to_dequeue = clib_min (max_dequeue, vec_len (em->rx_buf));
1121 n_read = app_recv_stream_raw (s->rx_fifo, em->rx_buf, to_dequeue,
1122 0 /* clear evt */ , 0 /* peek */ );
Florin Coras6792ec02017-03-13 03:49:51 -07001123 if (n_read > 0)
Florin Corase04c2992017-03-01 08:17:34 -08001124 {
Florin Corasf03a59a2017-06-09 21:07:32 -07001125 max_dequeue -= n_read;
Florin Coras9e47ac52019-01-24 23:22:37 -08001126 s->bytes_received += n_read;
Florin Corasf03a59a2017-06-09 21:07:32 -07001127 }
Florin Coras9e47ac52019-01-24 23:22:37 -08001128 else
1129 break;
Florin Corasf03a59a2017-06-09 21:07:32 -07001130
1131 /* Reflect if a non-drop session */
Florin Coras8e43d042018-05-04 15:46:57 -07001132 if (!em->no_return && n_read > 0)
Florin Corasf03a59a2017-06-09 21:07:32 -07001133 {
1134 offset = 0;
Florin Corase04c2992017-03-01 08:17:34 -08001135 do
1136 {
Florin Coras9e47ac52019-01-24 23:22:37 -08001137 n_sent = app_send_stream ((app_session_t *) s,
1138 &em->rx_buf[offset],
1139 n_read, SVM_Q_WAIT);
1140 if (n_sent > 0)
Florin Corasf03a59a2017-06-09 21:07:32 -07001141 {
Florin Coras9e47ac52019-01-24 23:22:37 -08001142 n_read -= n_sent;
1143 offset += n_sent;
Florin Corasf03a59a2017-06-09 21:07:32 -07001144 }
Florin Corase04c2992017-03-01 08:17:34 -08001145 }
Florin Coras9e47ac52019-01-24 23:22:37 -08001146 while ((n_sent <= 0 || n_read > 0) && !em->time_to_stop);
Florin Corase04c2992017-03-01 08:17:34 -08001147 }
Florin Corase04c2992017-03-01 08:17:34 -08001148 }
Florin Coras9e47ac52019-01-24 23:22:37 -08001149 while (max_dequeue > 0 && !em->time_to_stop);
Florin Corase04c2992017-03-01 08:17:34 -08001150}
1151
Florin Coras52207f12018-07-12 14:48:06 -07001152static void
Florin Coras9e47ac52019-01-24 23:22:37 -08001153server_handle_mq (echo_main_t * em)
Florin Corase04c2992017-03-01 08:17:34 -08001154{
Florin Coras3c2fed52018-07-04 04:15:05 -07001155 svm_msg_q_msg_t msg;
Florin Coras52207f12018-07-12 14:48:06 -07001156 session_event_t *e;
Florin Corase04c2992017-03-01 08:17:34 -08001157
1158 while (1)
1159 {
Florin Coras3c2fed52018-07-04 04:15:05 -07001160 svm_msg_q_sub (em->our_event_queue, &msg, SVM_Q_WAIT, 0);
1161 e = svm_msg_q_msg_data (em->our_event_queue, &msg);
Florin Corase04c2992017-03-01 08:17:34 -08001162 switch (e->event_type)
1163 {
Florin Corasa5464812017-04-19 13:00:05 -07001164 case FIFO_EVENT_APP_RX:
Florin Coras9e47ac52019-01-24 23:22:37 -08001165 server_handle_rx (em, e);
Florin Corase04c2992017-03-01 08:17:34 -08001166 break;
Florin Corase04c2992017-03-01 08:17:34 -08001167 default:
Florin Coras52207f12018-07-12 14:48:06 -07001168 handle_mq_event (e);
Florin Corase04c2992017-03-01 08:17:34 -08001169 break;
1170 }
Florin Corasb384b542018-01-15 01:08:33 -08001171 if (PREDICT_FALSE (em->time_to_stop == 1))
Florin Corase04c2992017-03-01 08:17:34 -08001172 break;
Florin Corasb384b542018-01-15 01:08:33 -08001173 if (PREDICT_FALSE (em->time_to_print_stats == 1))
Florin Corase04c2992017-03-01 08:17:34 -08001174 {
Florin Corasb384b542018-01-15 01:08:33 -08001175 em->time_to_print_stats = 0;
1176 fformat (stdout, "%d connections\n", pool_elts (em->sessions));
Florin Corase04c2992017-03-01 08:17:34 -08001177 }
Florin Coras3c2fed52018-07-04 04:15:05 -07001178 svm_msg_q_free_msg (em->our_event_queue, &msg);
Florin Corase04c2992017-03-01 08:17:34 -08001179 }
1180}
1181
1182void
Florin Corasb384b542018-01-15 01:08:33 -08001183server_send_listen (echo_main_t * em)
Florin Corase04c2992017-03-01 08:17:34 -08001184{
1185 vl_api_bind_uri_t *bmp;
Florin Corase04c2992017-03-01 08:17:34 -08001186 bmp = vl_msg_api_alloc (sizeof (*bmp));
Dave Barachb7b92992018-10-17 10:38:51 -04001187 clib_memset (bmp, 0, sizeof (*bmp));
Florin Corase04c2992017-03-01 08:17:34 -08001188
1189 bmp->_vl_msg_id = ntohs (VL_API_BIND_URI);
Florin Corasb384b542018-01-15 01:08:33 -08001190 bmp->client_index = em->my_client_index;
Florin Corase04c2992017-03-01 08:17:34 -08001191 bmp->context = ntohl (0xfeedface);
Florin Corasb384b542018-01-15 01:08:33 -08001192 memcpy (bmp->uri, em->uri, vec_len (em->uri));
1193 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp);
Florin Corase04c2992017-03-01 08:17:34 -08001194}
1195
Florin Corasa5464812017-04-19 13:00:05 -07001196int
Florin Corasb384b542018-01-15 01:08:33 -08001197server_listen (echo_main_t * em)
Florin Corasa5464812017-04-19 13:00:05 -07001198{
Florin Corasb384b542018-01-15 01:08:33 -08001199 server_send_listen (em);
1200 if (wait_for_state_change (em, STATE_READY))
Florin Corasa5464812017-04-19 13:00:05 -07001201 {
1202 clib_warning ("timeout waiting for STATE_READY");
1203 return -1;
1204 }
1205 return 0;
1206}
1207
Florin Corase04c2992017-03-01 08:17:34 -08001208void
Florin Corasb384b542018-01-15 01:08:33 -08001209server_send_unbind (echo_main_t * em)
Florin Corase04c2992017-03-01 08:17:34 -08001210{
1211 vl_api_unbind_uri_t *ump;
1212
1213 ump = vl_msg_api_alloc (sizeof (*ump));
Dave Barachb7b92992018-10-17 10:38:51 -04001214 clib_memset (ump, 0, sizeof (*ump));
Florin Corase04c2992017-03-01 08:17:34 -08001215
1216 ump->_vl_msg_id = ntohs (VL_API_UNBIND_URI);
Florin Corasb384b542018-01-15 01:08:33 -08001217 ump->client_index = em->my_client_index;
1218 memcpy (ump->uri, em->uri, vec_len (em->uri));
1219 vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & ump);
Florin Corase04c2992017-03-01 08:17:34 -08001220}
1221
Florin Corasa5464812017-04-19 13:00:05 -07001222int
Florin Corasb384b542018-01-15 01:08:33 -08001223server_unbind (echo_main_t * em)
Florin Corasa5464812017-04-19 13:00:05 -07001224{
Florin Corasb384b542018-01-15 01:08:33 -08001225 server_send_unbind (em);
1226 if (wait_for_state_change (em, STATE_START))
Florin Corasa5464812017-04-19 13:00:05 -07001227 {
1228 clib_warning ("timeout waiting for STATE_START");
1229 return -1;
1230 }
1231 return 0;
1232}
1233
Florin Corase04c2992017-03-01 08:17:34 -08001234void
Florin Corasb384b542018-01-15 01:08:33 -08001235server_run (echo_main_t * em)
Florin Corase04c2992017-03-01 08:17:34 -08001236{
Florin Coras9e47ac52019-01-24 23:22:37 -08001237 echo_session_t *session;
Florin Coras90a63982017-12-19 04:50:01 -08001238 int i;
1239
1240 /* $$$$ hack preallocation */
1241 for (i = 0; i < 200000; i++)
1242 {
Florin Corasb384b542018-01-15 01:08:33 -08001243 pool_get (em->sessions, session);
Dave Barachb7b92992018-10-17 10:38:51 -04001244 clib_memset (session, 0, sizeof (*session));
Florin Coras90a63982017-12-19 04:50:01 -08001245 }
1246 for (i = 0; i < 200000; i++)
Florin Corasb384b542018-01-15 01:08:33 -08001247 pool_put_index (em->sessions, i);
Florin Coras90a63982017-12-19 04:50:01 -08001248
Florin Corasb384b542018-01-15 01:08:33 -08001249 if (application_attach (em))
Florin Corasa5464812017-04-19 13:00:05 -07001250 return;
Florin Coras6cf30ad2017-04-04 23:08:23 -07001251
Dave Barach68b0fb02017-02-28 15:15:56 -05001252 /* Bind to uri */
Florin Corasb384b542018-01-15 01:08:33 -08001253 if (server_listen (em))
Florin Corasa5464812017-04-19 13:00:05 -07001254 return;
Dave Barach68b0fb02017-02-28 15:15:56 -05001255
1256 /* Enter handle event loop */
Florin Coras9e47ac52019-01-24 23:22:37 -08001257 server_handle_mq (em);
Dave Barach68b0fb02017-02-28 15:15:56 -05001258
1259 /* Cleanup */
Florin Corasb384b542018-01-15 01:08:33 -08001260 server_send_unbind (em);
Dave Barach68b0fb02017-02-28 15:15:56 -05001261
Florin Corasb384b542018-01-15 01:08:33 -08001262 application_detach (em);
Florin Coras6cf30ad2017-04-04 23:08:23 -07001263
Dave Barach68b0fb02017-02-28 15:15:56 -05001264 fformat (stdout, "Test complete...\n");
1265}
1266
Florin Corase69f4952017-03-07 10:06:24 -08001267static void
1268vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
1269 mp)
1270{
Florin Corasb384b542018-01-15 01:08:33 -08001271 echo_main_t *em = &echo_main;
Florin Corasa849b7b2018-05-18 00:41:55 -07001272 uword *p;
Florin Coras6792ec02017-03-13 03:49:51 -07001273
Florin Corasf03a59a2017-06-09 21:07:32 -07001274 if (mp->retval)
1275 {
1276 clib_warning ("vpp complained about disconnect: %d",
1277 ntohl (mp->retval));
Florin Corasa849b7b2018-05-18 00:41:55 -07001278 return;
Florin Corasf03a59a2017-06-09 21:07:32 -07001279 }
1280
Florin Corasb384b542018-01-15 01:08:33 -08001281 em->state = STATE_START;
Florin Corasa849b7b2018-05-18 00:41:55 -07001282
1283 p = hash_get (em->session_index_by_vpp_handles, mp->handle);
1284 if (p)
1285 {
1286 hash_unset (em->session_index_by_vpp_handles, mp->handle);
1287 }
1288 else
1289 {
1290 clib_warning ("couldn't find session key %llx", mp->handle);
1291 }
Florin Corase69f4952017-03-07 10:06:24 -08001292}
1293
Florin Corase3e2f072018-03-04 07:24:30 -08001294static void
1295 vl_api_application_tls_cert_add_reply_t_handler
1296 (vl_api_application_tls_cert_add_reply_t * mp)
1297{
1298 if (mp->retval)
1299 clib_warning ("failed to add tls cert");
1300}
1301
1302static void
1303 vl_api_application_tls_key_add_reply_t_handler
1304 (vl_api_application_tls_key_add_reply_t * mp)
1305{
1306 if (mp->retval)
1307 clib_warning ("failed to add tls key");
1308}
1309
1310#define foreach_tcp_echo_msg \
1311_(BIND_URI_REPLY, bind_uri_reply) \
1312_(UNBIND_URI_REPLY, unbind_uri_reply) \
Florin Corase3e2f072018-03-04 07:24:30 -08001313_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
Florin Corase3e2f072018-03-04 07:24:30 -08001314_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1315_(APPLICATION_DETACH_REPLY, application_detach_reply) \
1316_(MAP_ANOTHER_SEGMENT, map_another_segment) \
1317_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \
1318_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \
Dave Barach68b0fb02017-02-28 15:15:56 -05001319
1320void
Florin Corasb384b542018-01-15 01:08:33 -08001321tcp_echo_api_hookup (echo_main_t * em)
Dave Barach68b0fb02017-02-28 15:15:56 -05001322{
1323#define _(N,n) \
1324 vl_msg_api_set_handlers(VL_API_##N, #n, \
1325 vl_api_##n##_t_handler, \
1326 vl_noop_handler, \
1327 vl_api_##n##_t_endian, \
1328 vl_api_##n##_t_print, \
1329 sizeof(vl_api_##n##_t), 1);
Florin Corasb384b542018-01-15 01:08:33 -08001330 foreach_tcp_echo_msg;
Dave Barach68b0fb02017-02-28 15:15:56 -05001331#undef _
1332}
1333
1334int
1335main (int argc, char **argv)
1336{
Florin Coras8e43d042018-05-04 15:46:57 -07001337 int i_am_server = 1, test_return_packets = 0;
Florin Corasb384b542018-01-15 01:08:33 -08001338 echo_main_t *em = &echo_main;
Florin Corasadc74d72018-12-02 13:36:00 -08001339 svm_fifo_segment_main_t *sm = &em->segment_main;
Dave Barach68b0fb02017-02-28 15:15:56 -05001340 unformat_input_t _argv, *a = &_argv;
1341 u8 *chroot_prefix;
Dave Barach6a5adc32018-07-04 10:56:23 -04001342 u8 *uri = 0;
Florin Corase69f4952017-03-07 10:06:24 -08001343 u8 *bind_uri = (u8 *) "tcp://0.0.0.0/1234";
Florin Coras8e43d042018-05-04 15:46:57 -07001344 u8 *connect_uri = (u8 *) "tcp://6.0.1.1/1234";
Florin Coras6cf30ad2017-04-04 23:08:23 -07001345 u64 bytes_to_send = 64 << 10, mbytes;
Florin Corasb384b542018-01-15 01:08:33 -08001346 char *app_name;
Dave Barach68b0fb02017-02-28 15:15:56 -05001347 u32 tmp;
Dave Barach68b0fb02017-02-28 15:15:56 -05001348
Dave Barach6a5adc32018-07-04 10:56:23 -04001349 clib_mem_init_thread_safe (0, 256 << 20);
Dave Barach68b0fb02017-02-28 15:15:56 -05001350
Dave Barachb7b92992018-10-17 10:38:51 -04001351 clib_memset (em, 0, sizeof (*em));
Florin Corasb384b542018-01-15 01:08:33 -08001352 em->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
Florin Corasb384b542018-01-15 01:08:33 -08001353 em->my_pid = getpid ();
1354 em->configured_segment_size = 1 << 20;
1355 em->socket_name = 0;
1356 em->use_sock_api = 1;
Florin Coras8e43d042018-05-04 15:46:57 -07001357 em->fifo_size = 64 << 10;
Florin Corasa849b7b2018-05-18 00:41:55 -07001358 em->n_clients = 1;
Dave Barach68b0fb02017-02-28 15:15:56 -05001359
Florin Corasb384b542018-01-15 01:08:33 -08001360 clib_time_init (&em->clib_time);
1361 init_error_string_table (em);
David Johnsond9818dd2018-12-14 14:53:41 -05001362 svm_fifo_segment_main_init (sm, HIGH_SEGMENT_BASEVA, 20);
Dave Barach68b0fb02017-02-28 15:15:56 -05001363 unformat_init_command_line (a, argv);
1364
1365 while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
1366 {
1367 if (unformat (a, "chroot prefix %s", &chroot_prefix))
Florin Corase04c2992017-03-01 08:17:34 -08001368 {
1369 vl_set_memory_root_path ((char *) chroot_prefix);
1370 }
Florin Corase69f4952017-03-07 10:06:24 -08001371 else if (unformat (a, "uri %s", &uri))
Florin Corase04c2992017-03-01 08:17:34 -08001372 ;
Dave Barach68b0fb02017-02-28 15:15:56 -05001373 else if (unformat (a, "segment-size %dM", &tmp))
Florin Corasb384b542018-01-15 01:08:33 -08001374 em->configured_segment_size = tmp << 20;
Dave Barach68b0fb02017-02-28 15:15:56 -05001375 else if (unformat (a, "segment-size %dG", &tmp))
Florin Corasb384b542018-01-15 01:08:33 -08001376 em->configured_segment_size = tmp << 30;
Florin Coras8e43d042018-05-04 15:46:57 -07001377 else if (unformat (a, "server"))
1378 i_am_server = 1;
1379 else if (unformat (a, "client"))
1380 i_am_server = 0;
1381 else if (unformat (a, "no-return"))
1382 em->no_return = 1;
Florin Corase04c2992017-03-01 08:17:34 -08001383 else if (unformat (a, "test"))
1384 test_return_packets = 1;
Florin Coras6cf30ad2017-04-04 23:08:23 -07001385 else if (unformat (a, "mbytes %lld", &mbytes))
Florin Coras6792ec02017-03-13 03:49:51 -07001386 {
1387 bytes_to_send = mbytes << 20;
1388 }
Florin Coras6cf30ad2017-04-04 23:08:23 -07001389 else if (unformat (a, "gbytes %lld", &mbytes))
1390 {
1391 bytes_to_send = mbytes << 30;
1392 }
Florin Corasb384b542018-01-15 01:08:33 -08001393 else if (unformat (a, "socket-name %s", &em->socket_name))
Florin Coras90a63982017-12-19 04:50:01 -08001394 ;
1395 else if (unformat (a, "use-svm-api"))
Florin Corasb384b542018-01-15 01:08:33 -08001396 em->use_sock_api = 0;
Florin Coras8e43d042018-05-04 15:46:57 -07001397 else if (unformat (a, "fifo-size %d", &tmp))
1398 em->fifo_size = tmp << 10;
Florin Corasa849b7b2018-05-18 00:41:55 -07001399 else if (unformat (a, "nclients %d", &em->n_clients))
1400 ;
Dave Barach68b0fb02017-02-28 15:15:56 -05001401 else
Florin Corase04c2992017-03-01 08:17:34 -08001402 {
Jerome Tollet61f79122018-06-04 08:31:33 +01001403 fformat (stderr, "%s: usage [master|slave]\n", argv[0]);
Florin Corase04c2992017-03-01 08:17:34 -08001404 exit (1);
1405 }
Dave Barach68b0fb02017-02-28 15:15:56 -05001406 }
1407
Florin Corasb384b542018-01-15 01:08:33 -08001408 if (!em->socket_name)
1409 em->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0);
Florin Coras90a63982017-12-19 04:50:01 -08001410
Florin Corase69f4952017-03-07 10:06:24 -08001411 if (uri)
1412 {
Florin Corasb384b542018-01-15 01:08:33 -08001413 em->uri = format (0, "%s%c", uri, 0);
1414 em->connect_uri = format (0, "%s%c", uri, 0);
Florin Corase69f4952017-03-07 10:06:24 -08001415 }
1416 else
1417 {
Florin Corasb384b542018-01-15 01:08:33 -08001418 em->uri = format (0, "%s%c", bind_uri, 0);
1419 em->connect_uri = format (0, "%s%c", connect_uri, 0);
Florin Corase69f4952017-03-07 10:06:24 -08001420 }
1421
Florin Coras8e43d042018-05-04 15:46:57 -07001422 em->i_am_master = i_am_server;
Florin Corasb384b542018-01-15 01:08:33 -08001423 em->test_return_packets = test_return_packets;
1424 em->bytes_to_send = bytes_to_send;
1425 em->time_to_stop = 0;
Florin Coras9e47ac52019-01-24 23:22:37 -08001426 vec_validate (em->rx_buf, 4 << 20);
Florin Corasa849b7b2018-05-18 00:41:55 -07001427 vec_validate (em->client_thread_handles, em->n_clients - 1);
1428 vec_validate (em->thread_args, em->n_clients - 1);
Dave Barach68b0fb02017-02-28 15:15:56 -05001429
Florin Corase04c2992017-03-01 08:17:34 -08001430 setup_signal_handlers ();
Florin Corasb384b542018-01-15 01:08:33 -08001431 tcp_echo_api_hookup (em);
Dave Barach68b0fb02017-02-28 15:15:56 -05001432
Florin Coras8e43d042018-05-04 15:46:57 -07001433 app_name = i_am_server ? "tcp_echo_server" : "tcp_echo_client";
Florin Corasb384b542018-01-15 01:08:33 -08001434 if (connect_to_vpp (app_name) < 0)
Dave Barach68b0fb02017-02-28 15:15:56 -05001435 {
1436 svm_region_exit ();
1437 fformat (stderr, "Couldn't connect to vpe, exiting...\n");
1438 exit (1);
1439 }
1440
Florin Coras8e43d042018-05-04 15:46:57 -07001441 if (i_am_server == 0)
Florin Corasa849b7b2018-05-18 00:41:55 -07001442 clients_run (em);
Florin Coras90a63982017-12-19 04:50:01 -08001443 else
Florin Corasb384b542018-01-15 01:08:33 -08001444 server_run (em);
Dave Barach68b0fb02017-02-28 15:15:56 -05001445
Florin Corasa849b7b2018-05-18 00:41:55 -07001446 /* Make sure detach finishes */
1447 wait_for_state_change (em, STATE_DETACHED);
1448
Florin Corasb384b542018-01-15 01:08:33 -08001449 disconnect_from_vpp (em);
Dave Barach68b0fb02017-02-28 15:15:56 -05001450 exit (0);
1451}
Florin Corase04c2992017-03-01 08:17:34 -08001452
1453/*
1454 * fd.io coding-style-patch-verification: ON
1455 *
1456 * Local Variables:
1457 * eval: (c-set-style "gnu")
1458 * End:
1459 */