Line data Source code
1 : /*
2 : * Copyright (c) 2016-2019 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 : #include <vnet/session/application_interface.h>
16 : #include <vnet/session/application.h>
17 : #include <vnet/session/session.h>
18 :
19 : /** @file
20 : VPP's application/session API bind/unbind/connect/disconnect calls
21 : */
22 :
23 : /**
24 : * unformat a vnet URI
25 : *
26 : * transport-proto://[hostname]ip46-addr:port
27 : * eg. tcp://ip46-addr:port
28 : * tls://[testtsl.fd.io]ip46-addr:port
29 : *
30 : * u8 ip46_address[16];
31 : * u16 port_in_host_byte_order;
32 : * stream_session_type_t sst;
33 : * u8 *fifo_name;
34 : *
35 : * if (unformat (input, "%U", unformat_vnet_uri, &ip46_address,
36 : * &sst, &port, &fifo_name))
37 : * etc...
38 : *
39 : */
40 : uword
41 9 : unformat_vnet_uri (unformat_input_t * input, va_list * args)
42 : {
43 9 : session_endpoint_cfg_t *sep = va_arg (*args, session_endpoint_cfg_t *);
44 9 : u32 transport_proto = 0, port;
45 :
46 9 : if (unformat (input, "%U://%U/%d", unformat_transport_proto,
47 : &transport_proto, unformat_ip4_address, &sep->ip.ip4, &port))
48 : {
49 9 : sep->transport_proto = transport_proto;
50 9 : sep->port = clib_host_to_net_u16 (port);
51 9 : sep->is_ip4 = 1;
52 9 : return 1;
53 : }
54 0 : else if (unformat (input, "%U://%U/%d", unformat_transport_proto,
55 : &transport_proto, unformat_ip6_address, &sep->ip.ip6,
56 : &port))
57 : {
58 0 : sep->transport_proto = transport_proto;
59 0 : sep->port = clib_host_to_net_u16 (port);
60 0 : sep->is_ip4 = 0;
61 0 : return 1;
62 : }
63 0 : else if (unformat (input, "%U://session/%lu", unformat_transport_proto,
64 : &transport_proto, &sep->parent_handle))
65 : {
66 0 : sep->transport_proto = transport_proto;
67 0 : sep->ip.ip4.as_u32 = 1; /* ip need to be non zero in vnet */
68 0 : return 1;
69 : }
70 0 : return 0;
71 : }
72 :
73 : static u8 *cache_uri;
74 : static session_endpoint_cfg_t *cache_sep;
75 :
76 : session_error_t
77 41 : parse_uri (char *uri, session_endpoint_cfg_t *sep)
78 : {
79 41 : unformat_input_t _input, *input = &_input;
80 :
81 41 : if (cache_uri && !strncmp (uri, (char *) cache_uri, vec_len (cache_uri)))
82 : {
83 32 : *sep = *cache_sep;
84 32 : return 0;
85 : }
86 :
87 : /* Make sure */
88 9 : uri = (char *) format (0, "%s%c", uri, 0);
89 :
90 : /* Parse uri */
91 9 : unformat_init_string (input, uri, strlen (uri));
92 9 : if (!unformat (input, "%U", unformat_vnet_uri, sep))
93 : {
94 0 : unformat_free (input);
95 0 : return SESSION_E_INVALID;
96 : }
97 9 : unformat_free (input);
98 :
99 9 : vec_free (cache_uri);
100 9 : cache_uri = (u8 *) uri;
101 9 : if (cache_sep)
102 0 : clib_mem_free (cache_sep);
103 9 : cache_sep = clib_mem_alloc (sizeof (*sep));
104 9 : *cache_sep = *sep;
105 :
106 9 : return 0;
107 : }
108 :
109 : int
110 0 : vnet_bind_uri (vnet_listen_args_t * a)
111 : {
112 0 : session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
113 : int rv;
114 :
115 0 : rv = parse_uri (a->uri, &sep);
116 0 : if (rv)
117 0 : return rv;
118 0 : sep.app_wrk_index = 0;
119 0 : clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
120 0 : return vnet_listen (a);
121 : }
122 :
123 : session_error_t
124 0 : vnet_unbind_uri (vnet_unlisten_args_t *a)
125 : {
126 0 : session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
127 : application_t *app;
128 : session_t *listener;
129 : u32 table_index;
130 : session_error_t rv;
131 :
132 0 : if ((rv = parse_uri (a->uri, &sep)))
133 0 : return rv;
134 :
135 0 : app = application_get (a->app_index);
136 0 : if (!app)
137 0 : return SESSION_E_INVALID;
138 :
139 0 : table_index = application_session_table (app, fib_ip_proto (!sep.is_ip4));
140 0 : listener = session_lookup_listener (table_index,
141 : (session_endpoint_t *) & sep);
142 0 : if (!listener)
143 0 : return SESSION_E_ADDR_NOT_IN_USE;
144 0 : a->handle = listen_session_get_handle (listener);
145 0 : return vnet_unlisten (a);
146 : }
147 :
148 : session_error_t
149 0 : vnet_connect_uri (vnet_connect_args_t *a)
150 : {
151 0 : session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
152 : session_error_t rv;
153 :
154 0 : if ((rv = parse_uri (a->uri, &sep)))
155 0 : return rv;
156 :
157 0 : clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
158 0 : if ((rv = vnet_connect (a)))
159 0 : return rv;
160 0 : return 0;
161 : }
162 :
163 : /*
164 : * fd.io coding-style-patch-verification: ON
165 : *
166 : * Local Variables:
167 : * eval: (c-set-style "gnu")
168 : * End:
169 : */
|