FD.io VPP  v18.07-rc0-415-g6c78436
Vector Packet Processing
application_interface.c
Go to the documentation of this file.
1 /*
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  */
16 
17 #include <vnet/session/session.h>
18 #include <vlibmemory/api.h>
19 #include <vnet/dpo/load_balance.h>
20 
21 /** @file
22  VPP's application/session API bind/unbind/connect/disconnect calls
23 */
24 
25 /*
26  * TLS server cert and keys to be used for testing only
27  */
28 const char test_srv_crt_rsa[] =
29  "-----BEGIN CERTIFICATE-----\r\n"
30  "MIID5zCCAs+gAwIBAgIJALeMYCEHrTtJMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD\r\n"
31  "VQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMQ4wDAYDVQQK\r\n"
32  "DAVDaXNjbzEOMAwGA1UECwwFZmQuaW8xFjAUBgNVBAMMDXRlc3R0bHMuZmQuaW8x\r\n"
33  "IjAgBgkqhkiG9w0BCQEWE3ZwcC1kZXZAbGlzdHMuZmQuaW8wHhcNMTgwMzA1MjEx\r\n"
34  "NTEyWhcNMjgwMzAyMjExNTEyWjCBiTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB\r\n"
35  "MREwDwYDVQQHDAhTYW4gSm9zZTEOMAwGA1UECgwFQ2lzY28xDjAMBgNVBAsMBWZk\r\n"
36  "LmlvMRYwFAYDVQQDDA10ZXN0dGxzLmZkLmlvMSIwIAYJKoZIhvcNAQkBFhN2cHAt\r\n"
37  "ZGV2QGxpc3RzLmZkLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\r\n"
38  "4C1k8a1DuStgggqT4o09fP9sJ2dC54bxhS/Xk2VEfaIZ222WSo4X/syRVfVy9Yah\r\n"
39  "cpI1zJ/RDxaZSFhgA+nPZBrFMsrULkrdAOpOVj8eDEp9JuWdO2ODSoFnCvLxcYWB\r\n"
40  "Yc5kHryJpEaGJl1sFQSesnzMFty/59ta0stk0Fp8r5NhIjWvSovGzPo6Bhz+VS2c\r\n"
41  "ebIZh4x1t2hHaFcgm0qJoJ6DceReWCW8w+yOVovTolGGq+bpb2Hn7MnRSZ2K2NdL\r\n"
42  "+aLXpkZbS/AODP1FF2vTO1mYL290LO7/51vJmPXNKSDYMy5EvILr5/VqtjsFCwRL\r\n"
43  "Q4jcM/+GeHSAFWx4qIv0BwIDAQABo1AwTjAdBgNVHQ4EFgQUWa1SOB37xmT53tZQ\r\n"
44  "aXuLLhRI7U8wHwYDVR0jBBgwFoAUWa1SOB37xmT53tZQaXuLLhRI7U8wDAYDVR0T\r\n"
45  "BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAoUht13W4ya27NVzQuCMvqPWL3VM4\r\n"
46  "3xbPFk02FaGz/WupPu276zGlzJAZrbuDcQowwwU1Ni1Yygxl96s1c2M5rHDTrOKG\r\n"
47  "rK0hbkSFBo+i6I8u4HiiQ4rYmG0Hv6+sXn3of0HsbtDPGgWZoipPWDljPYEURu3e\r\n"
48  "3HRe/Dtsj9CakBoSDzs8ndWaBR+f4sM9Tk1cjD46Gq2T/qpSPXqKxEUXlzhdCAn4\r\n"
49  "twub17Bq2kykHpppCwPg5M+v30tHG/R2Go15MeFWbEJthFk3TZMjKL7UFs7fH+x2\r\n"
50  "wSonXb++jY+KmCb93C+soABBizE57g/KmiR2IxQ/LMjDik01RSUIaM0lLA==\r\n"
51  "-----END CERTIFICATE-----\r\n";
53 
54 const char test_srv_key_rsa[] =
55  "-----BEGIN PRIVATE KEY-----\r\n"
56  "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgLWTxrUO5K2CC\r\n"
57  "CpPijT18/2wnZ0LnhvGFL9eTZUR9ohnbbZZKjhf+zJFV9XL1hqFykjXMn9EPFplI\r\n"
58  "WGAD6c9kGsUyytQuSt0A6k5WPx4MSn0m5Z07Y4NKgWcK8vFxhYFhzmQevImkRoYm\r\n"
59  "XWwVBJ6yfMwW3L/n21rSy2TQWnyvk2EiNa9Ki8bM+joGHP5VLZx5shmHjHW3aEdo\r\n"
60  "VyCbSomgnoNx5F5YJbzD7I5Wi9OiUYar5ulvYefsydFJnYrY10v5otemRltL8A4M\r\n"
61  "/UUXa9M7WZgvb3Qs7v/nW8mY9c0pINgzLkS8guvn9Wq2OwULBEtDiNwz/4Z4dIAV\r\n"
62  "bHioi/QHAgMBAAECggEBAMzGipP8+oT166U+NlJXRFifFVN1DvdhG9PWnOxGL+c3\r\n"
63  "ILmBBC08WQzmHshPemBvR6DZkA1H23cV5JTiLWrFtC00CvhXsLRMrE5+uWotI6yE\r\n"
64  "iofybMroHvD6/X5R510UX9hQ6MHu5ShLR5VZ9zXHz5MpTmB/60jG5dLx+jgcwBK8\r\n"
65  "LuGv2YB/WCUwT9QJ3YU2eaingnXtz/MrFbkbltrqlnBdlD+kTtw6Yac9y1XuuQXc\r\n"
66  "BPeulLNDuPolJVWbUvDBZrpt2dXTgz8ws1sv+wCNE0xwQJsqW4Nx3QkpibUL9RUr\r\n"
67  "CVbKlNfa9lopT6nGKlgX69R/uH35yh9AOsfasro6w0ECgYEA82UJ8u/+ORah+0sF\r\n"
68  "Q0FfW5MTdi7OAUHOz16pUsGlaEv0ERrjZxmAkHA/VRwpvDBpx4alCv0Hc39PFLIk\r\n"
69  "nhSsM2BEuBkTAs6/GaoNAiBtQVE/hN7awNRWVmlieS0go3Y3dzaE9IUMyj8sPOFT\r\n"
70  "5JdJ6BM69PHKCkY3dKdnnfpFEuECgYEA68mRpteunF1mdZgXs+WrN+uLlRrQR20F\r\n"
71  "ZyMYiUCH2Dtn26EzA2moy7FipIIrQcX/j+KhYNGM3e7MU4LymIO29E18mn8JODnH\r\n"
72  "sQOXzBTsf8A4yIVMkcuQD3bfb0JiUGYUPOidTp2N7IJA7+6Yc3vQOyb74lnKnJoO\r\n"
73  "gougPT2wS+cCgYAn7muzb6xFsXDhyW0Tm6YJYBfRS9yAWEuVufINobeBZPSl2cN1\r\n"
74  "Jrnw+HlrfTNbrJWuJmjtZJXUXQ6cVp2rUbjutNyRV4vG6iRwEXYQ40EJdkr1gZpi\r\n"
75  "CHQhuShuuPih2MNAy7EEbM+sXrDjTBR3bFqzuHPzu7dp+BshCFX3lRfAAQKBgGQt\r\n"
76  "K5i7IhCFDjb/+3IPLgOAK7mZvsvZ4eXD33TQ2eZgtut1PXtBtNl17/b85uv293Fm\r\n"
77  "VDISVcsk3eLNS8zIiT6afUoWlxAwXEs0v5WRfjl4radkGvgGiJpJYvyeM67877RB\r\n"
78  "EDSKc/X8ESLfOB44iGvZUEMG6zJFscx9DgN25iQZAoGAbyd+JEWwdVH9/K3IH1t2\r\n"
79  "PBkZX17kNWv+iVM1WyFjbe++vfKZCrOJiyiqhDeEqgrP3AuNMlaaduC3VRC3G5oV\r\n"
80  "Mj1tlhDWQ/qhvKdCKNdIVQYDE75nw+FRWV8yYkHAnXYW3tNoweDIwixE0hkPR1bc\r\n"
81  "oEjPLVNtx8SOj/M4rhaPT3I=\r\n" "-----END PRIVATE KEY-----\r\n";
83 
84 static u8
86 {
87  return (ip_is_zero (&sep->ip, sep->is_ip4)
88  || ip_is_local_host (&sep->ip, sep->is_ip4));
89 }
90 
91 static u8
93 {
94  return ip_is_zero (&sep->ip, sep->is_ip4);
95 }
96 
97 u8
99 {
100  u8 is_lep = session_endpoint_is_local (sep);
101  if (!is_lep && sep->sw_if_index != ENDPOINT_INVALID_INDEX
102  && !ip_interface_has_address (sep->sw_if_index, &sep->ip, sep->is_ip4))
103  {
104  clib_warning ("sw_if_index %u not configured with ip %U",
105  sep->sw_if_index, format_ip46_address, &sep->ip,
106  sep->is_ip4);
107  return 0;
108  }
109  return (is_lep || ip_is_local (sep->fib_index, &sep->ip, sep->is_ip4));
110 }
111 
112 int
113 api_parse_session_handle (u64 handle, u32 * session_index, u32 * thread_index)
114 {
116  stream_session_t *pool;
117 
118  *thread_index = handle & 0xFFFFFFFF;
119  *session_index = handle >> 32;
120 
121  if (*thread_index >= vec_len (smm->sessions))
122  return VNET_API_ERROR_INVALID_VALUE;
123 
124  pool = smm->sessions[*thread_index];
125 
126  if (pool_is_free_index (pool, *session_index))
127  return VNET_API_ERROR_INVALID_VALUE_2;
128 
129  return 0;
130 }
131 
132 static void
134  application_t * app)
135 {
136  app_namespace_t *app_ns;
137  app_ns = app_namespace_get (app->ns_index);
138  if (app_ns)
139  {
140  /* Ask transport and network to bind to/connect using local interface
141  * that "supports" app's namespace. This will fix our local connection
142  * endpoint.
143  */
144  sep->sw_if_index = app_ns->sw_if_index;
145  sep->fib_index =
146  sep->is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
147  }
148 }
149 
150 static int
151 vnet_bind_i (u32 app_index, session_endpoint_t * sep, u64 * handle)
152 {
153  u64 lh, ll_handle = SESSION_INVALID_HANDLE;
154  application_t *app;
155  u32 table_index;
156  int rv;
157 
158  app = application_get_if_valid (app_index);
159  if (!app)
160  {
161  SESSION_DBG ("app not attached");
162  return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
163  }
164 
166  if (!session_endpoint_in_ns (sep))
167  return VNET_API_ERROR_INVALID_VALUE_2;
168 
169  table_index = application_session_table (app,
171  lh = session_lookup_endpoint_listener (table_index, sep, 1);
172  if (lh != SESSION_INVALID_HANDLE)
173  return VNET_API_ERROR_ADDRESS_IN_USE;
174 
175  /*
176  * Add session endpoint to local session table. Only binds to "inaddr_any"
177  * (i.e., zero address) are added to local scope table.
178  */
180  {
181  if ((rv = application_start_local_listen (app, sep, handle)))
182  return rv;
183  ll_handle = *handle;
184  }
185 
186  if (!application_has_global_scope (app))
187  return (ll_handle == SESSION_INVALID_HANDLE ? -1 : 0);
188 
189  /*
190  * Add session endpoint to global session table
191  */
192 
193  /* Setup listen path down to transport */
194  rv = application_start_listen (app, sep, handle);
195  if (rv && ll_handle != SESSION_INVALID_HANDLE)
196  session_lookup_del_session_endpoint (table_index, sep);
197 
198  /*
199  * Store in local table listener the index of the transport layer
200  * listener. We'll need local listeners are hit and we need to
201  * return global handle
202  */
203  if (ll_handle != SESSION_INVALID_HANDLE)
204  {
205  local_session_t *ll;
206  stream_session_t *tl;
208  tl = listen_session_get_from_handle (*handle);
209  ll->transport_listener_index = tl->session_index;
210  }
211  return rv;
212 }
213 
214 int
215 vnet_unbind_i (u32 app_index, session_handle_t handle)
216 {
217  application_t *app;
218  int rv;
219 
220  if (!(app = application_get_if_valid (app_index)))
221  {
222  SESSION_DBG ("app (%d) not attached", app_index);
223  return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
224  }
225 
226  if (application_has_local_scope (app))
227  {
228  if ((rv = application_stop_local_listen (app, handle)))
229  return rv;
230  }
231 
232  /*
233  * Clear the global scope table of the listener
234  */
236  return application_stop_listen (app, handle);
237  return 0;
238 }
239 
240 int
241 application_connect (u32 client_index, u32 api_context,
242  session_endpoint_t * sep)
243 {
244  application_t *server, *client;
245  u32 table_index, server_index, li;
246  stream_session_t *listener;
247  local_session_t *ll;
248  u64 lh;
249 
250  if (session_endpoint_is_zero (sep))
251  return VNET_API_ERROR_INVALID_VALUE;
252 
253  client = application_get (client_index);
254  session_endpoint_update_for_app (sep, client);
255 
256  /*
257  * First check the local scope for locally attached destinations.
258  * If we have local scope, we pass *all* connects through it since we may
259  * have special policy rules even for non-local destinations, think proxy.
260  */
261  if (application_has_local_scope (client))
262  {
263  table_index = application_local_session_table (client);
264  lh = session_lookup_local_endpoint (table_index, sep);
265  if (lh == SESSION_DROP_HANDLE)
266  return VNET_API_ERROR_APP_CONNECT_FILTERED;
267 
268  if (lh == SESSION_INVALID_HANDLE)
269  goto global_scope;
270 
271  local_session_parse_handle (lh, &server_index, &li);
272 
273  /*
274  * Break loop if rule in local table points to connecting app. This
275  * can happen if client is a generic proxy. Route connect through
276  * global table instead.
277  */
278  if (server_index != client_index)
279  {
280  server = application_get (server_index);
281  ll = application_get_local_listen_session (server, li);
282  return application_local_session_connect (table_index, client,
283  server, ll, api_context);
284  }
285  }
286 
287  /*
288  * If nothing found, check the global scope for locally attached
289  * destinations. Make sure first that we're allowed to.
290  */
291 
292 global_scope:
293  if (session_endpoint_is_local (sep))
294  return VNET_API_ERROR_SESSION_CONNECT;
295 
296  if (!application_has_global_scope (client))
297  return VNET_API_ERROR_APP_CONNECT_SCOPE;
298 
299  table_index = application_session_table (client,
301  listener = session_lookup_listener (table_index, sep);
302  if (listener)
303  {
304  server = application_get (listener->app_index);
305  if (server)
306  return application_local_session_connect (table_index, client, server,
307  (local_session_t *)
308  listener, api_context);
309  }
310 
311  /*
312  * Not connecting to a local server, propagate to transport
313  */
314  if (application_open_session (client, sep, api_context))
315  return VNET_API_ERROR_SESSION_CONNECT;
316  return 0;
317 }
318 
319 /**
320  * unformat a vnet URI
321  *
322  * transport-proto://[hostname]ip46-addr:port
323  * eg. tcp://ip46-addr:port
324  * tls://[testtsl.fd.io]ip46-addr:port
325  *
326  * u8 ip46_address[16];
327  * u16 port_in_host_byte_order;
328  * stream_session_type_t sst;
329  * u8 *fifo_name;
330  *
331  * if (unformat (input, "%U", unformat_vnet_uri, &ip46_address,
332  * &sst, &port, &fifo_name))
333  * etc...
334  *
335  */
336 uword
337 unformat_vnet_uri (unformat_input_t * input, va_list * args)
338 {
339  session_endpoint_extended_t *sep = va_arg (*args,
341  u32 transport_proto = 0, port;
342 
343  if (unformat (input, "%U://%U/%d", unformat_transport_proto,
344  &transport_proto, unformat_ip4_address, &sep->ip.ip4, &port))
345  {
346  sep->transport_proto = transport_proto;
347  sep->port = clib_host_to_net_u16 (port);
348  sep->is_ip4 = 1;
349  return 1;
350  }
351  else if (unformat (input, "%U://[%s]%U/%d", unformat_transport_proto,
352  &transport_proto, &sep->hostname, unformat_ip4_address,
353  &sep->ip.ip4, &port))
354  {
355  sep->transport_proto = transport_proto;
356  sep->port = clib_host_to_net_u16 (port);
357  sep->is_ip4 = 1;
358  return 1;
359  }
360  else if (unformat (input, "%U://%U/%d", unformat_transport_proto,
361  &transport_proto, unformat_ip6_address, &sep->ip.ip6,
362  &port))
363  {
364  sep->transport_proto = transport_proto;
365  sep->port = clib_host_to_net_u16 (port);
366  sep->is_ip4 = 0;
367  return 1;
368  }
369  else if (unformat (input, "%U://[%s]%U/%d", unformat_transport_proto,
370  &transport_proto, &sep->hostname, unformat_ip6_address,
371  &sep->ip.ip6, &port))
372  {
373  sep->transport_proto = transport_proto;
374  sep->port = clib_host_to_net_u16 (port);
375  sep->is_ip4 = 0;
376  return 1;
377  }
378  return 0;
379 }
380 
381 static u8 *cache_uri;
383 
384 int
386 {
387  unformat_input_t _input, *input = &_input;
388 
389  if (cache_uri && !strncmp (uri, (char *) cache_uri, vec_len (cache_uri)))
390  {
391  *sep = *cache_sep;
392  return 0;
393  }
394 
395  /* Make sure */
396  uri = (char *) format (0, "%s%c", uri, 0);
397 
398  /* Parse uri */
399  unformat_init_string (input, uri, strlen (uri));
400  if (!unformat (input, "%U", unformat_vnet_uri, sep))
401  {
402  unformat_free (input);
403  return VNET_API_ERROR_INVALID_VALUE;
404  }
405  unformat_free (input);
406 
408  cache_uri = (u8 *) uri;
409  if (cache_sep)
411  cache_sep = clib_mem_alloc (sizeof (*sep));
412  *cache_sep = *sep;
413 
414  return 0;
415 }
416 
417 static int
418 session_validate_namespace (u8 * namespace_id, u64 secret, u32 * app_ns_index)
419 {
420  app_namespace_t *app_ns;
421  if (vec_len (namespace_id) == 0)
422  {
423  /* Use default namespace */
424  *app_ns_index = 0;
425  return 0;
426  }
427 
428  *app_ns_index = app_namespace_index_from_id (namespace_id);
429  if (*app_ns_index == APP_NAMESPACE_INVALID_INDEX)
430  return VNET_API_ERROR_APP_INVALID_NS;
431  app_ns = app_namespace_get (*app_ns_index);
432  if (!app_ns)
433  return VNET_API_ERROR_APP_INVALID_NS;
434  if (app_ns->ns_secret != secret)
435  return VNET_API_ERROR_APP_WRONG_NS_SECRET;
436  return 0;
437 }
438 
439 /**
440  * Attach application to vpp
441  *
442  * Allocates a vpp app, i.e., a structure that keeps back pointers
443  * to external app and a segment manager for shared memory fifo based
444  * communication with the external app.
445  */
446 clib_error_t *
448 {
450  application_t *app = 0;
451  segment_manager_t *sm;
452  u32 app_ns_index = 0;
453  u64 secret;
454  int rv;
455 
456  if (a->api_client_index != APP_INVALID_INDEX)
457  app = application_lookup (a->api_client_index);
458  else if (a->name)
459  app = application_lookup_name (a->name);
460  else
461  return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
462  "api index or name must be provided");
463 
464  if (app)
465  return clib_error_return_code (0, VNET_API_ERROR_APP_ALREADY_ATTACHED, 0,
466  "app already attached");
467 
468  secret = a->options[APP_OPTIONS_NAMESPACE_SECRET];
469  if ((rv = session_validate_namespace (a->namespace_id, secret,
470  &app_ns_index)))
471  return clib_error_return_code (0, rv, 0, "namespace validation: %d", rv);
472  a->options[APP_OPTIONS_NAMESPACE] = app_ns_index;
473  app = application_new ();
474  if ((rv = application_init (app, a->api_client_index, a->name, a->options,
475  a->session_cb_vft)))
476  return clib_error_return_code (0, rv, 0, "app init: %d", rv);
477 
478  a->app_event_queue_address = pointer_to_uword (app->event_queue);
479  sm = segment_manager_get (app->first_segment_manager);
481 
482  if (application_is_proxy (app))
484 
485  ASSERT (vec_len (fs->ssvm.name) <= 128);
486  a->segment = &fs->ssvm;
487  a->app_index = app->index;
488 
490 
491  return 0;
492 }
493 
494 /**
495  * Detach application from vpp
496  */
497 int
499 {
500  application_t *app;
501  app = application_get_if_valid (a->app_index);
502 
503  if (!app)
504  {
505  clib_warning ("app not attached");
506  return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
507  }
508 
509  application_del (app);
510  return 0;
511 }
512 
513 int
515 {
517  int rv;
518 
519  rv = parse_uri (a->uri, &sep);
520  if (rv)
521  return rv;
522 
523  return vnet_bind_i (a->app_index, (session_endpoint_t *) & sep, &a->handle);
524 }
525 
526 int
528 {
530  stream_session_t *listener;
531  u32 table_index;
532  int rv;
533 
534  rv = parse_uri (a->uri, &sep);
535  if (rv)
536  return rv;
537 
538  /* NOTE: only default fib tables supported for uri apis */
539  table_index = session_lookup_get_index_for_fib (fib_ip_proto (!sep.is_ip4),
540  0);
541  listener = session_lookup_listener (table_index,
542  (session_endpoint_t *) & sep);
543  if (!listener)
544  return VNET_API_ERROR_ADDRESS_NOT_IN_USE;
545 
546  return vnet_unbind_i (a->app_index, listen_session_get_handle (listener));
547 }
548 
549 clib_error_t *
551 {
553  int rv;
554 
555  /* Parse uri */
556  rv = parse_uri (a->uri, &sep);
557  if (rv)
558  return clib_error_return_code (0, rv, 0, "app init: %d", rv);
559 
560  if ((rv = application_connect (a->app_index, a->api_context,
561  (session_endpoint_t *) & sep)))
562  return clib_error_return_code (0, rv, 0, "connect failed");
563  return 0;
564 }
565 
566 int
568 {
569  if (session_handle_is_local (a->handle))
570  {
571  local_session_t *ls;
573  if (ls->app_index != a->app_index && ls->client_index != a->app_index)
574  {
575  clib_warning ("app %u is neither client nor server for session %u",
576  a->app_index, a->app_index);
577  return VNET_API_ERROR_INVALID_VALUE;
578  }
579  return application_local_session_disconnect (a->app_index, ls);
580  }
581  else
582  {
583  stream_session_t *s;
584  s = session_get_from_handle_if_valid (a->handle);
585  if (!s || s->app_index != a->app_index)
586  return VNET_API_ERROR_INVALID_VALUE;
587 
588  /* We're peeking into another's thread pool. Make sure */
589  ASSERT (s->session_index == session_index_from_handle (a->handle));
590 
592  }
593  return 0;
594 }
595 
596 clib_error_t *
598 {
599  int rv;
600  if ((rv = vnet_bind_i (a->app_index, &a->sep, &a->handle)))
601  return clib_error_return_code (0, rv, 0, "bind failed");
602  return 0;
603 }
604 
605 clib_error_t *
607 {
608  int rv;
609  if ((rv = vnet_unbind_i (a->app_index, a->handle)))
610  return clib_error_return_code (0, rv, 0, "unbind failed");
611  return 0;
612 }
613 
614 clib_error_t *
616 {
617  session_endpoint_t *sep = (session_endpoint_t *) & a->sep;
618  int rv;
619 
620  if ((rv = application_connect (a->app_index, a->api_context, sep)))
621  return clib_error_return_code (0, rv, 0, "connect failed");
622  return 0;
623 }
624 
625 /*
626  * fd.io coding-style-patch-verification: ON
627  *
628  * Local Variables:
629  * eval: (c-set-style "gnu")
630  * End:
631  */
int application_open_session(application_t *app, session_endpoint_t *sep, u32 api_context)
Definition: application.c:513
#define SESSION_DROP_HANDLE
Definition: session_table.h:60
u8 session_endpoint_in_ns(session_endpoint_t *sep)
#define APP_NAMESPACE_INVALID_INDEX
void segment_manager_segment_reader_unlock(segment_manager_t *sm)
static session_endpoint_extended_t * cache_sep
a
Definition: bitmap.h:537
const u32 test_srv_crt_rsa_len
u64 session_lookup_endpoint_listener(u32 table_index, session_endpoint_t *sep, u8 use_rules)
Lookup listener for session endpoint in table.
static u8 session_endpoint_is_local(session_endpoint_t *sep)
u8 application_has_global_scope(application_t *app)
Definition: application.c:613
struct _vnet_connect_args vnet_connect_args_t
int vnet_bind_uri(vnet_bind_args_t *a)
const u32 test_srv_key_rsa_len
u8 ip_is_local(u32 fib_index, ip46_address_t *ip46_address, u8 is_ip4)
Checks that an ip is local to the requested fib.
Definition: ip.c:55
unsigned long u64
Definition: types.h:89
int application_stop_listen(application_t *srv, session_handle_t handle)
Stop listening on session associated to handle.
Definition: application.c:477
clib_error_t * vnet_unbind(vnet_unbind_args_t *a)
int application_start_local_listen(application_t *server, session_endpoint_t *sep, session_handle_t *handle)
Definition: application.c:857
application_t * application_lookup_name(const u8 *name)
Definition: application.c:147
u8 ip_interface_has_address(u32 sw_if_index, ip46_address_t *ip, u8 is_ip4)
Definition: ip.c:99
application_t * application_new()
Definition: application.c:158
u32 session_lookup_get_index_for_fib(u32 fib_proto, u32 fib_index)
u32 client_index
Client data.
local_session_t * application_get_local_session_from_handle(session_handle_t handle)
Definition: application.c:837
application_t * application_lookup(u32 api_client_index)
Definition: application.c:136
format_function_t format_ip46_address
Definition: format.h:61
static int vnet_bind_i(u32 app_index, session_endpoint_t *sep, u64 *handle)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static u8 * cache_uri
u64 session_handle_t
Definition: session.h:91
static u32 session_index_from_handle(session_handle_t handle)
Definition: session.h:316
#define SESSION_ENDPOINT_EXT_NULL
unsigned char u8
Definition: types.h:56
stream_session_t * session_lookup_listener(u32 table_index, session_endpoint_t *sep)
Lookup listener, exact or proxy (inaddr_any:0) match.
static stream_session_t * listen_session_get_from_handle(session_handle_t handle)
Definition: session.h:568
int application_is_proxy(application_t *app)
Definition: application.c:579
int vnet_unbind_uri(vnet_unbind_args_t *a)
unformat_function_t unformat_ip4_address
Definition: format.h:76
struct _vnet_disconnect_args_t vnet_disconnect_args_t
u32 transport_listener_index
struct _vnet_unbind_args_t vnet_unbind_args_t
svm_fifo_segment_private_t * segment_manager_get_segment_w_lock(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager&#39;s pool and acquires reader lock.
unsigned int u32
Definition: types.h:88
static local_session_t * application_get_local_listen_session(application_t *app, u32 session_index)
Definition: application.h:243
u32 app_namespace_index_from_id(const u8 *ns_id)
struct _stream_session_t stream_session_t
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:1023
struct _vnet_app_attach_args_t vnet_app_attach_args_t
static session_manager_main_t * vnet_get_session_manager_main()
Definition: session.h:266
struct _session_endpoint session_endpoint_t
static void local_session_parse_handle(session_handle_t handle, u32 *server_index, u32 *session_index)
Definition: application.h:226
static u8 session_handle_is_local(session_handle_t handle)
Definition: session.h:353
struct _unformat_input_t unformat_input_t
#define APP_INVALID_INDEX
Definition: application.h:136
app_namespace_t * app_namespace_get(u32 index)
clib_error_t * vnet_connect(vnet_connect_args_t *a)
u32 application_session_table(application_t *app, u8 fib_proto)
Definition: application.c:60
struct _session_manager_main session_manager_main_t
Definition: session.h:153
int parse_uri(char *uri, session_endpoint_extended_t *sep)
const char test_srv_crt_rsa[]
unformat_function_t unformat_ip6_address
Definition: format.h:97
#define SESSION_DBG(_fmt, _args...)
u64 session_lookup_local_endpoint(u32 table_index, session_endpoint_t *sep)
Look up endpoint in local session table.
u32 application_local_session_table(application_t *app)
Definition: application.c:75
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
#define ENDPOINT_INVALID_INDEX
Definition: transport.h:116
int session_lookup_del_session_endpoint(u32 table_index, session_endpoint_t *sep)
#define clib_warning(format, args...)
Definition: error.h:59
#define SESSION_INVALID_HANDLE
Definition: session_table.h:59
int vnet_unbind_i(u32 app_index, session_handle_t handle)
int application_start_listen(application_t *srv, session_endpoint_t *sep, session_handle_t *res)
Start listening local transport endpoint for requested transport.
Definition: application.c:436
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:270
struct _application application_t
int vnet_disconnect_session(vnet_disconnect_args_t *a)
int api_parse_session_handle(u64 handle, u32 *session_index, u32 *thread_index)
struct _app_namespace app_namespace_t
static stream_session_t * session_get_from_handle_if_valid(session_handle_t handle)
Definition: session.h:345
#define ASSERT(truth)
clib_error_t * vnet_bind(vnet_bind_args_t *a)
uword unformat_transport_proto(unformat_input_t *input, va_list *args)
Definition: transport.c:90
static local_session_t * application_get_local_listener_w_handle(session_handle_t handle)
Definition: application.h:249
static void session_endpoint_update_for_app(session_endpoint_t *sep, application_t *app)
static u8 session_endpoint_fib_proto(session_endpoint_t *sep)
int application_stop_local_listen(application_t *server, session_handle_t lh)
Clean up local session table.
Definition: application.c:895
static void clib_mem_free(void *p)
Definition: mem.h:179
static u8 session_endpoint_is_zero(session_endpoint_t *sep)
void application_del(application_t *app)
Definition: application.c:173
void stream_session_disconnect(stream_session_t *s)
Initialize session disconnect.
Definition: session.c:1063
int application_local_session_disconnect(u32 app_index, local_session_t *ls)
Definition: application.c:1121
struct _vnet_app_detach_args_t vnet_app_detach_args_t
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
static uword pointer_to_uword(const void *p)
Definition: types.h:131
u8 * name
Definition: ssvm.h:86
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:20
uword unformat_vnet_uri(unformat_input_t *input, va_list *args)
unformat a vnet URI
clib_error_t * vnet_connect_uri(vnet_connect_args_t *a)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
Definition: fib_types.h:80
application_t * application_get(u32 index)
Definition: application.c:386
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
u8 ip_is_local_host(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:29
struct _segment_manager segment_manager_t
int application_init(application_t *app, u32 api_client_index, u8 *app_name, u64 *options, session_cb_vft_t *cb_fns)
Definition: application.c:291
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
void application_setup_proxy(application_t *app)
Definition: application.c:766
static int session_validate_namespace(u8 *namespace_id, u64 secret, u32 *app_ns_index)
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
struct _vnet_bind_args_t vnet_bind_args_t
static segment_manager_t * segment_manager_get(u32 index)
static u64 listen_session_get_handle(stream_session_t *s)
Definition: session.h:561
struct _session_endpoint_extended session_endpoint_extended_t
application_t * application_get_if_valid(u32 index)
Definition: application.c:394
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
const char test_srv_key_rsa[]
int application_connect(u32 client_index, u32 api_context, session_endpoint_t *sep)
int application_local_session_connect(u32 table_index, application_t *client, application_t *server, local_session_t *ll, u32 opaque)
Definition: application.c:942
u8 application_has_local_scope(application_t *app)
Definition: application.c:607
u32 app_index
Server index.