blob: 335905d6ead94adc9ede33225fe1ac52ea3fe58e [file] [log] [blame]
Florin Coras04e53442017-07-16 17:12:15 -07001/*
Florin Coras288eaab2019-02-03 15:26:14 -08002 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
Florin Coras04e53442017-07-16 17:12:15 -07003 * 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/** Generate typed init functions for multiple hash table styles... */
17#include <vppinfra/bihash_16_8.h>
18#include <vppinfra/bihash_template.h>
19
20#include <vppinfra/bihash_template.c>
21
22#undef __included_bihash_template_h__
23
24#include <vppinfra/bihash_48_8.h>
25#include <vppinfra/bihash_template.h>
26
27#include <vppinfra/bihash_template.c>
28#include <vnet/session/session_lookup.h>
29#include <vnet/session/session.h>
Florin Corascea194d2017-10-02 00:18:51 -070030#include <vnet/session/application.h>
Florin Coras04e53442017-07-16 17:12:15 -070031
Florin Corascea194d2017-10-02 00:18:51 -070032/**
Florin Corascea194d2017-10-02 00:18:51 -070033 * Network namespace index (i.e., fib index) to session lookup table. We
34 * should have one per network protocol type but for now we only support IP4/6
35 */
36static u32 *fib_index_to_table_index[2];
37
Florin Coras04e53442017-07-16 17:12:15 -070038/* *INDENT-OFF* */
39/* 16 octets */
40typedef CLIB_PACKED (struct {
41 union
42 {
43 struct
44 {
45 ip4_address_t src;
46 ip4_address_t dst;
47 u16 src_port;
48 u16 dst_port;
49 /* align by making this 4 octets even though its a 1-bit field
50 * NOTE: avoid key overlap with other transports that use 5 tuples for
51 * session identification.
52 */
53 u32 proto;
54 };
55 u64 as_u64[2];
56 };
57}) v4_connection_key_t;
58
59typedef CLIB_PACKED (struct {
60 union
61 {
62 struct
63 {
64 /* 48 octets */
65 ip6_address_t src;
66 ip6_address_t dst;
67 u16 src_port;
68 u16 dst_port;
69 u32 proto;
70 u64 unused;
71 };
72 u64 as_u64[6];
73 };
74}) v6_connection_key_t;
75/* *INDENT-ON* */
76
77typedef clib_bihash_kv_16_8_t session_kv4_t;
78typedef clib_bihash_kv_48_8_t session_kv6_t;
79
80always_inline void
81make_v4_ss_kv (session_kv4_t * kv, ip4_address_t * lcl, ip4_address_t * rmt,
82 u16 lcl_port, u16 rmt_port, u8 proto)
83{
Florin Coras9679c812018-06-21 08:14:34 -070084 kv->key[0] = (u64) rmt->as_u32 << 32 | (u64) lcl->as_u32;
85 kv->key[1] = (u64) proto << 32 | (u64) rmt_port << 16 | (u64) lcl_port;
Florin Coras04e53442017-07-16 17:12:15 -070086 kv->value = ~0ULL;
87}
88
89always_inline void
90make_v4_listener_kv (session_kv4_t * kv, ip4_address_t * lcl, u16 lcl_port,
91 u8 proto)
92{
Florin Coras9679c812018-06-21 08:14:34 -070093 kv->key[0] = (u64) lcl->as_u32;
94 kv->key[1] = (u64) proto << 32 | (u64) lcl_port;
Florin Coras04e53442017-07-16 17:12:15 -070095 kv->value = ~0ULL;
96}
97
98always_inline void
Florin Corasdbd44562017-11-09 19:30:17 -080099make_v4_proxy_kv (session_kv4_t * kv, ip4_address_t * lcl, u8 proto)
100{
Florin Coras9679c812018-06-21 08:14:34 -0700101 kv->key[0] = (u64) lcl->as_u32;
102 kv->key[1] = (u64) proto << 32;
Florin Corasdbd44562017-11-09 19:30:17 -0800103 kv->value = ~0ULL;
104}
105
106always_inline void
Florin Coras561af9b2017-12-09 10:19:43 -0800107make_v4_ss_kv_from_tc (session_kv4_t * kv, transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700108{
Florin Coras561af9b2017-12-09 10:19:43 -0800109 make_v4_ss_kv (kv, &tc->lcl_ip.ip4, &tc->rmt_ip.ip4, tc->lcl_port,
110 tc->rmt_port, tc->proto);
Florin Coras04e53442017-07-16 17:12:15 -0700111}
112
113always_inline void
114make_v6_ss_kv (session_kv6_t * kv, ip6_address_t * lcl, ip6_address_t * rmt,
115 u16 lcl_port, u16 rmt_port, u8 proto)
116{
Florin Coras9679c812018-06-21 08:14:34 -0700117 kv->key[0] = lcl->as_u64[0];
118 kv->key[1] = lcl->as_u64[1];
119 kv->key[2] = rmt->as_u64[0];
120 kv->key[3] = rmt->as_u64[1];
121 kv->key[4] = (u64) proto << 32 | (u64) rmt_port << 16 | (u64) lcl_port;
122 kv->key[5] = 0;
Florin Coras04e53442017-07-16 17:12:15 -0700123 kv->value = ~0ULL;
124}
125
126always_inline void
127make_v6_listener_kv (session_kv6_t * kv, ip6_address_t * lcl, u16 lcl_port,
128 u8 proto)
129{
Florin Coras9679c812018-06-21 08:14:34 -0700130 kv->key[0] = lcl->as_u64[0];
131 kv->key[1] = lcl->as_u64[1];
132 kv->key[2] = 0;
133 kv->key[3] = 0;
134 kv->key[4] = (u64) proto << 32 | (u64) lcl_port;
135 kv->key[5] = 0;
Florin Coras04e53442017-07-16 17:12:15 -0700136 kv->value = ~0ULL;
137}
138
139always_inline void
Florin Corasdbd44562017-11-09 19:30:17 -0800140make_v6_proxy_kv (session_kv6_t * kv, ip6_address_t * lcl, u8 proto)
141{
Florin Coras9679c812018-06-21 08:14:34 -0700142 kv->key[0] = lcl->as_u64[0];
143 kv->key[1] = lcl->as_u64[1];
144 kv->key[2] = 0;
145 kv->key[3] = 0;
146 kv->key[4] = (u64) proto << 32;
147 kv->key[5] = 0;
Florin Corasdbd44562017-11-09 19:30:17 -0800148 kv->value = ~0ULL;
149}
150
151always_inline void
Florin Coras561af9b2017-12-09 10:19:43 -0800152make_v6_ss_kv_from_tc (session_kv6_t * kv, transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700153{
Florin Coras561af9b2017-12-09 10:19:43 -0800154 make_v6_ss_kv (kv, &tc->lcl_ip.ip6, &tc->rmt_ip.ip6, tc->lcl_port,
155 tc->rmt_port, tc->proto);
Florin Coras04e53442017-07-16 17:12:15 -0700156}
157
Florin Corascea194d2017-10-02 00:18:51 -0700158static session_table_t *
Andreas Schultz30a28c12020-04-23 10:41:50 +0200159session_table_get_or_alloc (u8 fib_proto, u32 fib_index)
Florin Coras04e53442017-07-16 17:12:15 -0700160{
Florin Corascea194d2017-10-02 00:18:51 -0700161 session_table_t *st;
Florin Coras6c36f532017-11-03 18:32:34 -0700162 u32 table_index;
Andreas Schultz30a28c12020-04-23 10:41:50 +0200163 ASSERT (fib_index != ~0);
164 if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index &&
165 fib_index_to_table_index[fib_proto][fib_index] != ~0)
166 {
167 table_index = fib_index_to_table_index[fib_proto][fib_index];
168 return session_table_get (table_index);
169 }
170 else
Florin Corascea194d2017-10-02 00:18:51 -0700171 {
172 st = session_table_alloc ();
173 table_index = session_table_index (st);
Andreas Schultz30a28c12020-04-23 10:41:50 +0200174 vec_validate_init_empty (fib_index_to_table_index[fib_proto], fib_index,
175 ~0);
Florin Coras6c36f532017-11-03 18:32:34 -0700176 fib_index_to_table_index[fib_proto][fib_index] = table_index;
177 st->active_fib_proto = fib_proto;
Florin Corasb795bd02017-12-14 11:30:48 -0800178 session_table_init (st, fib_proto);
Florin Corascea194d2017-10-02 00:18:51 -0700179 return st;
180 }
Florin Corascea194d2017-10-02 00:18:51 -0700181}
182
183static session_table_t *
Florin Coras6c36f532017-11-03 18:32:34 -0700184session_table_get_or_alloc_for_connection (transport_connection_t * tc)
185{
186 u32 fib_proto;
187 fib_proto = transport_connection_fib_proto (tc);
188 return session_table_get_or_alloc (fib_proto, tc->fib_index);
189}
190
191static session_table_t *
Florin Corascea194d2017-10-02 00:18:51 -0700192session_table_get_for_connection (transport_connection_t * tc)
193{
194 u32 fib_proto = transport_connection_fib_proto (tc);
195 if (vec_len (fib_index_to_table_index[fib_proto]) <= tc->fib_index)
196 return 0;
197 return
198 session_table_get (fib_index_to_table_index[fib_proto][tc->fib_index]);
199}
200
201static session_table_t *
202session_table_get_for_fib_index (u32 fib_proto, u32 fib_index)
203{
204 if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
205 return 0;
206 return session_table_get (fib_index_to_table_index[fib_proto][fib_index]);
207}
208
209u32
210session_lookup_get_index_for_fib (u32 fib_proto, u32 fib_index)
211{
212 if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
213 return SESSION_TABLE_INVALID_INDEX;
214 return fib_index_to_table_index[fib_proto][fib_index];
215}
216
Florin Corasa4d09562021-07-08 08:25:09 -0700217u32
218session_lookup_get_or_alloc_index_for_fib (u32 fib_proto, u32 fib_index)
219{
220 session_table_t *st;
221 st = session_table_get_or_alloc (fib_proto, fib_index);
222 return session_table_index (st);
223}
224
Florin Corascea194d2017-10-02 00:18:51 -0700225/**
226 * Add transport connection to a session table
227 *
228 * Session lookup 5-tuple (src-ip, dst-ip, src-port, dst-port, session-type)
229 * is added to requested session table.
230 *
231 * @param tc transport connection to be added
232 * @param value value to be stored
233 *
234 * @return non-zero if failure
235 */
236int
237session_lookup_add_connection (transport_connection_t * tc, u64 value)
238{
239 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700240 session_kv4_t kv4;
241 session_kv6_t kv6;
242
Florin Corascea194d2017-10-02 00:18:51 -0700243 st = session_table_get_or_alloc_for_connection (tc);
244 if (!st)
245 return -1;
Florin Coras68810622017-07-24 17:40:28 -0700246 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700247 {
Florin Coras04e53442017-07-16 17:12:15 -0700248 make_v4_ss_kv_from_tc (&kv4, tc);
249 kv4.value = value;
Florin Corascea194d2017-10-02 00:18:51 -0700250 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4,
251 1 /* is_add */ );
Florin Coras68810622017-07-24 17:40:28 -0700252 }
253 else
254 {
Florin Coras04e53442017-07-16 17:12:15 -0700255 make_v6_ss_kv_from_tc (&kv6, tc);
256 kv6.value = value;
Florin Corascea194d2017-10-02 00:18:51 -0700257 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6,
258 1 /* is_add */ );
Florin Coras04e53442017-07-16 17:12:15 -0700259 }
260}
261
Florin Coras04e53442017-07-16 17:12:15 -0700262int
Florin Corascea194d2017-10-02 00:18:51 -0700263session_lookup_add_session_endpoint (u32 table_index,
264 session_endpoint_t * sep, u64 value)
Florin Coras04e53442017-07-16 17:12:15 -0700265{
Florin Corascea194d2017-10-02 00:18:51 -0700266 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700267 session_kv4_t kv4;
268 session_kv6_t kv6;
Florin Coras68810622017-07-24 17:40:28 -0700269
Florin Corascea194d2017-10-02 00:18:51 -0700270 st = session_table_get (table_index);
271 if (!st)
272 return -1;
273 if (sep->is_ip4)
274 {
275 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
276 sep->transport_proto);
277 kv4.value = value;
278 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 1);
279 }
280 else
281 {
282 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
283 sep->transport_proto);
284 kv6.value = value;
285 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 1);
286 }
287}
288
289int
290session_lookup_del_session_endpoint (u32 table_index,
291 session_endpoint_t * sep)
292{
293 session_table_t *st;
294 session_kv4_t kv4;
295 session_kv6_t kv6;
296
297 st = session_table_get (table_index);
298 if (!st)
299 return -1;
300 if (sep->is_ip4)
301 {
302 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
303 sep->transport_proto);
304 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0);
305 }
306 else
307 {
308 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
309 sep->transport_proto);
310 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0);
311 }
312}
313
Florin Corasaab06042020-02-26 02:56:14 +0000314int
315session_lookup_del_session_endpoint2 (session_endpoint_t * sep)
316{
317 fib_protocol_t fib_proto;
318 session_table_t *st;
319 session_kv4_t kv4;
320 session_kv6_t kv6;
321
322 fib_proto = sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
323 st = session_table_get_for_fib_index (fib_proto, sep->fib_index);
324 if (!st)
325 return -1;
326 if (sep->is_ip4)
327 {
328 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
329 sep->transport_proto);
330 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0);
331 }
332 else
333 {
334 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
335 sep->transport_proto);
336 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0);
337 }
338}
339
Florin Corascea194d2017-10-02 00:18:51 -0700340/**
341 * Delete transport connection from session table
342 *
343 * @param table_index session table index
344 * @param tc transport connection to be removed
345 *
346 * @return non-zero if failure
347 */
348int
349session_lookup_del_connection (transport_connection_t * tc)
350{
351 session_table_t *st;
352 session_kv4_t kv4;
353 session_kv6_t kv6;
354
355 st = session_table_get_for_connection (tc);
356 if (!st)
357 return -1;
Florin Coras68810622017-07-24 17:40:28 -0700358 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700359 {
Florin Coras04e53442017-07-16 17:12:15 -0700360 make_v4_ss_kv_from_tc (&kv4, tc);
Florin Corascea194d2017-10-02 00:18:51 -0700361 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4,
Florin Coras04e53442017-07-16 17:12:15 -0700362 0 /* is_add */ );
Florin Coras68810622017-07-24 17:40:28 -0700363 }
364 else
365 {
Florin Coras04e53442017-07-16 17:12:15 -0700366 make_v6_ss_kv_from_tc (&kv6, tc);
Florin Corascea194d2017-10-02 00:18:51 -0700367 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6,
Florin Coras04e53442017-07-16 17:12:15 -0700368 0 /* is_add */ );
Florin Coras04e53442017-07-16 17:12:15 -0700369 }
Florin Coras04e53442017-07-16 17:12:15 -0700370}
371
372int
Florin Coras288eaab2019-02-03 15:26:14 -0800373session_lookup_del_session (session_t * s)
Florin Coras04e53442017-07-16 17:12:15 -0700374{
375 transport_connection_t *ts;
Florin Coras1ee78302019-02-05 15:51:15 -0800376 ts = transport_get_connection (session_get_transport_proto (s),
377 s->connection_index, s->thread_index);
Florin Corase1e7fb82019-09-25 07:28:34 -0700378 if (!ts || (ts->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
Nathan Skrzypczak2eed1a12019-07-04 14:26:21 +0200379 return 0;
Florin Corascea194d2017-10-02 00:18:51 -0700380 return session_lookup_del_connection (ts);
Florin Coras04e53442017-07-16 17:12:15 -0700381}
382
Florin Corasdff48db2017-11-19 18:06:58 -0800383static u8
384session_lookup_action_index_is_valid (u32 action_index)
Florin Corasf0c1c962017-11-02 21:31:46 -0700385{
Florin Corasdff48db2017-11-19 18:06:58 -0800386 if (action_index == SESSION_RULES_TABLE_ACTION_ALLOW
387 || action_index == SESSION_RULES_TABLE_INVALID_INDEX)
388 return 0;
389 return 1;
390}
391
Florin Corasf8f516a2018-02-08 15:10:09 -0800392static u64
393session_lookup_action_to_handle (u32 action_index)
Florin Corasdff48db2017-11-19 18:06:58 -0800394{
395 switch (action_index)
396 {
397 case SESSION_RULES_TABLE_ACTION_DROP:
Florin Corasf8f516a2018-02-08 15:10:09 -0800398 return SESSION_DROP_HANDLE;
Florin Corasdff48db2017-11-19 18:06:58 -0800399 case SESSION_RULES_TABLE_ACTION_ALLOW:
400 case SESSION_RULES_TABLE_INVALID_INDEX:
Florin Corasf8f516a2018-02-08 15:10:09 -0800401 return SESSION_INVALID_HANDLE;
Florin Corasdff48db2017-11-19 18:06:58 -0800402 default:
Florin Corasf8f516a2018-02-08 15:10:09 -0800403 /* application index */
Florin Corasdff48db2017-11-19 18:06:58 -0800404 return action_index;
405 }
Florin Corasf0c1c962017-11-02 21:31:46 -0700406}
407
Florin Coras288eaab2019-02-03 15:26:14 -0800408static session_t *
Florin Coras7999e832017-10-31 01:51:04 -0700409session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
410 u8 transport_proto)
Florin Coras1c710452017-10-17 00:03:13 -0700411{
412 application_t *app;
Florin Corasdff48db2017-11-19 18:06:58 -0800413 app = application_get_if_valid (app_index);
Florin Coras1c710452017-10-17 00:03:13 -0700414 if (!app)
415 return 0;
416
Florin Coras15531972018-08-12 23:50:53 -0700417 return app_worker_first_listener (application_get_default_worker (app),
418 fib_proto, transport_proto);
Florin Coras1c710452017-10-17 00:03:13 -0700419}
420
Florin Coras288eaab2019-02-03 15:26:14 -0800421static session_t *
Florin Corasa2ff7b82017-11-08 17:55:03 -0800422session_lookup_action_to_session (u32 action_index, u8 fib_proto,
423 u8 transport_proto)
424{
Florin Corasdff48db2017-11-19 18:06:58 -0800425 u32 app_index;
Florin Corasf8f516a2018-02-08 15:10:09 -0800426 app_index = session_lookup_action_to_handle (action_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800427 /* Nothing sophisticated for now, action index is app index */
Florin Corasdff48db2017-11-19 18:06:58 -0800428 return session_lookup_app_listen_session (app_index, fib_proto,
Florin Corasa2ff7b82017-11-08 17:55:03 -0800429 transport_proto);
430}
431
Florin Corasf8f516a2018-02-08 15:10:09 -0800432/** UNUSED */
Florin Coras288eaab2019-02-03 15:26:14 -0800433session_t *
Florin Corasa2ff7b82017-11-08 17:55:03 -0800434session_lookup_rules_table_session4 (session_table_t * st, u8 proto,
435 ip4_address_t * lcl, u16 lcl_port,
436 ip4_address_t * rmt, u16 rmt_port)
Florin Coras1c710452017-10-17 00:03:13 -0700437{
Florin Corasc97a7392017-11-05 23:07:07 -0800438 session_rules_table_t *srt = &st->session_rules[proto];
Florin Corasdff48db2017-11-19 18:06:58 -0800439 u32 action_index, app_index;
Florin Corasc97a7392017-11-05 23:07:07 -0800440 action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
Florin Coras1c710452017-10-17 00:03:13 -0700441 rmt_port);
Florin Corasf8f516a2018-02-08 15:10:09 -0800442 app_index = session_lookup_action_to_handle (action_index);
Florin Coras1c710452017-10-17 00:03:13 -0700443 /* Nothing sophisticated for now, action index is app index */
Florin Corasdff48db2017-11-19 18:06:58 -0800444 return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4,
Florin Coras7999e832017-10-31 01:51:04 -0700445 proto);
Florin Coras1c710452017-10-17 00:03:13 -0700446}
447
Florin Corasf8f516a2018-02-08 15:10:09 -0800448/** UNUSED */
Florin Coras288eaab2019-02-03 15:26:14 -0800449session_t *
Florin Corasdff48db2017-11-19 18:06:58 -0800450session_lookup_rules_table_session6 (session_table_t * st, u8 proto,
451 ip6_address_t * lcl, u16 lcl_port,
452 ip6_address_t * rmt, u16 rmt_port)
Florin Coras1c710452017-10-17 00:03:13 -0700453{
Florin Corasc97a7392017-11-05 23:07:07 -0800454 session_rules_table_t *srt = &st->session_rules[proto];
Florin Corasdff48db2017-11-19 18:06:58 -0800455 u32 action_index, app_index;
Florin Corasc97a7392017-11-05 23:07:07 -0800456 action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
Florin Coras1c710452017-10-17 00:03:13 -0700457 rmt_port);
Florin Corasf8f516a2018-02-08 15:10:09 -0800458 app_index = session_lookup_action_to_handle (action_index);
Florin Corasdff48db2017-11-19 18:06:58 -0800459 return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6,
Florin Coras7999e832017-10-31 01:51:04 -0700460 proto);
Florin Coras1c710452017-10-17 00:03:13 -0700461}
462
Florin Corasa2ff7b82017-11-08 17:55:03 -0800463/**
464 * Lookup listener for session endpoint in table
465 *
466 * @param table_index table where the endpoint should be looked up
467 * @param sep session endpoint to be looked up
468 * @param use_rules flag that indicates if the session rules of the table
469 * should be used
470 * @return invalid handle if nothing is found, the handle of a valid listener
Florin Corasf8f516a2018-02-08 15:10:09 -0800471 * or an action derived handle if a rule is hit
Florin Corasa2ff7b82017-11-08 17:55:03 -0800472 */
Florin Coras3cbc04b2017-10-02 00:18:51 -0700473u64
Florin Corasa2ff7b82017-11-08 17:55:03 -0800474session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
475 u8 use_rules)
Florin Coras04e53442017-07-16 17:12:15 -0700476{
Florin Corasc97a7392017-11-05 23:07:07 -0800477 session_rules_table_t *srt;
Florin Corascea194d2017-10-02 00:18:51 -0700478 session_table_t *st;
Florin Corasf0c1c962017-11-02 21:31:46 -0700479 u32 ai;
Florin Corascea194d2017-10-02 00:18:51 -0700480 int rv;
Florin Coras04e53442017-07-16 17:12:15 -0700481
Florin Corascea194d2017-10-02 00:18:51 -0700482 st = session_table_get (table_index);
483 if (!st)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700484 return SESSION_INVALID_HANDLE;
Florin Corascea194d2017-10-02 00:18:51 -0700485 if (sep->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700486 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800487 session_kv4_t kv4;
488 ip4_address_t lcl4;
489
Florin Coras561af9b2017-12-09 10:19:43 -0800490 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
491 sep->transport_proto);
Florin Corascea194d2017-10-02 00:18:51 -0700492 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
493 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700494 return kv4.value;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800495 if (use_rules)
496 {
Dave Barachb7b92992018-10-17 10:38:51 -0400497 clib_memset (&lcl4, 0, sizeof (lcl4));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800498 srt = &st->session_rules[sep->transport_proto];
499 ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
500 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800501 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800502 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800503 }
Florin Coras68810622017-07-24 17:40:28 -0700504 }
505 else
506 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800507 session_kv6_t kv6;
508 ip6_address_t lcl6;
509
Florin Coras561af9b2017-12-09 10:19:43 -0800510 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
511 sep->transport_proto);
Florin Corascea194d2017-10-02 00:18:51 -0700512 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
513 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700514 return kv6.value;
Florin Coras1c710452017-10-17 00:03:13 -0700515
Florin Corasa2ff7b82017-11-08 17:55:03 -0800516 if (use_rules)
517 {
Dave Barachb7b92992018-10-17 10:38:51 -0400518 clib_memset (&lcl6, 0, sizeof (lcl6));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800519 srt = &st->session_rules[sep->transport_proto];
520 ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
521 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800522 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800523 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800524 }
Florin Coras68810622017-07-24 17:40:28 -0700525 }
Florin Coras3cbc04b2017-10-02 00:18:51 -0700526 return SESSION_INVALID_HANDLE;
527}
528
Florin Corasa2ff7b82017-11-08 17:55:03 -0800529/**
530 * Look up endpoint in local session table
531 *
532 * The result, for now, is an application index and it may in the future
533 * be extended to a more complicated "action object". The only action we
534 * emulate now is "drop" and for that we return a special app index.
535 *
536 * Lookup logic is to check in order:
537 * - the rules in the table (connect acls)
538 * - session sub-table for a listener
539 * - session sub-table for a local listener (zeroed addr)
540 *
541 * @param table_index table where the lookup should be done
542 * @param sep session endpoint to be looked up
Florin Corasf8f516a2018-02-08 15:10:09 -0800543 * @return session handle that can be interpreted as an adjacency
Florin Corasa2ff7b82017-11-08 17:55:03 -0800544 */
Florin Corasf8f516a2018-02-08 15:10:09 -0800545u64
Florin Corasa2ff7b82017-11-08 17:55:03 -0800546session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
Florin Coras68810622017-07-24 17:40:28 -0700547{
Florin Corasc97a7392017-11-05 23:07:07 -0800548 session_rules_table_t *srt;
Florin Corascea194d2017-10-02 00:18:51 -0700549 session_table_t *st;
Florin Corasf0c1c962017-11-02 21:31:46 -0700550 u32 ai;
Florin Corascea194d2017-10-02 00:18:51 -0700551 int rv;
Florin Coras68810622017-07-24 17:40:28 -0700552
Florin Corascea194d2017-10-02 00:18:51 -0700553 st = session_table_get (table_index);
554 if (!st)
555 return SESSION_INVALID_INDEX;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800556 ASSERT (st->is_local);
557
Florin Corascea194d2017-10-02 00:18:51 -0700558 if (sep->is_ip4)
Florin Coras68810622017-07-24 17:40:28 -0700559 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800560 session_kv4_t kv4;
561 ip4_address_t lcl4;
562
563 /*
564 * Check if endpoint has special rules associated
565 */
Dave Barachb7b92992018-10-17 10:38:51 -0400566 clib_memset (&lcl4, 0, sizeof (lcl4));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800567 srt = &st->session_rules[sep->transport_proto];
568 ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
569 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800570 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800571 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800572
573 /*
574 * Check if session endpoint is a listener
575 */
Florin Corascea194d2017-10-02 00:18:51 -0700576 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
577 sep->transport_proto);
578 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
579 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800580 return kv4.value;
Florin Corascea194d2017-10-02 00:18:51 -0700581
582 /*
583 * Zero out the ip. Logic is that connect to local ips, say
584 * 127.0.0.1:port, can match 0.0.0.0:port
585 */
Florin Coras477e91a2018-02-27 10:05:57 -0800586 if (ip4_is_local_host (&sep->ip.ip4))
587 {
588 kv4.key[0] = 0;
589 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
590 if (rv == 0)
591 return kv4.value;
592 }
593 else
594 {
595 kv4.key[0] = 0;
596 }
Florin Corasdbd44562017-11-09 19:30:17 -0800597
598 /*
599 * Zero out the port and check if we have proxy
600 */
601 kv4.key[1] = 0;
602 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
603 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800604 return kv4.value;
Florin Coras68810622017-07-24 17:40:28 -0700605 }
606 else
607 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800608 session_kv6_t kv6;
609 ip6_address_t lcl6;
610
Dave Barachb7b92992018-10-17 10:38:51 -0400611 clib_memset (&lcl6, 0, sizeof (lcl6));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800612 srt = &st->session_rules[sep->transport_proto];
613 ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
614 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800615 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800616 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800617
Florin Corascea194d2017-10-02 00:18:51 -0700618 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
619 sep->transport_proto);
620 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
621 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800622 return kv6.value;
Florin Corascea194d2017-10-02 00:18:51 -0700623
624 /*
625 * Zero out the ip. Same logic as above.
626 */
Florin Coras477e91a2018-02-27 10:05:57 -0800627
628 if (ip6_is_local_host (&sep->ip.ip6))
629 {
630 kv6.key[0] = kv6.key[1] = 0;
631 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
632 if (rv == 0)
633 return kv6.value;
634 }
635 else
636 {
637 kv6.key[0] = kv6.key[1] = 0;
638 }
Florin Corasdbd44562017-11-09 19:30:17 -0800639
640 /*
641 * Zero out the port. Same logic as above.
642 */
643 kv6.key[4] = kv6.key[5] = 0;
644 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
645 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800646 return kv6.value;
Florin Coras04e53442017-07-16 17:12:15 -0700647 }
Florin Corasf8f516a2018-02-08 15:10:09 -0800648 return SESSION_INVALID_HANDLE;
Florin Coras04e53442017-07-16 17:12:15 -0700649}
650
Florin Coras288eaab2019-02-03 15:26:14 -0800651static inline session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700652session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl,
Florin Coras477e91a2018-02-27 10:05:57 -0800653 u16 lcl_port, u8 proto, u8 use_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700654{
Florin Coras04e53442017-07-16 17:12:15 -0700655 session_kv4_t kv4;
656 int rv;
657
Florin Corasdbd44562017-11-09 19:30:17 -0800658 /*
659 * First, try a fully formed listener
660 */
Florin Coras04e53442017-07-16 17:12:15 -0700661 make_v4_listener_kv (&kv4, lcl, lcl_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700662 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700663 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700664 return listen_session_get ((u32) kv4.value);
Florin Coras04e53442017-07-16 17:12:15 -0700665
Florin Corasdbd44562017-11-09 19:30:17 -0800666 /*
667 * Zero out the lcl ip and check if any 0/0 port binds have been done
668 */
Florin Coras477e91a2018-02-27 10:05:57 -0800669 if (use_wildcard)
670 {
671 kv4.key[0] = 0;
672 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
673 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700674 return listen_session_get ((u32) kv4.value);
Florin Coras477e91a2018-02-27 10:05:57 -0800675 }
676 else
677 {
678 kv4.key[0] = 0;
679 }
Florin Coras04e53442017-07-16 17:12:15 -0700680
Florin Corasdbd44562017-11-09 19:30:17 -0800681 /*
682 * Zero out port and check if we have a proxy set up for our ip
683 */
684 make_v4_proxy_kv (&kv4, lcl, proto);
685 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
686 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700687 return listen_session_get ((u32) kv4.value);
Florin Corasdbd44562017-11-09 19:30:17 -0800688
Florin Coras04e53442017-07-16 17:12:15 -0700689 return 0;
690}
691
Florin Coras288eaab2019-02-03 15:26:14 -0800692session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700693session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port,
Yu Pingb092b772019-12-27 04:04:33 +0800694 u8 proto, u8 use_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700695{
Florin Corascea194d2017-10-02 00:18:51 -0700696 session_table_t *st;
697 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
698 if (!st)
699 return 0;
Yu Pingb092b772019-12-27 04:04:33 +0800700 return session_lookup_listener4_i (st, lcl, lcl_port, proto, use_wildcard);
Florin Coras04e53442017-07-16 17:12:15 -0700701}
702
Florin Coras288eaab2019-02-03 15:26:14 -0800703static session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700704session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl,
Florin Coras477e91a2018-02-27 10:05:57 -0800705 u16 lcl_port, u8 proto, u8 ip_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700706{
Florin Coras04e53442017-07-16 17:12:15 -0700707 session_kv6_t kv6;
708 int rv;
709
710 make_v6_listener_kv (&kv6, lcl, lcl_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700711 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -0700712 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700713 return listen_session_get ((u32) kv6.value);
Florin Coras04e53442017-07-16 17:12:15 -0700714
715 /* Zero out the lcl ip */
Florin Coras477e91a2018-02-27 10:05:57 -0800716 if (ip_wildcard)
717 {
718 kv6.key[0] = kv6.key[1] = 0;
719 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
720 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700721 return listen_session_get ((u32) kv6.value);
Florin Coras477e91a2018-02-27 10:05:57 -0800722 }
723 else
724 {
725 kv6.key[0] = kv6.key[1] = 0;
726 }
Florin Coras04e53442017-07-16 17:12:15 -0700727
Florin Corasdbd44562017-11-09 19:30:17 -0800728 make_v6_proxy_kv (&kv6, lcl, proto);
729 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
730 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700731 return listen_session_get ((u32) kv6.value);
Florin Coras04e53442017-07-16 17:12:15 -0700732 return 0;
733}
734
Florin Coras288eaab2019-02-03 15:26:14 -0800735session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700736session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port,
Yu Pingb092b772019-12-27 04:04:33 +0800737 u8 proto, u8 use_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700738{
Florin Corascea194d2017-10-02 00:18:51 -0700739 session_table_t *st;
740 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
741 if (!st)
742 return 0;
Yu Pingb092b772019-12-27 04:04:33 +0800743 return session_lookup_listener6_i (st, lcl, lcl_port, proto, use_wildcard);
Florin Coras04e53442017-07-16 17:12:15 -0700744}
745
Florin Coras477e91a2018-02-27 10:05:57 -0800746/**
747 * Lookup listener, exact or proxy (inaddr_any:0) match
748 */
Florin Coras288eaab2019-02-03 15:26:14 -0800749session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700750session_lookup_listener (u32 table_index, session_endpoint_t * sep)
Florin Coras04e53442017-07-16 17:12:15 -0700751{
Florin Corascea194d2017-10-02 00:18:51 -0700752 session_table_t *st;
753 st = session_table_get (table_index);
754 if (!st)
755 return 0;
756 if (sep->is_ip4)
757 return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port,
Florin Coras477e91a2018-02-27 10:05:57 -0800758 sep->transport_proto, 0);
Florin Corascea194d2017-10-02 00:18:51 -0700759 else
760 return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port,
Florin Coras477e91a2018-02-27 10:05:57 -0800761 sep->transport_proto, 0);
Florin Coras04e53442017-07-16 17:12:15 -0700762 return 0;
763}
764
Florin Coras9f1a5432019-03-10 21:03:20 -0700765/**
766 * Lookup listener wildcard match
767 */
768session_t *
769session_lookup_listener_wildcard (u32 table_index, session_endpoint_t * sep)
770{
771 session_table_t *st;
772 st = session_table_get (table_index);
773 if (!st)
774 return 0;
775 if (sep->is_ip4)
776 return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port,
777 sep->transport_proto,
778 1 /* use_wildcard */ );
779 else
780 return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port,
781 sep->transport_proto,
782 1 /* use_wildcard */ );
783 return 0;
784}
785
Florin Corascea194d2017-10-02 00:18:51 -0700786int
787session_lookup_add_half_open (transport_connection_t * tc, u64 value)
788{
789 session_table_t *st;
790 session_kv4_t kv4;
791 session_kv6_t kv6;
792
793 st = session_table_get_or_alloc_for_connection (tc);
794 if (!st)
795 return 0;
796 if (tc->is_ip4)
797 {
798 make_v4_ss_kv_from_tc (&kv4, tc);
799 kv4.value = value;
800 return clib_bihash_add_del_16_8 (&st->v4_half_open_hash, &kv4,
801 1 /* is_add */ );
802 }
803 else
804 {
805 make_v6_ss_kv_from_tc (&kv6, tc);
806 kv6.value = value;
807 return clib_bihash_add_del_48_8 (&st->v6_half_open_hash, &kv6,
808 1 /* is_add */ );
809 }
810}
811
812int
813session_lookup_del_half_open (transport_connection_t * tc)
814{
815 session_table_t *st;
816 session_kv4_t kv4;
817 session_kv6_t kv6;
818
819 st = session_table_get_for_connection (tc);
820 if (!st)
821 return -1;
822 if (tc->is_ip4)
823 {
824 make_v4_ss_kv_from_tc (&kv4, tc);
825 return clib_bihash_add_del_16_8 (&st->v4_half_open_hash, &kv4,
826 0 /* is_add */ );
827 }
828 else
829 {
830 make_v6_ss_kv_from_tc (&kv6, tc);
831 return clib_bihash_add_del_48_8 (&st->v6_half_open_hash, &kv6,
832 0 /* is_add */ );
833 }
834}
835
Florin Coras04e53442017-07-16 17:12:15 -0700836u64
Florin Corascea194d2017-10-02 00:18:51 -0700837session_lookup_half_open_handle (transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700838{
Florin Corascea194d2017-10-02 00:18:51 -0700839 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700840 session_kv4_t kv4;
841 session_kv6_t kv6;
842 int rv;
843
Florin Corascea194d2017-10-02 00:18:51 -0700844 st = session_table_get_for_fib_index (transport_connection_fib_proto (tc),
845 tc->fib_index);
846 if (!st)
847 return HALF_OPEN_LOOKUP_INVALID_VALUE;
848 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700849 {
Florin Corascea194d2017-10-02 00:18:51 -0700850 make_v4_ss_kv (&kv4, &tc->lcl_ip.ip4, &tc->rmt_ip.ip4, tc->lcl_port,
Florin Coras3cbc04b2017-10-02 00:18:51 -0700851 tc->rmt_port, tc->proto);
Florin Corascea194d2017-10-02 00:18:51 -0700852 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700853 if (rv == 0)
854 return kv4.value;
Florin Corascea194d2017-10-02 00:18:51 -0700855 }
856 else
857 {
858 make_v6_ss_kv (&kv6, &tc->lcl_ip.ip6, &tc->rmt_ip.ip6, tc->lcl_port,
Florin Coras3cbc04b2017-10-02 00:18:51 -0700859 tc->rmt_port, tc->proto);
Florin Corascea194d2017-10-02 00:18:51 -0700860 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -0700861 if (rv == 0)
862 return kv6.value;
Florin Coras04e53442017-07-16 17:12:15 -0700863 }
864 return HALF_OPEN_LOOKUP_INVALID_VALUE;
865}
866
867transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -0700868session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700869{
Florin Coras04e53442017-07-16 17:12:15 -0700870 if (handle != HALF_OPEN_LOOKUP_INVALID_VALUE)
Florin Corascea194d2017-10-02 00:18:51 -0700871 {
Florin Coras1ee78302019-02-05 15:51:15 -0800872 u32 sst = session_type_from_proto_and_ip (proto, is_ip4);
873 return transport_get_half_open (sst, handle & 0xFFFFFFFF);
Florin Corascea194d2017-10-02 00:18:51 -0700874 }
Florin Coras04e53442017-07-16 17:12:15 -0700875 return 0;
876}
877
Florin Corascea194d2017-10-02 00:18:51 -0700878/**
879 * Lookup connection with ip4 and transport layer information
880 *
881 * This is used on the fast path so it needs to be fast. Thereby,
882 * duplication of code and 'hacks' allowed.
883 *
884 * The lookup is incremental and returns whenever something is matched. The
885 * steps are:
886 * - Try to find an established session
Florin Corascea194d2017-10-02 00:18:51 -0700887 * - Try to find a half-open connection
Florin Coras1c710452017-10-17 00:03:13 -0700888 * - Try session rules table
Florin Corasa2ff7b82017-11-08 17:55:03 -0800889 * - Try to find a fully-formed or local source wildcarded (listener bound to
890 * all interfaces) listener session
Florin Corascea194d2017-10-02 00:18:51 -0700891 * - return 0
892 *
893 * @param fib_index index of fib wherein the connection was received
894 * @param lcl local ip4 address
895 * @param rmt remote ip4 address
896 * @param lcl_port local port
897 * @param rmt_port remote port
898 * @param proto transport protocol (e.g., tcp, udp)
899 * @param thread_index thread index for request
Florin Corasdff48db2017-11-19 18:06:58 -0800900 * @param is_filtered return flag that indicates if connection was filtered.
Florin Corascea194d2017-10-02 00:18:51 -0700901 *
902 * @return pointer to transport connection, if one is found, 0 otherwise
903 */
Florin Coras04e53442017-07-16 17:12:15 -0700904transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -0700905session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
906 ip4_address_t * rmt, u16 lcl_port,
Florin Corasdff48db2017-11-19 18:06:58 -0800907 u16 rmt_port, u8 proto, u32 thread_index,
Florin Corasb5e55a22019-01-10 12:42:47 -0800908 u8 * result)
Florin Coras04e53442017-07-16 17:12:15 -0700909{
Florin Corascea194d2017-10-02 00:18:51 -0700910 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700911 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -0800912 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800913 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -0700914 int rv;
915
Florin Corascea194d2017-10-02 00:18:51 -0700916 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
917 if (PREDICT_FALSE (!st))
918 return 0;
919
Florin Corasa2ff7b82017-11-08 17:55:03 -0800920 /*
921 * Lookup session amongst established ones
922 */
Florin Coras04e53442017-07-16 17:12:15 -0700923 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700924 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700925 if (rv == 0)
926 {
Florin Corasb5e55a22019-01-10 12:42:47 -0800927 if (PREDICT_FALSE ((u32) (kv4.value >> 32) != thread_index))
928 {
929 *result = SESSION_LOOKUP_RESULT_WRONG_THREAD;
930 return 0;
931 }
Florin Corascea194d2017-10-02 00:18:51 -0700932 s = session_get (kv4.value & 0xFFFFFFFFULL, thread_index);
Florin Coras1ee78302019-02-05 15:51:15 -0800933 return transport_get_connection (proto, s->connection_index,
934 thread_index);
Florin Coras04e53442017-07-16 17:12:15 -0700935 }
936
Florin Corasa2ff7b82017-11-08 17:55:03 -0800937 /*
938 * Try half-open connections
939 */
Florin Corascea194d2017-10-02 00:18:51 -0700940 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700941 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -0800942 return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
Florin Coras1c710452017-10-17 00:03:13 -0700943
Florin Corasa2ff7b82017-11-08 17:55:03 -0800944 /*
945 * Check the session rules table
946 */
947 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
948 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -0800949 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -0800950 {
Florin Corasb5e55a22019-01-10 12:42:47 -0800951 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
952 {
953 *result = SESSION_LOOKUP_RESULT_FILTERED;
954 return 0;
955 }
Florin Corasdff48db2017-11-19 18:06:58 -0800956 if ((s = session_lookup_action_to_session (action_index,
957 FIB_PROTOCOL_IP4, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -0800958 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -0800959 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800960 }
961
962 /*
963 * If nothing is found, check if any listener is available
964 */
Florin Coras477e91a2018-02-27 10:05:57 -0800965 s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800966 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -0800967 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800968
969 return 0;
Florin Coras04e53442017-07-16 17:12:15 -0700970}
971
Florin Corascea194d2017-10-02 00:18:51 -0700972/**
973 * Lookup connection with ip4 and transport layer information
974 *
Florin Corasb5e55a22019-01-10 12:42:47 -0800975 * Not optimized. Lookup logic is identical to that of
976 * @ref session_lookup_connection_wt4
Florin Corascea194d2017-10-02 00:18:51 -0700977 *
978 * @param fib_index index of the fib wherein the connection was received
979 * @param lcl local ip4 address
980 * @param rmt remote ip4 address
981 * @param lcl_port local port
982 * @param rmt_port remote port
983 * @param proto transport protocol (e.g., tcp, udp)
984 *
985 * @return pointer to transport connection, if one is found, 0 otherwise
986 */
Florin Coras04e53442017-07-16 17:12:15 -0700987transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -0700988session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
989 ip4_address_t * rmt, u16 lcl_port, u16 rmt_port,
990 u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -0700991{
Florin Corascea194d2017-10-02 00:18:51 -0700992 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700993 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -0800994 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800995 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -0700996 int rv;
997
Florin Corascea194d2017-10-02 00:18:51 -0700998 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
999 if (PREDICT_FALSE (!st))
1000 return 0;
1001
Florin Corasa2ff7b82017-11-08 17:55:03 -08001002 /*
1003 * Lookup session amongst established ones
1004 */
Florin Coras04e53442017-07-16 17:12:15 -07001005 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001006 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -07001007 if (rv == 0)
1008 {
Florin Corascea194d2017-10-02 00:18:51 -07001009 s = session_get_from_handle (kv4.value);
Florin Coras1ee78302019-02-05 15:51:15 -08001010 return transport_get_connection (proto, s->connection_index,
1011 s->thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001012 }
1013
Florin Corasa2ff7b82017-11-08 17:55:03 -08001014 /*
1015 * Try half-open connections
1016 */
Florin Corascea194d2017-10-02 00:18:51 -07001017 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -07001018 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001019 return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001020
1021 /*
1022 * Check the session rules table
1023 */
1024 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
1025 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001026 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001027 {
Florin Corasdff48db2017-11-19 18:06:58 -08001028 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1029 return 0;
1030 if ((s = session_lookup_action_to_session (action_index,
1031 FIB_PROTOCOL_IP4, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001032 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001033 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001034 }
1035
1036 /*
1037 * If nothing is found, check if any listener is available
1038 */
Florin Coras477e91a2018-02-27 10:05:57 -08001039 s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001040 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001041 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001042
1043 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001044}
1045
Florin Corascea194d2017-10-02 00:18:51 -07001046/**
1047 * Lookup session with ip4 and transport layer information
1048 *
Florin Coras6bd8d3f2022-03-14 21:17:25 -07001049 * Important note: this may look into another thread's pool table
Florin Coras3cbc04b2017-10-02 00:18:51 -07001050 *
1051 * Lookup logic is similar to that of @ref session_lookup_connection_wt4 but
1052 * this returns a session as opposed to a transport connection and it does not
1053 * try to lookup half-open sessions.
1054 *
1055 * Typically used by dgram connections
Florin Corascea194d2017-10-02 00:18:51 -07001056 */
Florin Coras288eaab2019-02-03 15:26:14 -08001057session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001058session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt,
1059 u16 lcl_port, u16 rmt_port, u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -07001060{
Florin Corascea194d2017-10-02 00:18:51 -07001061 session_table_t *st;
1062 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -08001063 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001064 u32 action_index;
Florin Corascea194d2017-10-02 00:18:51 -07001065 int rv;
1066
1067 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
1068 if (PREDICT_FALSE (!st))
1069 return 0;
1070
Florin Corasa2ff7b82017-11-08 17:55:03 -08001071 /*
1072 * Lookup session amongst established ones
1073 */
Florin Corascea194d2017-10-02 00:18:51 -07001074 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
1075 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
1076 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -07001077 return session_get_from_handle_safe (kv4.value);
Florin Corascea194d2017-10-02 00:18:51 -07001078
Florin Corasa2ff7b82017-11-08 17:55:03 -08001079 /*
1080 * Check the session rules table
1081 */
1082 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
1083 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001084 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001085 {
Florin Corasdff48db2017-11-19 18:06:58 -08001086 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1087 return 0;
1088 return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
1089 proto);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001090 }
1091
1092 /*
1093 * If nothing is found, check if any listener is available
1094 */
Florin Coras477e91a2018-02-27 10:05:57 -08001095 if ((s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1)))
Florin Corascea194d2017-10-02 00:18:51 -07001096 return s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001097
1098 return 0;
Florin Corascea194d2017-10-02 00:18:51 -07001099}
1100
1101/**
1102 * Lookup connection with ip6 and transport layer information
1103 *
1104 * This is used on the fast path so it needs to be fast. Thereby,
1105 * duplication of code and 'hacks' allowed.
1106 *
1107 * The lookup is incremental and returns whenever something is matched. The
1108 * steps are:
1109 * - Try to find an established session
Florin Corascea194d2017-10-02 00:18:51 -07001110 * - Try to find a half-open connection
Florin Coras1c710452017-10-17 00:03:13 -07001111 * - Try session rules table
Florin Corasa2ff7b82017-11-08 17:55:03 -08001112 * - Try to find a fully-formed or local source wildcarded (listener bound to
1113 * all interfaces) listener session
Florin Corascea194d2017-10-02 00:18:51 -07001114 * - return 0
1115 *
1116 * @param fib_index index of the fib wherein the connection was received
1117 * @param lcl local ip6 address
1118 * @param rmt remote ip6 address
1119 * @param lcl_port local port
1120 * @param rmt_port remote port
1121 * @param proto transport protocol (e.g., tcp, udp)
1122 * @param thread_index thread index for request
1123 *
1124 * @return pointer to transport connection, if one is found, 0 otherwise
1125 */
1126transport_connection_t *
1127session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
1128 ip6_address_t * rmt, u16 lcl_port,
Florin Corasdff48db2017-11-19 18:06:58 -08001129 u16 rmt_port, u8 proto, u32 thread_index,
Florin Corasb5e55a22019-01-10 12:42:47 -08001130 u8 * result)
Florin Corascea194d2017-10-02 00:18:51 -07001131{
1132 session_table_t *st;
Florin Coras288eaab2019-02-03 15:26:14 -08001133 session_t *s;
Florin Coras04e53442017-07-16 17:12:15 -07001134 session_kv6_t kv6;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001135 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -07001136 int rv;
1137
Florin Corascea194d2017-10-02 00:18:51 -07001138 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1139 if (PREDICT_FALSE (!st))
1140 return 0;
1141
Florin Coras04e53442017-07-16 17:12:15 -07001142 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001143 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001144 if (rv == 0)
1145 {
Florin Corascea194d2017-10-02 00:18:51 -07001146 ASSERT ((u32) (kv6.value >> 32) == thread_index);
Florin Corasb5e55a22019-01-10 12:42:47 -08001147 if (PREDICT_FALSE ((u32) (kv6.value >> 32) != thread_index))
1148 {
1149 *result = SESSION_LOOKUP_RESULT_WRONG_THREAD;
1150 return 0;
1151 }
Florin Corascea194d2017-10-02 00:18:51 -07001152 s = session_get (kv6.value & 0xFFFFFFFFULL, thread_index);
Florin Coras1ee78302019-02-05 15:51:15 -08001153 return transport_get_connection (proto, s->connection_index,
1154 thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001155 }
1156
Florin Corasa2ff7b82017-11-08 17:55:03 -08001157 /* Try half-open connections */
Florin Corascea194d2017-10-02 00:18:51 -07001158 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001159 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001160 return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
Florin Coras04e53442017-07-16 17:12:15 -07001161
Florin Corasa2ff7b82017-11-08 17:55:03 -08001162 /* Check the session rules table */
1163 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1164 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001165 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001166 {
Florin Corasb5e55a22019-01-10 12:42:47 -08001167 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1168 {
1169 *result = SESSION_LOOKUP_RESULT_FILTERED;
1170 return 0;
1171 }
Florin Corasdff48db2017-11-19 18:06:58 -08001172 if ((s = session_lookup_action_to_session (action_index,
1173 FIB_PROTOCOL_IP6, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001174 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001175 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001176 }
1177
1178 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001179 s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001180 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001181 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001182
1183 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001184}
1185
Florin Corascea194d2017-10-02 00:18:51 -07001186/**
1187 * Lookup connection with ip6 and transport layer information
1188 *
1189 * Not optimized. This is used on the fast path so it needs to be fast.
1190 * Thereby, duplication of code and 'hacks' allowed. Lookup logic is identical
1191 * to that of @ref session_lookup_connection_wt4
1192 *
1193 * @param fib_index index of the fib wherein the connection was received
1194 * @param lcl local ip6 address
1195 * @param rmt remote ip6 address
1196 * @param lcl_port local port
1197 * @param rmt_port remote port
1198 * @param proto transport protocol (e.g., tcp, udp)
1199 *
1200 * @return pointer to transport connection, if one is found, 0 otherwise
1201 */
Florin Coras04e53442017-07-16 17:12:15 -07001202transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -07001203session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
1204 ip6_address_t * rmt, u16 lcl_port, u16 rmt_port,
1205 u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -07001206{
Florin Corascea194d2017-10-02 00:18:51 -07001207 session_table_t *st;
Florin Coras288eaab2019-02-03 15:26:14 -08001208 session_t *s;
Florin Coras04e53442017-07-16 17:12:15 -07001209 session_kv6_t kv6;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001210 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -07001211 int rv;
1212
Florin Corascea194d2017-10-02 00:18:51 -07001213 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1214 if (PREDICT_FALSE (!st))
1215 return 0;
1216
Florin Coras04e53442017-07-16 17:12:15 -07001217 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001218 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001219 if (rv == 0)
1220 {
Florin Corascea194d2017-10-02 00:18:51 -07001221 s = session_get_from_handle (kv6.value);
Florin Coras1ee78302019-02-05 15:51:15 -08001222 return transport_get_connection (proto, s->connection_index,
1223 s->thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001224 }
1225
Florin Corasa2ff7b82017-11-08 17:55:03 -08001226 /* Try half-open connections */
Florin Corascea194d2017-10-02 00:18:51 -07001227 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001228 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001229 return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
Florin Coras04e53442017-07-16 17:12:15 -07001230
Florin Corasa2ff7b82017-11-08 17:55:03 -08001231 /* Check the session rules table */
1232 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1233 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001234 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001235 {
Florin Corasdff48db2017-11-19 18:06:58 -08001236 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1237 return 0;
1238 if ((s = session_lookup_action_to_session (action_index,
1239 FIB_PROTOCOL_IP6, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001240 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001241 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001242 }
1243
1244 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001245 s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001246 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001247 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001248
1249 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001250}
1251
Florin Corascea194d2017-10-02 00:18:51 -07001252/**
1253 * Lookup session with ip6 and transport layer information
1254 *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001255 * Important note: this may look into another thread's pool table and
1256 * register as 'peeker'. Caller should call @ref session_pool_remove_peeker as
1257 * if needed as soon as possible.
1258 *
1259 * Lookup logic is similar to that of @ref session_lookup_connection_wt6 but
1260 * this returns a session as opposed to a transport connection and it does not
1261 * try to lookup half-open sessions.
1262 *
1263 * Typically used by dgram connections
Florin Corascea194d2017-10-02 00:18:51 -07001264 */
Florin Coras288eaab2019-02-03 15:26:14 -08001265session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001266session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt,
1267 u16 lcl_port, u16 rmt_port, u8 proto)
Florin Corascea194d2017-10-02 00:18:51 -07001268{
1269 session_table_t *st;
1270 session_kv6_t kv6;
Florin Coras288eaab2019-02-03 15:26:14 -08001271 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001272 u32 action_index;
Florin Corascea194d2017-10-02 00:18:51 -07001273 int rv;
1274
1275 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1276 if (PREDICT_FALSE (!st))
1277 return 0;
1278
1279 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
1280 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
1281 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -07001282 return session_get_from_handle_safe (kv6.value);
Florin Corascea194d2017-10-02 00:18:51 -07001283
Florin Corasa2ff7b82017-11-08 17:55:03 -08001284 /* Check the session rules table */
1285 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1286 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001287 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001288 {
Florin Corasdff48db2017-11-19 18:06:58 -08001289 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1290 return 0;
1291 return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6,
1292 proto);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001293 }
1294
Florin Corascea194d2017-10-02 00:18:51 -07001295 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001296 if ((s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1)))
Florin Corascea194d2017-10-02 00:18:51 -07001297 return s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001298 return 0;
Florin Corascea194d2017-10-02 00:18:51 -07001299}
1300
Florin Coras57660d92020-04-04 22:45:34 +00001301transport_connection_t *
1302session_lookup_connection (u32 fib_index, ip46_address_t * lcl,
1303 ip46_address_t * rmt, u16 lcl_port, u16 rmt_port,
1304 u8 proto, u8 is_ip4)
1305{
1306 if (is_ip4)
1307 return session_lookup_connection4 (fib_index, &lcl->ip4, &rmt->ip4,
1308 lcl_port, rmt_port, proto);
1309 else
1310 return session_lookup_connection6 (fib_index, &lcl->ip6, &rmt->ip6,
1311 lcl_port, rmt_port, proto);
1312}
1313
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001314session_error_t
1315vnet_session_rule_add_del (session_rule_add_del_args_t *args)
Florin Coras1c710452017-10-17 00:03:13 -07001316{
1317 app_namespace_t *app_ns = app_namespace_get (args->appns_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001318 session_rules_table_t *srt;
Florin Coras1c710452017-10-17 00:03:13 -07001319 session_table_t *st;
1320 u32 fib_index;
1321 u8 fib_proto;
Florin Corasc1a42652019-02-08 18:27:29 -08001322 int rv = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001323
1324 if (!app_ns)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001325 return SESSION_E_INVALID_NS;
Florin Corasc1a42652019-02-08 18:27:29 -08001326
Florin Coras1c710452017-10-17 00:03:13 -07001327 if (args->scope > 3)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001328 return SESSION_E_INVALID;
Florin Corasc1a42652019-02-08 18:27:29 -08001329
Florin Corasc97a7392017-11-05 23:07:07 -08001330 if (args->transport_proto != TRANSPORT_PROTO_TCP
1331 && args->transport_proto != TRANSPORT_PROTO_UDP)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001332 return SESSION_E_INVALID;
Florin Corasc1a42652019-02-08 18:27:29 -08001333
Florin Coras1c710452017-10-17 00:03:13 -07001334 if ((args->scope & SESSION_RULE_SCOPE_GLOBAL) || args->scope == 0)
1335 {
1336 fib_proto = args->table_args.rmt.fp_proto;
1337 fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
1338 st = session_table_get_for_fib_index (fib_proto, fib_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001339 srt = &st->session_rules[args->transport_proto];
Florin Corasc1a42652019-02-08 18:27:29 -08001340 if ((rv = session_rules_table_add_del (srt, &args->table_args)))
1341 return rv;
Florin Coras1c710452017-10-17 00:03:13 -07001342 }
1343 if (args->scope & SESSION_RULE_SCOPE_LOCAL)
1344 {
Dave Barachb7b92992018-10-17 10:38:51 -04001345 clib_memset (&args->table_args.lcl, 0, sizeof (args->table_args.lcl));
Florin Corasa2ff7b82017-11-08 17:55:03 -08001346 args->table_args.lcl.fp_proto = args->table_args.rmt.fp_proto;
1347 args->table_args.lcl_port = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001348 st = app_namespace_get_local_table (app_ns);
Florin Corasc97a7392017-11-05 23:07:07 -08001349 srt = &st->session_rules[args->transport_proto];
Florin Corasc1a42652019-02-08 18:27:29 -08001350 rv = session_rules_table_add_del (srt, &args->table_args);
Florin Coras1c710452017-10-17 00:03:13 -07001351 }
Florin Corasc1a42652019-02-08 18:27:29 -08001352 return rv;
Florin Coras1c710452017-10-17 00:03:13 -07001353}
1354
Florin Coras6c36f532017-11-03 18:32:34 -07001355/**
1356 * Mark (global) tables as pertaining to app ns
1357 */
1358void
1359session_lookup_set_tables_appns (app_namespace_t * app_ns)
1360{
1361 session_table_t *st;
1362 u32 fib_index;
1363 u8 fp;
1364
1365 for (fp = 0; fp < ARRAY_LEN (fib_index_to_table_index); fp++)
1366 {
1367 fib_index = app_namespace_get_fib_index (app_ns, fp);
Florin Coras95cd8642019-12-30 21:53:19 -08001368 st = session_table_get_or_alloc (fp, fib_index);
Florin Coras6c36f532017-11-03 18:32:34 -07001369 if (st)
1370 st->appns_index = app_namespace_index (app_ns);
1371 }
1372}
1373
Florin Corascea194d2017-10-02 00:18:51 -07001374u8 *
1375format_ip4_session_lookup_kvp (u8 * s, va_list * args)
1376{
1377 clib_bihash_kv_16_8_t *kvp = va_arg (*args, clib_bihash_kv_16_8_t *);
Florin Coras2b81e3c2019-02-27 07:55:46 -08001378 u32 is_local = va_arg (*args, u32);
Florin Coras15531972018-08-12 23:50:53 -07001379 v4_connection_key_t *key = (v4_connection_key_t *) kvp->key;
Florin Coras288eaab2019-02-03 15:26:14 -08001380 session_t *session;
Florin Coras15531972018-08-12 23:50:53 -07001381 app_worker_t *app_wrk;
Florin Coras053a0e42018-11-13 15:52:38 -08001382 const u8 *app_name;
1383 u8 *str = 0;
Florin Corascea194d2017-10-02 00:18:51 -07001384
Florin Corascea194d2017-10-02 00:18:51 -07001385 if (!is_local)
1386 {
1387 session = session_get_from_handle (kvp->value);
Florin Coras15531972018-08-12 23:50:53 -07001388 app_wrk = app_worker_get (session->app_wrk_index);
1389 app_name = application_name_from_index (app_wrk->app_index);
Florin Coras561af9b2017-12-09 10:19:43 -08001390 str = format (0, "[%U] %U:%d->%U:%d", format_transport_proto_short,
1391 key->proto, format_ip4_address, &key->src,
1392 clib_net_to_host_u16 (key->src_port), format_ip4_address,
1393 &key->dst, clib_net_to_host_u16 (key->dst_port));
Florin Corascea194d2017-10-02 00:18:51 -07001394 s = format (s, "%-40v%-30v", str, app_name);
1395 }
1396 else
1397 {
Florin Coras2b81e3c2019-02-27 07:55:46 -08001398 session = session_get_from_handle (kvp->value);
1399 app_wrk = app_worker_get (session->app_wrk_index);
Florin Coras15531972018-08-12 23:50:53 -07001400 app_name = application_name_from_index (app_wrk->app_index);
Florin Coras561af9b2017-12-09 10:19:43 -08001401 str = format (0, "[%U] %U:%d", format_transport_proto_short, key->proto,
1402 format_ip4_address, &key->src,
1403 clib_net_to_host_u16 (key->src_port));
Florin Corascea194d2017-10-02 00:18:51 -07001404 s = format (s, "%-30v%-30v", str, app_name);
1405 }
Florin Corascea194d2017-10-02 00:18:51 -07001406 return s;
1407}
1408
1409typedef struct _ip4_session_table_show_ctx_t
1410{
1411 vlib_main_t *vm;
1412 u8 is_local;
1413} ip4_session_table_show_ctx_t;
1414
1415static int
1416ip4_session_table_show (clib_bihash_kv_16_8_t * kvp, void *arg)
1417{
1418 ip4_session_table_show_ctx_t *ctx = arg;
1419 vlib_cli_output (ctx->vm, "%U", format_ip4_session_lookup_kvp, kvp,
1420 ctx->is_local);
1421 return 1;
1422}
1423
1424void
1425session_lookup_show_table_entries (vlib_main_t * vm, session_table_t * table,
1426 u8 type, u8 is_local)
1427{
1428 ip4_session_table_show_ctx_t ctx = {
1429 .vm = vm,
1430 .is_local = is_local,
1431 };
1432 if (!is_local)
1433 vlib_cli_output (vm, "%-40s%-30s", "Session", "Application");
1434 else
1435 vlib_cli_output (vm, "%-30s%-30s", "Listener", "Application");
1436 switch (type)
1437 {
1438 /* main table v4 */
1439 case 0:
1440 ip4_session_table_walk (&table->v4_session_hash, ip4_session_table_show,
1441 &ctx);
1442 break;
1443 default:
1444 clib_warning ("not supported");
1445 }
1446}
Florin Coras66b11312017-07-31 17:18:03 -07001447
Florin Coras1c710452017-10-17 00:03:13 -07001448static clib_error_t *
1449session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
1450 vlib_cli_command_t * cmd)
1451{
Florin Corasc97a7392017-11-05 23:07:07 -08001452 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen = 0, rmt_plen = 0;
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001453 clib_error_t *error = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001454 u32 appns_index, scope = 0;
1455 ip46_address_t lcl_ip, rmt_ip;
1456 u8 is_ip4 = 1, conn_set = 0;
1457 u8 fib_proto, is_add = 1, *ns_id = 0;
Florin Corasc97a7392017-11-05 23:07:07 -08001458 u8 *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001459 app_namespace_t *app_ns;
Florin Corasc1a42652019-02-08 18:27:29 -08001460 int rv;
Florin Coras1c710452017-10-17 00:03:13 -07001461
Guanghua Zhangfcd5e122019-08-24 10:52:19 +08001462 session_cli_return_if_not_enabled ();
1463
Dave Barachb7b92992018-10-17 10:38:51 -04001464 clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
1465 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Florin Coras1c710452017-10-17 00:03:13 -07001466 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1467 {
1468 if (unformat (input, "del"))
1469 is_add = 0;
1470 else if (unformat (input, "add"))
1471 ;
1472 else if (unformat (input, "appns %_%v%_", &ns_id))
1473 ;
1474 else if (unformat (input, "scope global"))
1475 scope = SESSION_RULE_SCOPE_GLOBAL;
1476 else if (unformat (input, "scope local"))
1477 scope = SESSION_RULE_SCOPE_LOCAL;
1478 else if (unformat (input, "scope all"))
1479 scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
1480 else if (unformat (input, "proto %U", unformat_transport_proto, &proto))
1481 ;
1482 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip4_address,
1483 &lcl_ip.ip4, &lcl_plen, &lcl_port,
1484 unformat_ip4_address, &rmt_ip.ip4, &rmt_plen,
1485 &rmt_port))
1486 {
1487 is_ip4 = 1;
1488 conn_set = 1;
1489 }
1490 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip6_address,
1491 &lcl_ip.ip6, &lcl_plen, &lcl_port,
1492 unformat_ip6_address, &rmt_ip.ip6, &rmt_plen,
1493 &rmt_port))
1494 {
1495 is_ip4 = 0;
1496 conn_set = 1;
1497 }
1498 else if (unformat (input, "action %d", &action))
1499 ;
Florin Corasc97a7392017-11-05 23:07:07 -08001500 else if (unformat (input, "tag %_%v%_", &tag))
1501 ;
Florin Coras1c710452017-10-17 00:03:13 -07001502 else
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001503 {
1504 error = clib_error_return (0, "unknown input `%U'",
1505 format_unformat_error, input);
1506 goto done;
1507 }
Florin Coras1c710452017-10-17 00:03:13 -07001508 }
1509
Florin Corasc97a7392017-11-05 23:07:07 -08001510 if (proto == ~0)
1511 {
1512 vlib_cli_output (vm, "proto must be set");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001513 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001514 }
1515 if (is_add && !conn_set && action == ~0)
1516 {
1517 vlib_cli_output (vm, "connection and action must be set for add");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001518 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001519 }
1520 if (!is_add && !tag && !conn_set)
1521 {
1522 vlib_cli_output (vm, "connection or tag must be set for delete");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001523 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001524 }
1525 if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
1526 {
1527 vlib_cli_output (vm, "tag too long (max u64)");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001528 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001529 }
Florin Coras1c710452017-10-17 00:03:13 -07001530
1531 if (ns_id)
1532 {
1533 app_ns = app_namespace_get_from_id (ns_id);
1534 if (!app_ns)
Florin Corasc97a7392017-11-05 23:07:07 -08001535 {
1536 vlib_cli_output (vm, "namespace %v does not exist", ns_id);
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001537 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001538 }
Florin Coras1c710452017-10-17 00:03:13 -07001539 }
1540 else
1541 {
1542 app_ns = app_namespace_get_default ();
1543 }
1544 appns_index = app_namespace_index (app_ns);
1545
1546 fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
1547 session_rule_add_del_args_t args = {
zhanglimaoa04ebb82019-03-13 10:36:54 +08001548 .transport_proto = proto,
Florin Coras1c710452017-10-17 00:03:13 -07001549 .table_args.lcl.fp_addr = lcl_ip,
1550 .table_args.lcl.fp_len = lcl_plen,
1551 .table_args.lcl.fp_proto = fib_proto,
1552 .table_args.rmt.fp_addr = rmt_ip,
1553 .table_args.rmt.fp_len = rmt_plen,
1554 .table_args.rmt.fp_proto = fib_proto,
1555 .table_args.lcl_port = lcl_port,
1556 .table_args.rmt_port = rmt_port,
1557 .table_args.action_index = action,
1558 .table_args.is_add = is_add,
Florin Corasc97a7392017-11-05 23:07:07 -08001559 .table_args.tag = tag,
Florin Coras1c710452017-10-17 00:03:13 -07001560 .appns_index = appns_index,
1561 .scope = scope,
1562 };
Florin Corasc1a42652019-02-08 18:27:29 -08001563 if ((rv = vnet_session_rule_add_del (&args)))
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001564 error = clib_error_return (0, "rule add del returned %u", rv);
Florin Corasc1a42652019-02-08 18:27:29 -08001565
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001566done:
1567 vec_free (ns_id);
Florin Corasc97a7392017-11-05 23:07:07 -08001568 vec_free (tag);
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001569 return error;
Florin Coras1c710452017-10-17 00:03:13 -07001570}
1571
1572/* *INDENT-OFF* */
1573VLIB_CLI_COMMAND (session_rule_command, static) =
1574{
1575 .path = "session rule",
1576 .short_help = "session rule [add|del] appns <ns_id> proto <proto> "
1577 "<lcl-ip/plen> <lcl-port> <rmt-ip/plen> <rmt-port> action <action>",
1578 .function = session_rule_command_fn,
1579};
1580/* *INDENT-ON* */
1581
Florin Coras7999e832017-10-31 01:51:04 -07001582void
1583session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
1584 u8 transport_proto)
1585{
1586 vlib_main_t *vm = vlib_get_main ();
Florin Corasc97a7392017-11-05 23:07:07 -08001587 session_rules_table_t *srt;
Florin Coras7999e832017-10-31 01:51:04 -07001588 session_table_t *st;
1589 st = session_table_get_for_fib_index (fib_index, fib_proto);
Florin Corasc97a7392017-11-05 23:07:07 -08001590 srt = &st->session_rules[transport_proto];
1591 session_rules_table_cli_dump (vm, srt, fib_proto);
Florin Coras7999e832017-10-31 01:51:04 -07001592}
1593
1594void
1595session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto,
1596 u8 transport_proto)
1597{
1598 vlib_main_t *vm = vlib_get_main ();
Florin Corasc97a7392017-11-05 23:07:07 -08001599 session_rules_table_t *srt;
Florin Coras7999e832017-10-31 01:51:04 -07001600 session_table_t *st;
1601 st = session_table_get (table_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001602 srt = &st->session_rules[transport_proto];
1603 session_rules_table_cli_dump (vm, srt, fib_proto);
Florin Coras7999e832017-10-31 01:51:04 -07001604}
1605
Florin Coras1c710452017-10-17 00:03:13 -07001606static clib_error_t *
1607show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
1608 vlib_cli_command_t * cmd)
1609{
1610 u32 transport_proto = ~0, lcl_port, rmt_port, lcl_plen, rmt_plen;
1611 u32 fib_index, scope = 0;
1612 ip46_address_t lcl_ip, rmt_ip;
1613 u8 is_ip4 = 1, show_one = 0;
1614 app_namespace_t *app_ns;
Florin Corasc97a7392017-11-05 23:07:07 -08001615 session_rules_table_t *srt;
Florin Coras1c710452017-10-17 00:03:13 -07001616 session_table_t *st;
1617 u8 *ns_id = 0, fib_proto;
1618
Guanghua Zhangfcd5e122019-08-24 10:52:19 +08001619 session_cli_return_if_not_enabled ();
1620
Dave Barachb7b92992018-10-17 10:38:51 -04001621 clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
1622 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Florin Coras1c710452017-10-17 00:03:13 -07001623 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1624 {
1625 if (unformat (input, "%U", unformat_transport_proto, &transport_proto))
1626 ;
1627 else if (unformat (input, "appns %_%v%_", &ns_id))
1628 ;
1629 else if (unformat (input, "scope global"))
1630 scope = 1;
1631 else if (unformat (input, "scope local"))
1632 scope = 2;
1633 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip4_address,
1634 &lcl_ip.ip4, &lcl_plen, &lcl_port,
1635 unformat_ip4_address, &rmt_ip.ip4, &rmt_plen,
1636 &rmt_port))
1637 {
1638 is_ip4 = 1;
1639 show_one = 1;
1640 }
1641 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip6_address,
1642 &lcl_ip.ip6, &lcl_plen, &lcl_port,
1643 unformat_ip6_address, &rmt_ip.ip6, &rmt_plen,
1644 &rmt_port))
1645 {
1646 is_ip4 = 0;
1647 show_one = 1;
1648 }
1649 else
1650 return clib_error_return (0, "unknown input `%U'",
1651 format_unformat_error, input);
1652 }
1653
1654 if (transport_proto == ~0)
1655 {
1656 vlib_cli_output (vm, "transport proto must be set");
1657 return 0;
1658 }
1659
1660 if (ns_id)
1661 {
1662 app_ns = app_namespace_get_from_id (ns_id);
1663 if (!app_ns)
1664 {
1665 vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
1666 return 0;
1667 }
1668 }
1669 else
1670 {
1671 app_ns = app_namespace_get_default ();
1672 }
1673
1674 if (scope == 1 || scope == 0)
1675 {
1676 fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
1677 fib_index = is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
1678 st = session_table_get_for_fib_index (fib_proto, fib_index);
1679 }
1680 else
1681 {
1682 st = app_namespace_get_local_table (app_ns);
1683 }
1684
1685 if (show_one)
1686 {
Florin Corasc97a7392017-11-05 23:07:07 -08001687 srt = &st->session_rules[transport_proto];
1688 session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip,
1689 rmt_port, is_ip4);
Florin Coras1c710452017-10-17 00:03:13 -07001690 return 0;
1691 }
1692
Florin Corasc97a7392017-11-05 23:07:07 -08001693 vlib_cli_output (vm, "%U rules table", format_transport_proto,
1694 transport_proto);
1695 srt = &st->session_rules[transport_proto];
1696 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
1697 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
Florin Coras1c710452017-10-17 00:03:13 -07001698
1699 vec_free (ns_id);
1700 return 0;
1701}
1702
1703/* *INDENT-OFF* */
1704VLIB_CLI_COMMAND (show_session_rules_command, static) =
1705{
1706 .path = "show session rules",
Florin Corasdff48db2017-11-19 18:06:58 -08001707 .short_help = "show session rules [<proto> appns <id> <lcl-ip/plen> "
1708 "<lcl-port> <rmt-ip/plen> <rmt-port> scope <scope>]",
Florin Coras1c710452017-10-17 00:03:13 -07001709 .function = show_session_rules_command_fn,
1710};
1711/* *INDENT-ON* */
1712
Florin Coras894d0a62023-11-17 16:35:04 -08001713u8 *
1714format_session_lookup_tables (u8 *s, va_list *args)
1715{
1716 u32 fib_proto = va_arg (*args, u32);
1717 u32 *fibs, num_fibs = 0, fib_index, indent;
1718 session_table_t *st;
1719 u64 total_mem = 0;
1720
1721 fibs = fib_index_to_table_index[fib_proto];
1722
1723 for (fib_index = 0; fib_index < vec_len (fibs); fib_index++)
1724 {
1725 if (fibs[fib_index] == ~0)
1726 continue;
1727
1728 num_fibs += 1;
1729 st = session_table_get (fibs[fib_index]);
1730 total_mem += session_table_memory_size (st);
1731 }
1732
1733 indent = format_get_indent (s);
1734 s = format (s, "active fibs:\t%u\n", num_fibs);
1735 s = format (s, "%Umax fib-index:\t%u\n", format_white_space, indent,
1736 vec_len (fibs) - 1);
1737 s = format (s, "%Utable memory:\t%U\n", format_white_space, indent,
1738 format_memory_size, total_mem);
1739 s = format (s, "%Uvec memory:\t%U\n", format_white_space, indent,
1740 format_memory_size, vec_mem_size (fibs));
1741
1742 return s;
1743}
1744
1745static clib_error_t *
1746show_session_lookup_command_fn (vlib_main_t *vm, unformat_input_t *input,
1747 vlib_cli_command_t *cmd)
1748{
1749 session_table_t *st;
1750 u32 fib_index = ~0;
1751
1752 session_cli_return_if_not_enabled ();
1753 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1754 {
1755 if (unformat (input, "table %u", &fib_index))
1756 ;
1757 else
1758 return clib_error_return (0, "unknown input `%U'",
1759 format_unformat_error, input);
1760 }
1761
1762 if (fib_index != ~0)
1763 {
1764 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
1765 if (st)
1766 vlib_cli_output (vm, "%U", format_session_table, st);
1767 else
1768 vlib_cli_output (vm, "no ip4 table for fib-index %u", fib_index);
1769 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1770 if (st)
1771 vlib_cli_output (vm, "%U", format_session_table, st);
1772 else
1773 vlib_cli_output (vm, "no ip6 table for fib-index %u", fib_index);
1774 goto done;
1775 }
1776
1777 vlib_cli_output (vm, "ip4 fib lookup tables:\n %U",
1778 format_session_lookup_tables, FIB_PROTOCOL_IP4);
1779 vlib_cli_output (vm, "ip6 fib lookup tables:\n %U",
1780 format_session_lookup_tables, FIB_PROTOCOL_IP6);
1781
1782done:
1783 return 0;
1784}
1785
1786VLIB_CLI_COMMAND (show_session_lookup_command, static) = {
1787 .path = "show session lookup",
1788 .short_help = "show session lookup [table <fib-index>]",
1789 .function = show_session_lookup_command_fn,
1790};
1791
Florin Coras04e53442017-07-16 17:12:15 -07001792void
1793session_lookup_init (void)
1794{
Florin Corascea194d2017-10-02 00:18:51 -07001795 /*
1796 * Allocate default table and map it to fib_index 0
1797 */
1798 session_table_t *st = session_table_alloc ();
1799 vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP4], 0);
1800 fib_index_to_table_index[FIB_PROTOCOL_IP4][0] = session_table_index (st);
Florin Coras6c36f532017-11-03 18:32:34 -07001801 st->active_fib_proto = FIB_PROTOCOL_IP4;
1802 session_table_init (st, FIB_PROTOCOL_IP4);
Florin Corascea194d2017-10-02 00:18:51 -07001803 st = session_table_alloc ();
1804 vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP6], 0);
1805 fib_index_to_table_index[FIB_PROTOCOL_IP6][0] = session_table_index (st);
Florin Coras6c36f532017-11-03 18:32:34 -07001806 st->active_fib_proto = FIB_PROTOCOL_IP6;
1807 session_table_init (st, FIB_PROTOCOL_IP6);
Florin Coras04e53442017-07-16 17:12:15 -07001808}
1809
1810/*
1811 * fd.io coding-style-patch-verification: ON
1812 *
1813 * Local Variables:
1814 * eval: (c-set-style "gnu")
1815 * End:
1816 */