blob: 60d9b4de51bbd772196e6c9da789d24c2ee97e02 [file] [log] [blame]
Dave Barach68b0fb02017-02-28 15:15:56 -05001/*
2 * Copyright (c) 2015-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 <vnet/vnet.h>
17#include <vlibmemory/api.h>
18#include <vnet/session/application.h>
19
20#include <vnet/vnet_msg_enum.h>
21#include "application_interface.h"
22
23#define vl_typedefs /* define message structures */
24#include <vnet/vnet_all_api_h.h>
25#undef vl_typedefs
26
27#define vl_endianfun /* define message structures */
28#include <vnet/vnet_all_api_h.h>
29#undef vl_endianfun
30
31/* instantiate all the print functions we know about */
32#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
33#define vl_printfun
34#include <vnet/vnet_all_api_h.h>
35#undef vl_printfun
36
37#include <vlibapi/api_helper_macros.h>
38
39#define foreach_session_api_msg \
40_(MAP_ANOTHER_SEGMENT_REPLY, map_another_segment_reply) \
Florin Coras6cf30ad2017-04-04 23:08:23 -070041_(APPLICATION_ATTACH, application_attach) \
42_(APPLICATION_DETACH, application_detach) \
Dave Barach68b0fb02017-02-28 15:15:56 -050043_(BIND_URI, bind_uri) \
44_(UNBIND_URI, unbind_uri) \
45_(CONNECT_URI, connect_uri) \
46_(DISCONNECT_SESSION, disconnect_session) \
47_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
48_(ACCEPT_SESSION_REPLY, accept_session_reply) \
49_(RESET_SESSION_REPLY, reset_session_reply) \
50_(BIND_SOCK, bind_sock) \
51_(UNBIND_SOCK, unbind_sock) \
52_(CONNECT_SOCK, connect_sock) \
Florin Corase04c2992017-03-01 08:17:34 -080053_(SESSION_ENABLE_DISABLE, session_enable_disable) \
54
Dave Barach68b0fb02017-02-28 15:15:56 -050055static int
56send_add_segment_callback (u32 api_client_index, const u8 * segment_name,
57 u32 segment_size)
58{
59 vl_api_map_another_segment_t *mp;
60 unix_shared_memory_queue_t *q;
61
62 q = vl_api_client_index_to_input_queue (api_client_index);
63
64 if (!q)
65 return -1;
66
67 mp = vl_msg_api_alloc (sizeof (*mp));
68 memset (mp, 0, sizeof (*mp));
69 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MAP_ANOTHER_SEGMENT);
70 mp->segment_size = segment_size;
71 strncpy ((char *) mp->segment_name, (char *) segment_name,
72 sizeof (mp->segment_name) - 1);
73
74 vl_msg_api_send_shmem (q, (u8 *) & mp);
75
76 return 0;
77}
78
79static int
Florin Coras6cf30ad2017-04-04 23:08:23 -070080send_session_accept_callback (stream_session_t * s)
Dave Barach68b0fb02017-02-28 15:15:56 -050081{
82 vl_api_accept_session_t *mp;
83 unix_shared_memory_queue_t *q, *vpp_queue;
84 application_t *server = application_get (s->app_index);
Florin Coras6cf30ad2017-04-04 23:08:23 -070085 transport_connection_t *tc;
86 transport_proto_vft_t *tp_vft;
87 stream_session_t *listener;
Dave Barach68b0fb02017-02-28 15:15:56 -050088
89 q = vl_api_client_index_to_input_queue (server->api_client_index);
90 vpp_queue = session_manager_get_vpp_event_queue (s->thread_index);
91
92 if (!q)
93 return -1;
94
95 mp = vl_msg_api_alloc (sizeof (*mp));
Florin Coras6cf30ad2017-04-04 23:08:23 -070096 memset (mp, 0, sizeof (*mp));
97
Dave Barach68b0fb02017-02-28 15:15:56 -050098 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_ACCEPT_SESSION);
Florin Corasa5464812017-04-19 13:00:05 -070099 mp->context = server->index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700100 listener = listen_session_get (s->session_type, s->listener_index);
101 tp_vft = session_get_transport_vft (s->session_type);
102 tc = tp_vft->get_connection (s->connection_index, s->thread_index);
103 mp->listener_handle = listen_session_get_handle (listener);
104 mp->handle = stream_session_handle (s);
Damjan Marion7bee80c2017-04-26 15:32:12 +0200105 mp->server_rx_fifo = pointer_to_uword (s->server_rx_fifo);
106 mp->server_tx_fifo = pointer_to_uword (s->server_tx_fifo);
107 mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700108 mp->port = tc->rmt_port;
109 mp->is_ip4 = tc->is_ip4;
110 clib_memcpy (&mp->ip, &tc->rmt_ip, sizeof (tc->rmt_ip));
Dave Barach68b0fb02017-02-28 15:15:56 -0500111 vl_msg_api_send_shmem (q, (u8 *) & mp);
112
113 return 0;
114}
115
116static void
Florin Coras6cf30ad2017-04-04 23:08:23 -0700117send_session_disconnect_callback (stream_session_t * s)
Dave Barach68b0fb02017-02-28 15:15:56 -0500118{
119 vl_api_disconnect_session_t *mp;
120 unix_shared_memory_queue_t *q;
121 application_t *app = application_get (s->app_index);
122
123 q = vl_api_client_index_to_input_queue (app->api_client_index);
124
125 if (!q)
126 return;
127
128 mp = vl_msg_api_alloc (sizeof (*mp));
129 memset (mp, 0, sizeof (*mp));
130 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_DISCONNECT_SESSION);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700131 mp->handle = stream_session_handle (s);
Dave Barach68b0fb02017-02-28 15:15:56 -0500132 vl_msg_api_send_shmem (q, (u8 *) & mp);
133}
134
Florin Corasd79b41e2017-03-04 05:37:52 -0800135static void
Florin Coras6cf30ad2017-04-04 23:08:23 -0700136send_session_reset_callback (stream_session_t * s)
Florin Corasd79b41e2017-03-04 05:37:52 -0800137{
138 vl_api_reset_session_t *mp;
139 unix_shared_memory_queue_t *q;
140 application_t *app = application_get (s->app_index);
141
142 q = vl_api_client_index_to_input_queue (app->api_client_index);
143
144 if (!q)
145 return;
146
147 mp = vl_msg_api_alloc (sizeof (*mp));
148 memset (mp, 0, sizeof (*mp));
149 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_RESET_SESSION);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700150 mp->handle = stream_session_handle (s);
Florin Corasd79b41e2017-03-04 05:37:52 -0800151 vl_msg_api_send_shmem (q, (u8 *) & mp);
152}
153
Dave Barach0194f1a2017-05-15 10:11:39 -0400154int
Florin Coras6cf30ad2017-04-04 23:08:23 -0700155send_session_connected_callback (u32 app_index, u32 api_context,
156 stream_session_t * s, u8 is_fail)
Dave Barach68b0fb02017-02-28 15:15:56 -0500157{
Dave Wallace33e002b2017-09-06 01:20:02 -0400158 vl_api_connect_session_reply_t *mp;
Dave Barach68b0fb02017-02-28 15:15:56 -0500159 unix_shared_memory_queue_t *q;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700160 application_t *app;
Dave Barach68b0fb02017-02-28 15:15:56 -0500161 unix_shared_memory_queue_t *vpp_queue;
162
Florin Coras6cf30ad2017-04-04 23:08:23 -0700163 app = application_get (app_index);
Dave Barach68b0fb02017-02-28 15:15:56 -0500164 q = vl_api_client_index_to_input_queue (app->api_client_index);
165
166 if (!q)
167 return -1;
168
169 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Wallace33e002b2017-09-06 01:20:02 -0400170 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_CONNECT_SESSION_REPLY);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700171 mp->context = api_context;
Dave Barach68b0fb02017-02-28 15:15:56 -0500172 if (!is_fail)
173 {
174 vpp_queue = session_manager_get_vpp_event_queue (s->thread_index);
Damjan Marion7bee80c2017-04-26 15:32:12 +0200175 mp->server_rx_fifo = pointer_to_uword (s->server_rx_fifo);
176 mp->server_tx_fifo = pointer_to_uword (s->server_tx_fifo);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700177 mp->handle = stream_session_handle (s);
Damjan Marion7bee80c2017-04-26 15:32:12 +0200178 mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
Florin Corase04c2992017-03-01 08:17:34 -0800179 mp->retval = 0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500180 }
Florin Corase04c2992017-03-01 08:17:34 -0800181 else
182 {
flyingeagle23db42b7b2017-04-20 18:38:48 +0800183 mp->retval = clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT_FAIL);
Florin Corase04c2992017-03-01 08:17:34 -0800184 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500185
186 vl_msg_api_send_shmem (q, (u8 *) & mp);
Dave Barach68b0fb02017-02-28 15:15:56 -0500187 return 0;
188}
189
190/**
191 * Redirect a connect_uri message to the indicated server.
192 * Only sent if the server has bound the related port with
193 * URI_OPTIONS_FLAGS_USE_FIFO
194 */
195static int
Florin Coras6cf30ad2017-04-04 23:08:23 -0700196redirect_connect_callback (u32 server_api_client_index, void *mp_arg)
Dave Barach68b0fb02017-02-28 15:15:56 -0500197{
198 vl_api_connect_uri_t *mp = mp_arg;
199 unix_shared_memory_queue_t *server_q, *client_q;
200 vlib_main_t *vm = vlib_get_main ();
201 f64 timeout = vlib_time_now (vm) + 0.5;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700202 application_t *app;
Dave Barach68b0fb02017-02-28 15:15:56 -0500203 int rv = 0;
204
205 server_q = vl_api_client_index_to_input_queue (server_api_client_index);
206
207 if (!server_q)
208 {
209 rv = VNET_API_ERROR_INVALID_VALUE;
210 goto out;
211 }
212
213 client_q = vl_api_client_index_to_input_queue (mp->client_index);
214 if (!client_q)
215 {
216 rv = VNET_API_ERROR_INVALID_VALUE_2;
217 goto out;
218 }
219
220 /* Tell the server the client's API queue address, so it can reply */
Damjan Marion7bee80c2017-04-26 15:32:12 +0200221 mp->client_queue_address = pointer_to_uword (client_q);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700222 app = application_lookup (mp->client_index);
Florin Coras82b13a82017-04-25 11:58:06 -0700223 if (!app)
224 {
225 clib_warning ("no client application");
226 return -1;
227 }
228
Florin Coras6cf30ad2017-04-04 23:08:23 -0700229 mp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = app->sm_properties.rx_fifo_size;
230 mp->options[SESSION_OPTIONS_TX_FIFO_SIZE] = app->sm_properties.tx_fifo_size;
Dave Barach68b0fb02017-02-28 15:15:56 -0500231
232 /*
233 * Bounce message handlers MUST NOT block the data-plane.
234 * Spin waiting for the queue lock, but
235 */
236
237 while (vlib_time_now (vm) < timeout)
238 {
239 rv =
240 unix_shared_memory_queue_add (server_q, (u8 *) & mp, 1 /*nowait */ );
241 switch (rv)
242 {
243 /* correctly enqueued */
244 case 0:
245 return VNET_CONNECT_REDIRECTED;
246
247 /* continue spinning, wait for pthread_mutex_trylock to work */
248 case -1:
249 continue;
250
251 /* queue stuffed, drop the msg */
252 case -2:
253 rv = VNET_API_ERROR_QUEUE_FULL;
254 goto out;
255 }
256 }
257out:
258 /* Dispose of the message */
259 vl_msg_api_free (mp);
260 return rv;
261}
262
263static session_cb_vft_t uri_session_cb_vft = {
Dave Barach68b0fb02017-02-28 15:15:56 -0500264 .session_accept_callback = send_session_accept_callback,
265 .session_disconnect_callback = send_session_disconnect_callback,
266 .session_connected_callback = send_session_connected_callback,
Florin Corasd79b41e2017-03-04 05:37:52 -0800267 .session_reset_callback = send_session_reset_callback,
Dave Barach68b0fb02017-02-28 15:15:56 -0500268 .add_segment_callback = send_add_segment_callback,
269 .redirect_connect_callback = redirect_connect_callback
270};
271
Dave Barach68b0fb02017-02-28 15:15:56 -0500272static void
Florin Corase04c2992017-03-01 08:17:34 -0800273vl_api_session_enable_disable_t_handler (vl_api_session_enable_disable_t * mp)
274{
275 vl_api_session_enable_disable_reply_t *rmp;
276 vlib_main_t *vm = vlib_get_main ();
277 int rv = 0;
278
279 vnet_session_enable_disable (vm, mp->is_enable);
280 REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
281}
282
283static void
Florin Coras6cf30ad2017-04-04 23:08:23 -0700284vl_api_application_attach_t_handler (vl_api_application_attach_t * mp)
Dave Barach68b0fb02017-02-28 15:15:56 -0500285{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700286 vl_api_application_attach_reply_t *rmp;
287 vnet_app_attach_args_t _a, *a = &_a;
Dave Barach68b0fb02017-02-28 15:15:56 -0500288 int rv;
289
Florin Coras6cf30ad2017-04-04 23:08:23 -0700290 if (session_manager_is_enabled () == 0)
291 {
292 rv = VNET_API_ERROR_FEATURE_DISABLED;
293 goto done;
294 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500295
Florin Coras6cf30ad2017-04-04 23:08:23 -0700296 STATIC_ASSERT (sizeof (u64) * SESSION_OPTIONS_N_OPTIONS <=
297 sizeof (mp->options),
298 "Out of options, fix api message definition");
Dave Barach68b0fb02017-02-28 15:15:56 -0500299
300 memset (a, 0, sizeof (*a));
301
Dave Barach68b0fb02017-02-28 15:15:56 -0500302 a->api_client_index = mp->client_index;
303 a->options = mp->options;
Dave Barach68b0fb02017-02-28 15:15:56 -0500304 a->session_cb_vft = &uri_session_cb_vft;
305
Florin Coras6cf30ad2017-04-04 23:08:23 -0700306 rv = vnet_application_attach (a);
Dave Barach68b0fb02017-02-28 15:15:56 -0500307
Florin Coras6cf30ad2017-04-04 23:08:23 -0700308done:
Florin Corasa5464812017-04-19 13:00:05 -0700309
Dave Barach68b0fb02017-02-28 15:15:56 -0500310 /* *INDENT-OFF* */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700311 REPLY_MACRO2 (VL_API_APPLICATION_ATTACH_REPLY, ({
Dave Barach68b0fb02017-02-28 15:15:56 -0500312 if (!rv)
313 {
314 rmp->segment_name_length = 0;
315 /* $$$$ policy? */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700316 rmp->segment_size = a->segment_size;
317 if (a->segment_name_length)
Dave Barach68b0fb02017-02-28 15:15:56 -0500318 {
Florin Coras6cf30ad2017-04-04 23:08:23 -0700319 memcpy (rmp->segment_name, a->segment_name,
320 a->segment_name_length);
321 rmp->segment_name_length = a->segment_name_length;
Dave Barach68b0fb02017-02-28 15:15:56 -0500322 }
Florin Coras6cf30ad2017-04-04 23:08:23 -0700323 rmp->app_event_queue_address = a->app_event_queue_address;
Dave Barach68b0fb02017-02-28 15:15:56 -0500324 }
325 }));
326 /* *INDENT-ON* */
Dave Barach68b0fb02017-02-28 15:15:56 -0500327}
328
329static void
Florin Coras6cf30ad2017-04-04 23:08:23 -0700330vl_api_application_detach_t_handler (vl_api_application_detach_t * mp)
331{
332 vl_api_application_detach_reply_t *rmp;
333 int rv = VNET_API_ERROR_INVALID_VALUE_2;
334 vnet_app_detach_args_t _a, *a = &_a;
335 application_t *app;
336
337 if (session_manager_is_enabled () == 0)
338 {
339 rv = VNET_API_ERROR_FEATURE_DISABLED;
340 goto done;
341 }
342
343 app = application_lookup (mp->client_index);
344 if (app)
345 {
346 a->app_index = app->index;
347 rv = vnet_application_detach (a);
348 }
349
350done:
351 REPLY_MACRO (VL_API_APPLICATION_DETACH_REPLY);
352}
353
354static void
355vl_api_bind_uri_t_handler (vl_api_bind_uri_t * mp)
356{
357 vl_api_bind_uri_reply_t *rmp;
358 vnet_bind_args_t _a, *a = &_a;
359 application_t *app;
360 int rv;
361
362 if (session_manager_is_enabled () == 0)
363 {
364 rv = VNET_API_ERROR_FEATURE_DISABLED;
365 goto done;
366 }
367
368 app = application_lookup (mp->client_index);
369 if (app)
370 {
371 memset (a, 0, sizeof (*a));
372 a->uri = (char *) mp->uri;
373 a->app_index = app->index;
374 rv = vnet_bind_uri (a);
375 }
376 else
377 {
378 rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
379 }
380
381done:
382 REPLY_MACRO (VL_API_BIND_URI_REPLY);
383}
384
385static void
Dave Barach68b0fb02017-02-28 15:15:56 -0500386vl_api_unbind_uri_t_handler (vl_api_unbind_uri_t * mp)
387{
388 vl_api_unbind_uri_reply_t *rmp;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700389 application_t *app;
390 vnet_unbind_args_t _a, *a = &_a;
Dave Barach68b0fb02017-02-28 15:15:56 -0500391 int rv;
392
Florin Coras6cf30ad2017-04-04 23:08:23 -0700393 if (session_manager_is_enabled () == 0)
394 {
395 rv = VNET_API_ERROR_FEATURE_DISABLED;
396 goto done;
397 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500398
Florin Coras6cf30ad2017-04-04 23:08:23 -0700399 app = application_lookup (mp->client_index);
400 if (app)
401 {
402 a->uri = (char *) mp->uri;
403 a->app_index = app->index;
404 rv = vnet_unbind_uri (a);
405 }
406 else
407 {
408 rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
409 }
410
411done:
Dave Barach68b0fb02017-02-28 15:15:56 -0500412 REPLY_MACRO (VL_API_UNBIND_URI_REPLY);
413}
414
Florin Corasf03a59a2017-06-09 21:07:32 -0700415static void
Dave Barach68b0fb02017-02-28 15:15:56 -0500416vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
417{
Dave Wallace33e002b2017-09-06 01:20:02 -0400418 vl_api_connect_session_reply_t *rmp;
Dave Barach68b0fb02017-02-28 15:15:56 -0500419 vnet_connect_args_t _a, *a = &_a;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700420 application_t *app;
Florin Corase04c2992017-03-01 08:17:34 -0800421 int rv;
Dave Barach68b0fb02017-02-28 15:15:56 -0500422
Florin Coras6cf30ad2017-04-04 23:08:23 -0700423 if (session_manager_is_enabled () == 0)
424 {
425 rv = VNET_API_ERROR_FEATURE_DISABLED;
426 goto done;
427 }
Florin Corase04c2992017-03-01 08:17:34 -0800428
Florin Coras6cf30ad2017-04-04 23:08:23 -0700429 app = application_lookup (mp->client_index);
430 if (app)
431 {
432 a->uri = (char *) mp->uri;
433 a->api_context = mp->context;
434 a->app_index = app->index;
435 a->mp = mp;
436 rv = vnet_connect_uri (a);
437 }
438 else
439 {
440 rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
441 }
Florin Corase04c2992017-03-01 08:17:34 -0800442
443 if (rv == 0 || rv == VNET_CONNECT_REDIRECTED)
444 return;
445
446 /* Got some error, relay it */
447
Florin Coras6cf30ad2017-04-04 23:08:23 -0700448done:
Florin Corase04c2992017-03-01 08:17:34 -0800449 /* *INDENT-OFF* */
Dave Wallace33e002b2017-09-06 01:20:02 -0400450 REPLY_MACRO (VL_API_CONNECT_SESSION_REPLY);
Florin Corase04c2992017-03-01 08:17:34 -0800451 /* *INDENT-ON* */
Dave Barach68b0fb02017-02-28 15:15:56 -0500452}
453
454static void
455vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
456{
457 vl_api_disconnect_session_reply_t *rmp;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700458 vnet_disconnect_args_t _a, *a = &_a;
459 application_t *app;
460 int rv = 0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500461
Florin Coras6cf30ad2017-04-04 23:08:23 -0700462 if (session_manager_is_enabled () == 0)
463 {
464 rv = VNET_API_ERROR_FEATURE_DISABLED;
465 goto done;
466 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500467
Florin Coras6cf30ad2017-04-04 23:08:23 -0700468 app = application_lookup (mp->client_index);
469 if (app)
470 {
471 a->handle = mp->handle;
472 a->app_index = app->index;
473 rv = vnet_disconnect_session (a);
474 }
475 else
476 {
477 rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
478 }
479
480done:
Dave Barach68b0fb02017-02-28 15:15:56 -0500481 REPLY_MACRO (VL_API_DISCONNECT_SESSION_REPLY);
482}
483
484static void
485vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
486 mp)
487{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700488 vnet_disconnect_args_t _a, *a = &_a;
489 application_t *app;
Dave Barach68b0fb02017-02-28 15:15:56 -0500490
491 /* Client objected to disconnecting the session, log and continue */
492 if (mp->retval)
493 {
494 clib_warning ("client retval %d", mp->retval);
495 return;
496 }
497
498 /* Disconnect has been confirmed. Confirm close to transport */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700499 app = application_lookup (mp->client_index);
500 if (app)
501 {
502 a->handle = mp->handle;
503 a->app_index = app->index;
504 vnet_disconnect_session (a);
505 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500506}
507
508static void
509vl_api_reset_session_reply_t_handler (vl_api_reset_session_reply_t * mp)
510{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700511 application_t *app;
Dave Barach68b0fb02017-02-28 15:15:56 -0500512 stream_session_t *s;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700513 u32 index, thread_index;
Dave Barach68b0fb02017-02-28 15:15:56 -0500514
Florin Coras6cf30ad2017-04-04 23:08:23 -0700515 app = application_lookup (mp->client_index);
516 if (!app)
517 return;
518
519 stream_session_parse_handle (mp->handle, &index, &thread_index);
520 s = stream_session_get_if_valid (index, thread_index);
521 if (s == 0 || app->index != s->app_index)
Dave Barach68b0fb02017-02-28 15:15:56 -0500522 {
523 clib_warning ("Invalid session!");
524 return;
525 }
526
527 /* Client objected to resetting the session, log and continue */
528 if (mp->retval)
529 {
530 clib_warning ("client retval %d", mp->retval);
531 return;
532 }
533
Dave Barach68b0fb02017-02-28 15:15:56 -0500534 /* This comes as a response to a reset, transport only waiting for
535 * confirmation to remove connection state, no need to disconnect */
536 stream_session_cleanup (s);
537}
538
539static void
540vl_api_accept_session_reply_t_handler (vl_api_accept_session_reply_t * mp)
541{
542 stream_session_t *s;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700543 u32 session_index, thread_index;
Florin Corasa5464812017-04-19 13:00:05 -0700544 vnet_disconnect_args_t _a, *a = &_a;
Dave Barach68b0fb02017-02-28 15:15:56 -0500545
Florin Corasa5464812017-04-19 13:00:05 -0700546 /* Server isn't interested, kill the session */
547 if (mp->retval)
Dave Barach68b0fb02017-02-28 15:15:56 -0500548 {
Florin Corasa5464812017-04-19 13:00:05 -0700549 a->app_index = mp->context;
550 a->handle = mp->handle;
551 vnet_disconnect_session (a);
Dave Barach68b0fb02017-02-28 15:15:56 -0500552 }
Florin Corasa5464812017-04-19 13:00:05 -0700553 else
554 {
555 stream_session_parse_handle (mp->handle, &session_index, &thread_index);
556 s = stream_session_get_if_valid (session_index, thread_index);
557 if (!s)
558 {
559 clib_warning ("session doesn't exist");
560 return;
561 }
562 if (s->app_index != mp->context)
563 {
564 clib_warning ("app doesn't own session");
565 return;
566 }
567 /* XXX volatile? */
568 s->session_state = SESSION_STATE_READY;
569 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500570}
571
572static void
573vl_api_map_another_segment_reply_t_handler (vl_api_map_another_segment_reply_t
574 * mp)
575{
576 clib_warning ("not implemented");
577}
578
579static void
580vl_api_bind_sock_t_handler (vl_api_bind_sock_t * mp)
581{
582 vl_api_bind_sock_reply_t *rmp;
583 vnet_bind_args_t _a, *a = &_a;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700584 int rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
585 application_t *app;
Dave Barach68b0fb02017-02-28 15:15:56 -0500586
Florin Coras6cf30ad2017-04-04 23:08:23 -0700587 if (session_manager_is_enabled () == 0)
588 {
589 rv = VNET_API_ERROR_FEATURE_DISABLED;
590 goto done;
591 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500592
Florin Coras6cf30ad2017-04-04 23:08:23 -0700593 app = application_lookup (mp->client_index);
594 if (app)
595 {
Dave Wallace33e002b2017-09-06 01:20:02 -0400596 ip46_address_t *ip46 = (ip46_address_t *) mp->ip;
597
Florin Coras6cf30ad2017-04-04 23:08:23 -0700598 memset (a, 0, sizeof (*a));
Florin Coras6cf30ad2017-04-04 23:08:23 -0700599 a->tep.is_ip4 = mp->is_ip4;
Dave Wallace33e002b2017-09-06 01:20:02 -0400600 a->tep.ip = *ip46;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700601 a->tep.port = mp->port;
602 a->tep.vrf = mp->vrf;
603 a->app_index = app->index;
Dave Barach68b0fb02017-02-28 15:15:56 -0500604
Florin Coras6cf30ad2017-04-04 23:08:23 -0700605 rv = vnet_bind (a);
606 }
607done:
608 REPLY_MACRO (VL_API_BIND_SOCK_REPLY);
Dave Barach68b0fb02017-02-28 15:15:56 -0500609}
610
611static void
612vl_api_unbind_sock_t_handler (vl_api_unbind_sock_t * mp)
613{
614 vl_api_unbind_sock_reply_t *rmp;
615 vnet_unbind_args_t _a, *a = &_a;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700616 application_t *app;
617 int rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
Dave Barach68b0fb02017-02-28 15:15:56 -0500618
Florin Coras6cf30ad2017-04-04 23:08:23 -0700619 if (session_manager_is_enabled () == 0)
620 {
621 rv = VNET_API_ERROR_FEATURE_DISABLED;
622 goto done;
623 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500624
Florin Coras6cf30ad2017-04-04 23:08:23 -0700625 app = application_lookup (mp->client_index);
626 if (app)
627 {
628 a->app_index = mp->client_index;
629 a->handle = mp->handle;
630 rv = vnet_unbind (a);
631 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500632
Florin Coras6cf30ad2017-04-04 23:08:23 -0700633done:
Dave Barach68b0fb02017-02-28 15:15:56 -0500634 REPLY_MACRO (VL_API_UNBIND_SOCK_REPLY);
635}
636
637static void
638vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
639{
Dave Wallace33e002b2017-09-06 01:20:02 -0400640 vl_api_connect_session_reply_t *rmp;
Dave Barach68b0fb02017-02-28 15:15:56 -0500641 vnet_connect_args_t _a, *a = &_a;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700642 application_t *app;
Florin Corase04c2992017-03-01 08:17:34 -0800643 int rv;
Dave Barach68b0fb02017-02-28 15:15:56 -0500644
Florin Coras6cf30ad2017-04-04 23:08:23 -0700645 if (session_manager_is_enabled () == 0)
646 {
647 rv = VNET_API_ERROR_FEATURE_DISABLED;
648 goto done;
649 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500650
Florin Coras6cf30ad2017-04-04 23:08:23 -0700651 app = application_lookup (mp->client_index);
652 if (app)
653 {
Dave Wallaceb2d5ff32017-06-14 12:38:28 -0400654 unix_shared_memory_queue_t *client_q;
Dave Wallace33e002b2017-09-06 01:20:02 -0400655 ip46_address_t *ip46 = (ip46_address_t *) mp->ip;
Dave Wallaceb2d5ff32017-06-14 12:38:28 -0400656
657 client_q = vl_api_client_index_to_input_queue (mp->client_index);
658 mp->client_queue_address = pointer_to_uword (client_q);
659 a->tep.is_ip4 = mp->is_ip4;
Dave Wallace33e002b2017-09-06 01:20:02 -0400660 a->tep.ip = *ip46;
Dave Wallaceb2d5ff32017-06-14 12:38:28 -0400661 a->tep.port = mp->port;
Dave Wallace33e002b2017-09-06 01:20:02 -0400662 a->tep.vrf = mp->vrf;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700663 a->api_context = mp->context;
664 a->app_index = app->index;
Dave Wallaceb2d5ff32017-06-14 12:38:28 -0400665 a->proto = mp->proto;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700666 a->mp = mp;
667 rv = vnet_connect (a);
668 }
669 else
670 {
671 rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
672 }
Florin Corase04c2992017-03-01 08:17:34 -0800673
674 if (rv == 0 || rv == VNET_CONNECT_REDIRECTED)
675 return;
676
677 /* Got some error, relay it */
678
Florin Coras6cf30ad2017-04-04 23:08:23 -0700679done:
Dave Wallace33e002b2017-09-06 01:20:02 -0400680 REPLY_MACRO (VL_API_CONNECT_SESSION_REPLY);
Dave Barach68b0fb02017-02-28 15:15:56 -0500681}
682
Florin Coras6cf30ad2017-04-04 23:08:23 -0700683static clib_error_t *
684application_reaper_cb (u32 client_index)
Dave Barach68b0fb02017-02-28 15:15:56 -0500685{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700686 application_t *app = application_lookup (client_index);
687 vnet_app_detach_args_t _a, *a = &_a;
688 if (app)
689 {
690 a->app_index = app->index;
691 vnet_application_detach (a);
692 }
693 return 0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500694}
695
Florin Coras6cf30ad2017-04-04 23:08:23 -0700696VL_MSG_API_REAPER_FUNCTION (application_reaper_cb);
Dave Barach68b0fb02017-02-28 15:15:56 -0500697
698#define vl_msg_name_crc_list
699#include <vnet/vnet_all_api_h.h>
700#undef vl_msg_name_crc_list
701
702static void
703setup_message_id_table (api_main_t * am)
704{
705#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
706 foreach_vl_msg_name_crc_session;
707#undef _
708}
709
710/*
711 * session_api_hookup
712 * Add uri's API message handlers to the table.
713 * vlib has alread mapped shared memory and
714 * added the client registration handlers.
715 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
716 */
717static clib_error_t *
718session_api_hookup (vlib_main_t * vm)
719{
720 api_main_t *am = &api_main;
721
722#define _(N,n) \
723 vl_msg_api_set_handlers(VL_API_##N, #n, \
724 vl_api_##n##_t_handler, \
725 vl_noop_handler, \
726 vl_api_##n##_t_endian, \
727 vl_api_##n##_t_print, \
728 sizeof(vl_api_##n##_t), 1);
729 foreach_session_api_msg;
730#undef _
731
732 /*
733 * Messages which bounce off the data-plane to
734 * an API client. Simply tells the message handling infra not
735 * to free the message.
736 *
737 * Bounced message handlers MUST NOT block the data plane
738 */
739 am->message_bounce[VL_API_CONNECT_URI] = 1;
740 am->message_bounce[VL_API_CONNECT_SOCK] = 1;
741
742 /*
743 * Set up the (msg_name, crc, message-id) table
744 */
745 setup_message_id_table (am);
746
747 return 0;
748}
749
750VLIB_API_INIT_FUNCTION (session_api_hookup);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700751
Dave Barach68b0fb02017-02-28 15:15:56 -0500752/*
753 * fd.io coding-style-patch-verification: ON
754 *
755 * Local Variables:
756 * eval: (c-set-style "gnu")
757 * End:
758 */