blob: 593642cb09cd2a6f3a5d88627fde7c445950ed27 [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;
26
27static int
28builtin_session_create_callback (stream_session_t * s)
29{
30 /* Simple version: declare session ready-to-go... */
31 s->session_state = SESSION_STATE_READY;
32 return 0;
33}
34
35static void
36builtin_session_disconnect_callback (stream_session_t * s)
37{
38 stream_session_disconnect (s);
39}
40
41static int
Florin Coras6792ec02017-03-13 03:49:51 -070042builtin_server_rx_callback (stream_session_t * s)
Dave Barach68b0fb02017-02-28 15:15:56 -050043{
44 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras6792ec02017-03-13 03:49:51 -070045 u32 this_transfer, max_deq, max_enq;
Dave Barach68b0fb02017-02-28 15:15:56 -050046 int actual_transfer;
47 u8 *my_copy_buffer;
48 session_fifo_event_t evt;
49 unix_shared_memory_queue_t *q;
50
51 my_copy_buffer = copy_buffers[s->thread_index];
52 rx_fifo = s->server_rx_fifo;
53 tx_fifo = s->server_tx_fifo;
54
Florin Coras6792ec02017-03-13 03:49:51 -070055 max_deq = svm_fifo_max_dequeue (rx_fifo);
56 max_enq = svm_fifo_max_enqueue (tx_fifo);
57 this_transfer = max_enq < max_deq ? max_enq : max_deq;
Dave Barach68b0fb02017-02-28 15:15:56 -050058
59 vec_validate (my_copy_buffer, this_transfer - 1);
60 _vec_len (my_copy_buffer) = this_transfer;
61
Florin Corasa5464812017-04-19 13:00:05 -070062 actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, this_transfer,
Dave Barach68b0fb02017-02-28 15:15:56 -050063 my_copy_buffer);
64 ASSERT (actual_transfer == this_transfer);
Florin Corasa5464812017-04-19 13:00:05 -070065 actual_transfer = svm_fifo_enqueue_nowait (tx_fifo, this_transfer,
Dave Barach68b0fb02017-02-28 15:15:56 -050066 my_copy_buffer);
Florin Coras6792ec02017-03-13 03:49:51 -070067 ASSERT (actual_transfer == this_transfer);
Dave Barach68b0fb02017-02-28 15:15:56 -050068
69 copy_buffers[s->thread_index] = my_copy_buffer;
70
Florin Coras6792ec02017-03-13 03:49:51 -070071 if (svm_fifo_set_event (tx_fifo))
72 {
73 /* Fabricate TX event, send to ourselves */
74 evt.fifo = tx_fifo;
Florin Corasa5464812017-04-19 13:00:05 -070075 evt.event_type = FIFO_EVENT_APP_TX;
Florin Coras6792ec02017-03-13 03:49:51 -070076 q = session_manager_get_vpp_event_queue (s->thread_index);
77 unix_shared_memory_queue_add (q, (u8 *) & evt,
78 0 /* do wait for mutex */ );
79 }
Dave Barach68b0fb02017-02-28 15:15:56 -050080
81 return 0;
82}
83
84/* *INDENT-OFF* */
85static session_cb_vft_t builtin_server = {
86 .session_accept_callback = builtin_session_create_callback,
87 .session_disconnect_callback = builtin_session_disconnect_callback,
88 .builtin_server_rx_callback = builtin_server_rx_callback
89};
90/* *INDENT-ON* */
91
92static int
Florin Coras6cf30ad2017-04-04 23:08:23 -070093attach_builtin_uri_server ()
Dave Barach68b0fb02017-02-28 15:15:56 -050094{
Florin Coras6cf30ad2017-04-04 23:08:23 -070095 vnet_app_attach_args_t _a, *a = &_a;
96 u8 segment_name[128];
Dave Barach68b0fb02017-02-28 15:15:56 -050097 u32 segment_name_length;
Dave Barach68b0fb02017-02-28 15:15:56 -050098 u64 options[16];
99
100 segment_name_length = ARRAY_LEN (segment_name);
101
102 memset (a, 0, sizeof (*a));
103 memset (options, 0, sizeof (options));
104
Florin Coras6cf30ad2017-04-04 23:08:23 -0700105 a->api_client_index = ~0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500106 a->segment_name = segment_name;
107 a->segment_name_length = segment_name_length;
108 a->session_cb_vft = &builtin_server;
109
110 options[SESSION_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
111 options[SESSION_OPTIONS_SEGMENT_SIZE] = (2 << 30); /*$$$$ config / arg */
Florin Corasa5464812017-04-19 13:00:05 -0700112 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_BUILTIN_APP;
Dave Barach10d8cc62017-05-30 09:30:07 -0400113 options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 1024;
Florin Corasa5464812017-04-19 13:00:05 -0700114
Dave Barach68b0fb02017-02-28 15:15:56 -0500115 a->options = options;
116
Florin Corascea194d2017-10-02 00:18:51 -0700117 if (vnet_application_attach (a))
118 return -1;
119 return 0;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700120}
121
122static int
123bind_builtin_uri_server (u8 * uri)
124{
125 vnet_bind_args_t _a, *a = &_a;
126 int rv;
127
128 rv = attach_builtin_uri_server ();
129 if (rv)
130 return rv;
131
132 memset (a, 0, sizeof (*a));
133 a->uri = (char *) uri;
134 a->app_index = ~0; /* built-in server */
135
Dave Barach68b0fb02017-02-28 15:15:56 -0500136 rv = vnet_bind_uri (a);
137
138 return rv;
139}
140
141static int
142unbind_builtin_uri_server (u8 * uri)
143{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700144 vnet_unbind_args_t _a, *a = &_a;
Dave Barach68b0fb02017-02-28 15:15:56 -0500145
Florin Coras6cf30ad2017-04-04 23:08:23 -0700146 a->app_index = ~0;
147 a->uri = (char *) uri;
Dave Barach68b0fb02017-02-28 15:15:56 -0500148
Florin Coras6cf30ad2017-04-04 23:08:23 -0700149 return vnet_unbind_uri (a);
Dave Barach68b0fb02017-02-28 15:15:56 -0500150}
151
152static clib_error_t *
153builtin_server_init (vlib_main_t * vm)
154{
155 vlib_thread_main_t *vtm = vlib_get_thread_main ();
156 u32 num_threads;
157
158 num_threads = 1 /* main thread */ + vtm->n_threads;
159
160 vec_validate (copy_buffers, num_threads - 1);
161 return 0;
162}
163
164VLIB_INIT_FUNCTION (builtin_server_init);
165
166static clib_error_t *
167builtin_uri_bind_command_fn (vlib_main_t * vm,
168 unformat_input_t * input,
169 vlib_cli_command_t * cmd)
170{
171 u8 *uri = 0;
172 int rv;
173
174 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
175 {
176 if (unformat (input, "uri %s", &uri))
177 ;
178 else
179 break;
180 }
181
182 if (uri == 0)
183 return clib_error_return (0, "uri to bind not specified...");
184
185 rv = bind_builtin_uri_server (uri);
186
187 vec_free (uri);
188
189 switch (rv)
190 {
191 case 0:
192 break;
193
194 default:
195 return clib_error_return (0, "bind_uri_server returned %d", rv);
196 break;
197 }
198
199 return 0;
200}
201
202/* *INDENT-OFF* */
203VLIB_CLI_COMMAND (builtin_uri_bind_command, static) =
204{
205 .path = "builtin uri bind",
206 .short_help = "builtin uri bind",
207 .function = builtin_uri_bind_command_fn,
208};
209/* *INDENT-ON* */
210
211static clib_error_t *
212builtin_uri_unbind_command_fn (vlib_main_t * vm,
213 unformat_input_t * input,
214 vlib_cli_command_t * cmd)
215{
216 u8 *uri = 0;
217 int rv;
218
219 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
220 {
221 if (unformat (input, "uri %s", &uri))
222 ;
223 else
224 break;
225 }
226
227 if (uri == 0)
228 return clib_error_return (0, "uri to unbind not specified...");
229
230 rv = unbind_builtin_uri_server (uri);
231
232 vec_free (uri);
233
234 switch (rv)
235 {
236 case 0:
237 break;
238
239 default:
240 return clib_error_return (0, "unbind_uri_server returned %d", rv);
241 break;
242 }
243
244 return 0;
245}
246
247/* *INDENT-OFF* */
248VLIB_CLI_COMMAND (builtin_uri_unbind_command, static) =
249{
250 .path = "builtin uri unbind",
251 .short_help = "builtin uri unbind",
252 .function = builtin_uri_unbind_command_fn,
253};
254/* *INDENT-ON* */
255
256/*
257 * fd.io coding-style-patch-verification: ON
258 *
259 * Local Variables:
260 * eval: (c-set-style "gnu")
261 * End:
262 */