blob: 05a47031dc22d5457b0cec97e3ce109a9c0bcdee [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/** @file
17 udp builtin server
18*/
19
20#include <vnet/udp/udp.h>
21#include <vnet/session/session.h>
22#include <vnet/session/application_interface.h>
23
24/** per-worker built-in server copy buffers */
25u8 **copy_buffers;
Andreas Schultz10593f82017-12-08 16:35:56 +010026static int app_index = ~0;
Dave Barach68b0fb02017-02-28 15:15:56 -050027
28static int
29builtin_session_create_callback (stream_session_t * s)
30{
31 /* Simple version: declare session ready-to-go... */
32 s->session_state = SESSION_STATE_READY;
33 return 0;
34}
35
36static void
37builtin_session_disconnect_callback (stream_session_t * s)
38{
39 stream_session_disconnect (s);
40}
41
Andreas Schultz10593f82017-12-08 16:35:56 +010042static void
43builtin_session_reset_callback (stream_session_t * s)
44{
45 clib_warning ("Reset session %U", format_stream_session, s, 2);
46 stream_session_cleanup (s);
47}
48
49static int
50builtin_session_connected_callback (u32 app_index, u32 api_context,
51 stream_session_t * s, u8 is_fail)
52{
53 clib_warning ("called...");
54 return -1;
55}
56
Dave Barach68b0fb02017-02-28 15:15:56 -050057static int
Florin Coras6792ec02017-03-13 03:49:51 -070058builtin_server_rx_callback (stream_session_t * s)
Dave Barach68b0fb02017-02-28 15:15:56 -050059{
60 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras6792ec02017-03-13 03:49:51 -070061 u32 this_transfer, max_deq, max_enq;
Dave Barach68b0fb02017-02-28 15:15:56 -050062 int actual_transfer;
63 u8 *my_copy_buffer;
64 session_fifo_event_t evt;
65 unix_shared_memory_queue_t *q;
66
67 my_copy_buffer = copy_buffers[s->thread_index];
68 rx_fifo = s->server_rx_fifo;
69 tx_fifo = s->server_tx_fifo;
70
Florin Coras6792ec02017-03-13 03:49:51 -070071 max_deq = svm_fifo_max_dequeue (rx_fifo);
72 max_enq = svm_fifo_max_enqueue (tx_fifo);
73 this_transfer = max_enq < max_deq ? max_enq : max_deq;
Dave Barach68b0fb02017-02-28 15:15:56 -050074
75 vec_validate (my_copy_buffer, this_transfer - 1);
76 _vec_len (my_copy_buffer) = this_transfer;
77
Florin Corasa5464812017-04-19 13:00:05 -070078 actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, this_transfer,
Dave Barach68b0fb02017-02-28 15:15:56 -050079 my_copy_buffer);
80 ASSERT (actual_transfer == this_transfer);
Florin Corasa5464812017-04-19 13:00:05 -070081 actual_transfer = svm_fifo_enqueue_nowait (tx_fifo, this_transfer,
Dave Barach68b0fb02017-02-28 15:15:56 -050082 my_copy_buffer);
Florin Coras6792ec02017-03-13 03:49:51 -070083 ASSERT (actual_transfer == this_transfer);
Dave Barach68b0fb02017-02-28 15:15:56 -050084
85 copy_buffers[s->thread_index] = my_copy_buffer;
86
Florin Coras6792ec02017-03-13 03:49:51 -070087 if (svm_fifo_set_event (tx_fifo))
88 {
89 /* Fabricate TX event, send to ourselves */
90 evt.fifo = tx_fifo;
Florin Corasa5464812017-04-19 13:00:05 -070091 evt.event_type = FIFO_EVENT_APP_TX;
Florin Coras6792ec02017-03-13 03:49:51 -070092 q = session_manager_get_vpp_event_queue (s->thread_index);
93 unix_shared_memory_queue_add (q, (u8 *) & evt,
94 0 /* do wait for mutex */ );
95 }
Dave Barach68b0fb02017-02-28 15:15:56 -050096
97 return 0;
98}
99
100/* *INDENT-OFF* */
101static session_cb_vft_t builtin_server = {
102 .session_accept_callback = builtin_session_create_callback,
Andreas Schultz10593f82017-12-08 16:35:56 +0100103 .session_connected_callback = builtin_session_connected_callback,
Dave Barach68b0fb02017-02-28 15:15:56 -0500104 .session_disconnect_callback = builtin_session_disconnect_callback,
Andreas Schultz10593f82017-12-08 16:35:56 +0100105 .builtin_server_rx_callback = builtin_server_rx_callback,
106 .session_reset_callback = builtin_session_reset_callback
Dave Barach68b0fb02017-02-28 15:15:56 -0500107};
108/* *INDENT-ON* */
109
110static int
Florin Coras6cf30ad2017-04-04 23:08:23 -0700111attach_builtin_uri_server ()
Dave Barach68b0fb02017-02-28 15:15:56 -0500112{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700113 vnet_app_attach_args_t _a, *a = &_a;
114 u8 segment_name[128];
Dave Barach68b0fb02017-02-28 15:15:56 -0500115 u32 segment_name_length;
Dave Barach68b0fb02017-02-28 15:15:56 -0500116 u64 options[16];
117
118 segment_name_length = ARRAY_LEN (segment_name);
119
120 memset (a, 0, sizeof (*a));
121 memset (options, 0, sizeof (options));
122
Florin Coras6cf30ad2017-04-04 23:08:23 -0700123 a->api_client_index = ~0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500124 a->segment_name = segment_name;
125 a->segment_name_length = segment_name_length;
126 a->session_cb_vft = &builtin_server;
127
Florin Corasff6e7692017-12-11 04:59:01 -0800128 options[APP_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
129 options[APP_OPTIONS_SEGMENT_SIZE] = (2 << 30); /*$$$$ config / arg */
Florin Coras7999e832017-10-31 01:51:04 -0700130 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
Dave Barach10d8cc62017-05-30 09:30:07 -0400131 options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 1024;
Florin Corasa5464812017-04-19 13:00:05 -0700132
Dave Barach68b0fb02017-02-28 15:15:56 -0500133 a->options = options;
134
Florin Corascea194d2017-10-02 00:18:51 -0700135 if (vnet_application_attach (a))
136 return -1;
Andreas Schultz10593f82017-12-08 16:35:56 +0100137
138 app_index = a->app_index;
Florin Corascea194d2017-10-02 00:18:51 -0700139 return 0;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700140}
141
142static int
143bind_builtin_uri_server (u8 * uri)
144{
145 vnet_bind_args_t _a, *a = &_a;
146 int rv;
147
148 rv = attach_builtin_uri_server ();
149 if (rv)
150 return rv;
151
152 memset (a, 0, sizeof (*a));
153 a->uri = (char *) uri;
Andreas Schultz10593f82017-12-08 16:35:56 +0100154 a->app_index = app_index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700155
Dave Barach68b0fb02017-02-28 15:15:56 -0500156 rv = vnet_bind_uri (a);
157
158 return rv;
159}
160
161static int
162unbind_builtin_uri_server (u8 * uri)
163{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700164 vnet_unbind_args_t _a, *a = &_a;
Dave Barach68b0fb02017-02-28 15:15:56 -0500165
Andreas Schultz10593f82017-12-08 16:35:56 +0100166 a->app_index = app_index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700167 a->uri = (char *) uri;
Dave Barach68b0fb02017-02-28 15:15:56 -0500168
Florin Coras6cf30ad2017-04-04 23:08:23 -0700169 return vnet_unbind_uri (a);
Dave Barach68b0fb02017-02-28 15:15:56 -0500170}
171
172static clib_error_t *
173builtin_server_init (vlib_main_t * vm)
174{
175 vlib_thread_main_t *vtm = vlib_get_thread_main ();
176 u32 num_threads;
177
178 num_threads = 1 /* main thread */ + vtm->n_threads;
179
180 vec_validate (copy_buffers, num_threads - 1);
181 return 0;
182}
183
184VLIB_INIT_FUNCTION (builtin_server_init);
185
186static clib_error_t *
187builtin_uri_bind_command_fn (vlib_main_t * vm,
188 unformat_input_t * input,
189 vlib_cli_command_t * cmd)
190{
191 u8 *uri = 0;
192 int rv;
193
194 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
195 {
196 if (unformat (input, "uri %s", &uri))
197 ;
198 else
199 break;
200 }
201
202 if (uri == 0)
203 return clib_error_return (0, "uri to bind not specified...");
204
Andreas Schultz10593f82017-12-08 16:35:56 +0100205 vnet_session_enable_disable (vm, 1 /* turn on UDP, etc. */ );
206
Dave Barach68b0fb02017-02-28 15:15:56 -0500207 rv = bind_builtin_uri_server (uri);
208
209 vec_free (uri);
210
211 switch (rv)
212 {
213 case 0:
214 break;
215
216 default:
217 return clib_error_return (0, "bind_uri_server returned %d", rv);
218 break;
219 }
220
221 return 0;
222}
223
224/* *INDENT-OFF* */
225VLIB_CLI_COMMAND (builtin_uri_bind_command, static) =
226{
227 .path = "builtin uri bind",
228 .short_help = "builtin uri bind",
229 .function = builtin_uri_bind_command_fn,
230};
231/* *INDENT-ON* */
232
233static clib_error_t *
234builtin_uri_unbind_command_fn (vlib_main_t * vm,
235 unformat_input_t * input,
236 vlib_cli_command_t * cmd)
237{
238 u8 *uri = 0;
239 int rv;
240
241 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
242 {
243 if (unformat (input, "uri %s", &uri))
244 ;
245 else
246 break;
247 }
248
249 if (uri == 0)
250 return clib_error_return (0, "uri to unbind not specified...");
251
252 rv = unbind_builtin_uri_server (uri);
253
254 vec_free (uri);
255
256 switch (rv)
257 {
258 case 0:
259 break;
260
261 default:
262 return clib_error_return (0, "unbind_uri_server returned %d", rv);
263 break;
264 }
265
266 return 0;
267}
268
269/* *INDENT-OFF* */
270VLIB_CLI_COMMAND (builtin_uri_unbind_command, static) =
271{
272 .path = "builtin uri unbind",
273 .short_help = "builtin uri unbind",
274 .function = builtin_uri_unbind_command_fn,
275};
276/* *INDENT-ON* */
277
278/*
279 * fd.io coding-style-patch-verification: ON
280 *
281 * Local Variables:
282 * eval: (c-set-style "gnu")
283 * End:
284 */