blob: 1e58e5e78063bbdfcd6a54b9a8d4cb500a9427a4 [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 Corasf9bdc032024-02-02 13:01:07 -080032static session_lookup_main_t sl_main;
33
Florin Corascea194d2017-10-02 00:18:51 -070034/**
Florin Corascea194d2017-10-02 00:18:51 -070035 * Network namespace index (i.e., fib index) to session lookup table. We
36 * should have one per network protocol type but for now we only support IP4/6
37 */
38static u32 *fib_index_to_table_index[2];
39
Steven Luong5682ca82024-07-17 16:16:05 -070040static u32 *fib_index_to_lock_count[2];
41
Florin Coras04e53442017-07-16 17:12:15 -070042/* 16 octets */
43typedef CLIB_PACKED (struct {
44 union
45 {
46 struct
47 {
48 ip4_address_t src;
49 ip4_address_t dst;
50 u16 src_port;
51 u16 dst_port;
52 /* align by making this 4 octets even though its a 1-bit field
53 * NOTE: avoid key overlap with other transports that use 5 tuples for
54 * session identification.
55 */
56 u32 proto;
57 };
58 u64 as_u64[2];
59 };
60}) v4_connection_key_t;
61
62typedef CLIB_PACKED (struct {
63 union
64 {
65 struct
66 {
67 /* 48 octets */
68 ip6_address_t src;
69 ip6_address_t dst;
70 u16 src_port;
71 u16 dst_port;
72 u32 proto;
73 u64 unused;
74 };
75 u64 as_u64[6];
76 };
77}) v6_connection_key_t;
Florin Coras04e53442017-07-16 17:12:15 -070078
79typedef clib_bihash_kv_16_8_t session_kv4_t;
80typedef clib_bihash_kv_48_8_t session_kv6_t;
81
82always_inline void
83make_v4_ss_kv (session_kv4_t * kv, ip4_address_t * lcl, ip4_address_t * rmt,
84 u16 lcl_port, u16 rmt_port, u8 proto)
85{
Florin Coras9679c812018-06-21 08:14:34 -070086 kv->key[0] = (u64) rmt->as_u32 << 32 | (u64) lcl->as_u32;
87 kv->key[1] = (u64) proto << 32 | (u64) rmt_port << 16 | (u64) lcl_port;
Florin Coras04e53442017-07-16 17:12:15 -070088 kv->value = ~0ULL;
89}
90
91always_inline void
92make_v4_listener_kv (session_kv4_t * kv, ip4_address_t * lcl, u16 lcl_port,
93 u8 proto)
94{
Florin Coras9679c812018-06-21 08:14:34 -070095 kv->key[0] = (u64) lcl->as_u32;
96 kv->key[1] = (u64) proto << 32 | (u64) lcl_port;
Florin Coras04e53442017-07-16 17:12:15 -070097 kv->value = ~0ULL;
98}
99
100always_inline void
Florin Corasdbd44562017-11-09 19:30:17 -0800101make_v4_proxy_kv (session_kv4_t * kv, ip4_address_t * lcl, u8 proto)
102{
Florin Coras9679c812018-06-21 08:14:34 -0700103 kv->key[0] = (u64) lcl->as_u32;
104 kv->key[1] = (u64) proto << 32;
Florin Corasdbd44562017-11-09 19:30:17 -0800105 kv->value = ~0ULL;
106}
107
108always_inline void
Florin Coras561af9b2017-12-09 10:19:43 -0800109make_v4_ss_kv_from_tc (session_kv4_t * kv, transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700110{
Florin Coras561af9b2017-12-09 10:19:43 -0800111 make_v4_ss_kv (kv, &tc->lcl_ip.ip4, &tc->rmt_ip.ip4, tc->lcl_port,
112 tc->rmt_port, tc->proto);
Florin Coras04e53442017-07-16 17:12:15 -0700113}
114
115always_inline void
116make_v6_ss_kv (session_kv6_t * kv, ip6_address_t * lcl, ip6_address_t * rmt,
117 u16 lcl_port, u16 rmt_port, u8 proto)
118{
Florin Coras9679c812018-06-21 08:14:34 -0700119 kv->key[0] = lcl->as_u64[0];
120 kv->key[1] = lcl->as_u64[1];
121 kv->key[2] = rmt->as_u64[0];
122 kv->key[3] = rmt->as_u64[1];
123 kv->key[4] = (u64) proto << 32 | (u64) rmt_port << 16 | (u64) lcl_port;
124 kv->key[5] = 0;
Florin Coras04e53442017-07-16 17:12:15 -0700125 kv->value = ~0ULL;
126}
127
128always_inline void
129make_v6_listener_kv (session_kv6_t * kv, ip6_address_t * lcl, u16 lcl_port,
130 u8 proto)
131{
Florin Coras9679c812018-06-21 08:14:34 -0700132 kv->key[0] = lcl->as_u64[0];
133 kv->key[1] = lcl->as_u64[1];
134 kv->key[2] = 0;
135 kv->key[3] = 0;
136 kv->key[4] = (u64) proto << 32 | (u64) lcl_port;
137 kv->key[5] = 0;
Florin Coras04e53442017-07-16 17:12:15 -0700138 kv->value = ~0ULL;
139}
140
141always_inline void
Florin Corasdbd44562017-11-09 19:30:17 -0800142make_v6_proxy_kv (session_kv6_t * kv, ip6_address_t * lcl, u8 proto)
143{
Florin Coras9679c812018-06-21 08:14:34 -0700144 kv->key[0] = lcl->as_u64[0];
145 kv->key[1] = lcl->as_u64[1];
146 kv->key[2] = 0;
147 kv->key[3] = 0;
148 kv->key[4] = (u64) proto << 32;
149 kv->key[5] = 0;
Florin Corasdbd44562017-11-09 19:30:17 -0800150 kv->value = ~0ULL;
151}
152
153always_inline void
Florin Coras561af9b2017-12-09 10:19:43 -0800154make_v6_ss_kv_from_tc (session_kv6_t * kv, transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700155{
Florin Coras561af9b2017-12-09 10:19:43 -0800156 make_v6_ss_kv (kv, &tc->lcl_ip.ip6, &tc->rmt_ip.ip6, tc->lcl_port,
157 tc->rmt_port, tc->proto);
Florin Coras04e53442017-07-16 17:12:15 -0700158}
159
Florin Corasf9bdc032024-02-02 13:01:07 -0800160static inline u8
161session_table_alloc_needs_sync (void)
162{
163 return !vlib_thread_is_main_w_barrier () && (vlib_num_workers () > 1);
164}
165
Florin Coras5bd96b72024-03-20 16:31:38 -0700166static_always_inline u8
167session_table_is_alloced (u8 fib_proto, u32 fib_index)
168{
169 return (vec_len (fib_index_to_table_index[fib_proto]) > fib_index &&
170 fib_index_to_table_index[fib_proto][fib_index] != ~0);
171}
172
Florin Corascea194d2017-10-02 00:18:51 -0700173static session_table_t *
Andreas Schultz30a28c12020-04-23 10:41:50 +0200174session_table_get_or_alloc (u8 fib_proto, u32 fib_index)
Florin Coras04e53442017-07-16 17:12:15 -0700175{
Florin Corascea194d2017-10-02 00:18:51 -0700176 session_table_t *st;
Florin Coras6c36f532017-11-03 18:32:34 -0700177 u32 table_index;
Florin Coras5bd96b72024-03-20 16:31:38 -0700178
Andreas Schultz30a28c12020-04-23 10:41:50 +0200179 ASSERT (fib_index != ~0);
Florin Coras5bd96b72024-03-20 16:31:38 -0700180
181 if (session_table_is_alloced (fib_proto, fib_index))
Andreas Schultz30a28c12020-04-23 10:41:50 +0200182 {
183 table_index = fib_index_to_table_index[fib_proto][fib_index];
184 return session_table_get (table_index);
185 }
Florin Coras5bd96b72024-03-20 16:31:38 -0700186
187 u8 needs_sync = session_table_alloc_needs_sync ();
188 session_lookup_main_t *slm = &sl_main;
189
190 /* Stop workers, otherwise consumers might be affected. This is
191 * acceptable because new tables should seldom be allocated */
192 if (needs_sync)
193 {
194 vlib_workers_sync ();
195
196 /* We might have a race, only one worker allowed at once */
197 clib_spinlock_lock (&slm->st_alloc_lock);
198 }
199
200 /* Another worker just allocated this table */
201 if (session_table_is_alloced (fib_proto, fib_index))
202 {
203 table_index = fib_index_to_table_index[fib_proto][fib_index];
204 st = session_table_get (table_index);
205 }
Andreas Schultz30a28c12020-04-23 10:41:50 +0200206 else
Florin Corascea194d2017-10-02 00:18:51 -0700207 {
208 st = session_table_alloc ();
Florin Coras6c36f532017-11-03 18:32:34 -0700209 st->active_fib_proto = fib_proto;
Florin Corasb795bd02017-12-14 11:30:48 -0800210 session_table_init (st, fib_proto);
Florin Coras5bd96b72024-03-20 16:31:38 -0700211 vec_validate_init_empty (fib_index_to_table_index[fib_proto], fib_index,
212 ~0);
213 table_index = session_table_index (st);
214 fib_index_to_table_index[fib_proto][fib_index] = table_index;
Florin Corascea194d2017-10-02 00:18:51 -0700215 }
Florin Coras5bd96b72024-03-20 16:31:38 -0700216
217 if (needs_sync)
218 {
219 clib_spinlock_unlock (&slm->st_alloc_lock);
220 vlib_workers_continue ();
221 }
222
223 return st;
Florin Corascea194d2017-10-02 00:18:51 -0700224}
225
226static session_table_t *
Florin Coras6c36f532017-11-03 18:32:34 -0700227session_table_get_or_alloc_for_connection (transport_connection_t * tc)
228{
229 u32 fib_proto;
230 fib_proto = transport_connection_fib_proto (tc);
231 return session_table_get_or_alloc (fib_proto, tc->fib_index);
232}
233
234static session_table_t *
Florin Corascea194d2017-10-02 00:18:51 -0700235session_table_get_for_connection (transport_connection_t * tc)
236{
237 u32 fib_proto = transport_connection_fib_proto (tc);
238 if (vec_len (fib_index_to_table_index[fib_proto]) <= tc->fib_index)
239 return 0;
240 return
241 session_table_get (fib_index_to_table_index[fib_proto][tc->fib_index]);
242}
243
244static session_table_t *
245session_table_get_for_fib_index (u32 fib_proto, u32 fib_index)
246{
247 if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
248 return 0;
249 return session_table_get (fib_index_to_table_index[fib_proto][fib_index]);
250}
251
252u32
253session_lookup_get_index_for_fib (u32 fib_proto, u32 fib_index)
254{
255 if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
256 return SESSION_TABLE_INVALID_INDEX;
257 return fib_index_to_table_index[fib_proto][fib_index];
258}
259
Florin Corasa4d09562021-07-08 08:25:09 -0700260u32
261session_lookup_get_or_alloc_index_for_fib (u32 fib_proto, u32 fib_index)
262{
263 session_table_t *st;
264 st = session_table_get_or_alloc (fib_proto, fib_index);
265 return session_table_index (st);
266}
267
Florin Corascea194d2017-10-02 00:18:51 -0700268/**
269 * Add transport connection to a session table
270 *
271 * Session lookup 5-tuple (src-ip, dst-ip, src-port, dst-port, session-type)
272 * is added to requested session table.
273 *
274 * @param tc transport connection to be added
275 * @param value value to be stored
276 *
277 * @return non-zero if failure
278 */
279int
280session_lookup_add_connection (transport_connection_t * tc, u64 value)
281{
282 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700283 session_kv4_t kv4;
284 session_kv6_t kv6;
285
Florin Corascea194d2017-10-02 00:18:51 -0700286 st = session_table_get_or_alloc_for_connection (tc);
287 if (!st)
288 return -1;
Florin Coras68810622017-07-24 17:40:28 -0700289 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700290 {
Florin Coras04e53442017-07-16 17:12:15 -0700291 make_v4_ss_kv_from_tc (&kv4, tc);
292 kv4.value = value;
Florin Corascea194d2017-10-02 00:18:51 -0700293 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4,
294 1 /* is_add */ );
Florin Coras68810622017-07-24 17:40:28 -0700295 }
296 else
297 {
Florin Coras04e53442017-07-16 17:12:15 -0700298 make_v6_ss_kv_from_tc (&kv6, tc);
299 kv6.value = value;
Florin Corascea194d2017-10-02 00:18:51 -0700300 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6,
301 1 /* is_add */ );
Florin Coras04e53442017-07-16 17:12:15 -0700302 }
303}
304
Florin Coras04e53442017-07-16 17:12:15 -0700305int
Florin Corascea194d2017-10-02 00:18:51 -0700306session_lookup_add_session_endpoint (u32 table_index,
307 session_endpoint_t * sep, u64 value)
Florin Coras04e53442017-07-16 17:12:15 -0700308{
Florin Corascea194d2017-10-02 00:18:51 -0700309 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700310 session_kv4_t kv4;
311 session_kv6_t kv6;
Florin Coras68810622017-07-24 17:40:28 -0700312
Florin Corascea194d2017-10-02 00:18:51 -0700313 st = session_table_get (table_index);
314 if (!st)
315 return -1;
316 if (sep->is_ip4)
317 {
318 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
319 sep->transport_proto);
320 kv4.value = value;
321 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 1);
322 }
323 else
324 {
325 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
326 sep->transport_proto);
327 kv6.value = value;
328 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 1);
329 }
330}
331
332int
333session_lookup_del_session_endpoint (u32 table_index,
334 session_endpoint_t * sep)
335{
336 session_table_t *st;
337 session_kv4_t kv4;
338 session_kv6_t kv6;
339
340 st = session_table_get (table_index);
341 if (!st)
342 return -1;
343 if (sep->is_ip4)
344 {
345 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
346 sep->transport_proto);
347 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0);
348 }
349 else
350 {
351 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
352 sep->transport_proto);
353 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0);
354 }
355}
356
Florin Corasaab06042020-02-26 02:56:14 +0000357int
358session_lookup_del_session_endpoint2 (session_endpoint_t * sep)
359{
360 fib_protocol_t fib_proto;
361 session_table_t *st;
362 session_kv4_t kv4;
363 session_kv6_t kv6;
364
365 fib_proto = sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
366 st = session_table_get_for_fib_index (fib_proto, sep->fib_index);
367 if (!st)
368 return -1;
369 if (sep->is_ip4)
370 {
371 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
372 sep->transport_proto);
373 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0);
374 }
375 else
376 {
377 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
378 sep->transport_proto);
379 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0);
380 }
381}
382
Florin Corascea194d2017-10-02 00:18:51 -0700383/**
384 * Delete transport connection from session table
385 *
386 * @param table_index session table index
387 * @param tc transport connection to be removed
388 *
389 * @return non-zero if failure
390 */
391int
392session_lookup_del_connection (transport_connection_t * tc)
393{
394 session_table_t *st;
395 session_kv4_t kv4;
396 session_kv6_t kv6;
397
398 st = session_table_get_for_connection (tc);
399 if (!st)
400 return -1;
Florin Coras68810622017-07-24 17:40:28 -0700401 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700402 {
Florin Coras04e53442017-07-16 17:12:15 -0700403 make_v4_ss_kv_from_tc (&kv4, tc);
Florin Corascea194d2017-10-02 00:18:51 -0700404 return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4,
Florin Coras04e53442017-07-16 17:12:15 -0700405 0 /* is_add */ );
Florin Coras68810622017-07-24 17:40:28 -0700406 }
407 else
408 {
Florin Coras04e53442017-07-16 17:12:15 -0700409 make_v6_ss_kv_from_tc (&kv6, tc);
Florin Corascea194d2017-10-02 00:18:51 -0700410 return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6,
Florin Coras04e53442017-07-16 17:12:15 -0700411 0 /* is_add */ );
Florin Coras04e53442017-07-16 17:12:15 -0700412 }
Florin Coras04e53442017-07-16 17:12:15 -0700413}
414
415int
Florin Coras288eaab2019-02-03 15:26:14 -0800416session_lookup_del_session (session_t * s)
Florin Coras04e53442017-07-16 17:12:15 -0700417{
418 transport_connection_t *ts;
Florin Coras1ee78302019-02-05 15:51:15 -0800419 ts = transport_get_connection (session_get_transport_proto (s),
420 s->connection_index, s->thread_index);
Florin Corase1e7fb82019-09-25 07:28:34 -0700421 if (!ts || (ts->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
Nathan Skrzypczak2eed1a12019-07-04 14:26:21 +0200422 return 0;
Florin Corascea194d2017-10-02 00:18:51 -0700423 return session_lookup_del_connection (ts);
Florin Coras04e53442017-07-16 17:12:15 -0700424}
425
Florin Corasdff48db2017-11-19 18:06:58 -0800426static u8
427session_lookup_action_index_is_valid (u32 action_index)
Florin Corasf0c1c962017-11-02 21:31:46 -0700428{
Florin Corasdff48db2017-11-19 18:06:58 -0800429 if (action_index == SESSION_RULES_TABLE_ACTION_ALLOW
430 || action_index == SESSION_RULES_TABLE_INVALID_INDEX)
431 return 0;
432 return 1;
433}
434
Florin Corasf8f516a2018-02-08 15:10:09 -0800435static u64
436session_lookup_action_to_handle (u32 action_index)
Florin Corasdff48db2017-11-19 18:06:58 -0800437{
438 switch (action_index)
439 {
440 case SESSION_RULES_TABLE_ACTION_DROP:
Florin Corasf8f516a2018-02-08 15:10:09 -0800441 return SESSION_DROP_HANDLE;
Florin Corasdff48db2017-11-19 18:06:58 -0800442 case SESSION_RULES_TABLE_ACTION_ALLOW:
443 case SESSION_RULES_TABLE_INVALID_INDEX:
Florin Corasf8f516a2018-02-08 15:10:09 -0800444 return SESSION_INVALID_HANDLE;
Florin Corasdff48db2017-11-19 18:06:58 -0800445 default:
Florin Corasf8f516a2018-02-08 15:10:09 -0800446 /* application index */
Florin Corasdff48db2017-11-19 18:06:58 -0800447 return action_index;
448 }
Florin Corasf0c1c962017-11-02 21:31:46 -0700449}
450
Florin Coras288eaab2019-02-03 15:26:14 -0800451static session_t *
Florin Coras7999e832017-10-31 01:51:04 -0700452session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
453 u8 transport_proto)
Florin Coras1c710452017-10-17 00:03:13 -0700454{
455 application_t *app;
Florin Corasdff48db2017-11-19 18:06:58 -0800456 app = application_get_if_valid (app_index);
Florin Coras1c710452017-10-17 00:03:13 -0700457 if (!app)
458 return 0;
459
Florin Coras15531972018-08-12 23:50:53 -0700460 return app_worker_first_listener (application_get_default_worker (app),
461 fib_proto, transport_proto);
Florin Coras1c710452017-10-17 00:03:13 -0700462}
463
Florin Coras288eaab2019-02-03 15:26:14 -0800464static session_t *
Florin Corasa2ff7b82017-11-08 17:55:03 -0800465session_lookup_action_to_session (u32 action_index, u8 fib_proto,
466 u8 transport_proto)
467{
Florin Corasdff48db2017-11-19 18:06:58 -0800468 u32 app_index;
Florin Corasf8f516a2018-02-08 15:10:09 -0800469 app_index = session_lookup_action_to_handle (action_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800470 /* Nothing sophisticated for now, action index is app index */
Florin Corasdff48db2017-11-19 18:06:58 -0800471 return session_lookup_app_listen_session (app_index, fib_proto,
Florin Corasa2ff7b82017-11-08 17:55:03 -0800472 transport_proto);
473}
474
Florin Corasf8f516a2018-02-08 15:10:09 -0800475/** UNUSED */
Florin Coras288eaab2019-02-03 15:26:14 -0800476session_t *
Florin Corasa2ff7b82017-11-08 17:55:03 -0800477session_lookup_rules_table_session4 (session_table_t * st, u8 proto,
478 ip4_address_t * lcl, u16 lcl_port,
479 ip4_address_t * rmt, u16 rmt_port)
Florin Coras1c710452017-10-17 00:03:13 -0700480{
Florin Corasc97a7392017-11-05 23:07:07 -0800481 session_rules_table_t *srt = &st->session_rules[proto];
Florin Corasdff48db2017-11-19 18:06:58 -0800482 u32 action_index, app_index;
Florin Corasc97a7392017-11-05 23:07:07 -0800483 action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
Florin Coras1c710452017-10-17 00:03:13 -0700484 rmt_port);
Florin Corasf8f516a2018-02-08 15:10:09 -0800485 app_index = session_lookup_action_to_handle (action_index);
Florin Coras1c710452017-10-17 00:03:13 -0700486 /* Nothing sophisticated for now, action index is app index */
Florin Corasdff48db2017-11-19 18:06:58 -0800487 return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4,
Florin Coras7999e832017-10-31 01:51:04 -0700488 proto);
Florin Coras1c710452017-10-17 00:03:13 -0700489}
490
Florin Corasf8f516a2018-02-08 15:10:09 -0800491/** UNUSED */
Florin Coras288eaab2019-02-03 15:26:14 -0800492session_t *
Florin Corasdff48db2017-11-19 18:06:58 -0800493session_lookup_rules_table_session6 (session_table_t * st, u8 proto,
494 ip6_address_t * lcl, u16 lcl_port,
495 ip6_address_t * rmt, u16 rmt_port)
Florin Coras1c710452017-10-17 00:03:13 -0700496{
Florin Corasc97a7392017-11-05 23:07:07 -0800497 session_rules_table_t *srt = &st->session_rules[proto];
Florin Corasdff48db2017-11-19 18:06:58 -0800498 u32 action_index, app_index;
Florin Corasc97a7392017-11-05 23:07:07 -0800499 action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
Florin Coras1c710452017-10-17 00:03:13 -0700500 rmt_port);
Florin Corasf8f516a2018-02-08 15:10:09 -0800501 app_index = session_lookup_action_to_handle (action_index);
Florin Corasdff48db2017-11-19 18:06:58 -0800502 return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6,
Florin Coras7999e832017-10-31 01:51:04 -0700503 proto);
Florin Coras1c710452017-10-17 00:03:13 -0700504}
505
Florin Corasa2ff7b82017-11-08 17:55:03 -0800506/**
507 * Lookup listener for session endpoint in table
508 *
509 * @param table_index table where the endpoint should be looked up
510 * @param sep session endpoint to be looked up
511 * @param use_rules flag that indicates if the session rules of the table
512 * should be used
513 * @return invalid handle if nothing is found, the handle of a valid listener
Florin Corasf8f516a2018-02-08 15:10:09 -0800514 * or an action derived handle if a rule is hit
Florin Corasa2ff7b82017-11-08 17:55:03 -0800515 */
Florin Coras3cbc04b2017-10-02 00:18:51 -0700516u64
Florin Corasa2ff7b82017-11-08 17:55:03 -0800517session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
518 u8 use_rules)
Florin Coras04e53442017-07-16 17:12:15 -0700519{
Florin Corasc97a7392017-11-05 23:07:07 -0800520 session_rules_table_t *srt;
Florin Corascea194d2017-10-02 00:18:51 -0700521 session_table_t *st;
Florin Corasf0c1c962017-11-02 21:31:46 -0700522 u32 ai;
Florin Corascea194d2017-10-02 00:18:51 -0700523 int rv;
Florin Coras04e53442017-07-16 17:12:15 -0700524
Florin Corascea194d2017-10-02 00:18:51 -0700525 st = session_table_get (table_index);
526 if (!st)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700527 return SESSION_INVALID_HANDLE;
Florin Corascea194d2017-10-02 00:18:51 -0700528 if (sep->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700529 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800530 session_kv4_t kv4;
531 ip4_address_t lcl4;
532
Florin Coras561af9b2017-12-09 10:19:43 -0800533 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
534 sep->transport_proto);
Florin Corascea194d2017-10-02 00:18:51 -0700535 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
536 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700537 return kv4.value;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800538 if (use_rules)
539 {
Dave Barachb7b92992018-10-17 10:38:51 -0400540 clib_memset (&lcl4, 0, sizeof (lcl4));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800541 srt = &st->session_rules[sep->transport_proto];
542 ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
543 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800544 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800545 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800546 }
Florin Coras68810622017-07-24 17:40:28 -0700547 }
548 else
549 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800550 session_kv6_t kv6;
551 ip6_address_t lcl6;
552
Florin Coras561af9b2017-12-09 10:19:43 -0800553 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
554 sep->transport_proto);
Florin Corascea194d2017-10-02 00:18:51 -0700555 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
556 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -0700557 return kv6.value;
Florin Coras1c710452017-10-17 00:03:13 -0700558
Florin Corasa2ff7b82017-11-08 17:55:03 -0800559 if (use_rules)
560 {
Dave Barachb7b92992018-10-17 10:38:51 -0400561 clib_memset (&lcl6, 0, sizeof (lcl6));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800562 srt = &st->session_rules[sep->transport_proto];
563 ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
564 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800565 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800566 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800567 }
Florin Coras68810622017-07-24 17:40:28 -0700568 }
Florin Coras3cbc04b2017-10-02 00:18:51 -0700569 return SESSION_INVALID_HANDLE;
570}
571
Florin Corasa2ff7b82017-11-08 17:55:03 -0800572/**
573 * Look up endpoint in local session table
574 *
575 * The result, for now, is an application index and it may in the future
576 * be extended to a more complicated "action object". The only action we
577 * emulate now is "drop" and for that we return a special app index.
578 *
579 * Lookup logic is to check in order:
580 * - the rules in the table (connect acls)
581 * - session sub-table for a listener
582 * - session sub-table for a local listener (zeroed addr)
583 *
584 * @param table_index table where the lookup should be done
585 * @param sep session endpoint to be looked up
Florin Corasf8f516a2018-02-08 15:10:09 -0800586 * @return session handle that can be interpreted as an adjacency
Florin Corasa2ff7b82017-11-08 17:55:03 -0800587 */
Florin Corasf8f516a2018-02-08 15:10:09 -0800588u64
Florin Corasa2ff7b82017-11-08 17:55:03 -0800589session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
Florin Coras68810622017-07-24 17:40:28 -0700590{
Florin Corasc97a7392017-11-05 23:07:07 -0800591 session_rules_table_t *srt;
Florin Corascea194d2017-10-02 00:18:51 -0700592 session_table_t *st;
Florin Corasf0c1c962017-11-02 21:31:46 -0700593 u32 ai;
Florin Corascea194d2017-10-02 00:18:51 -0700594 int rv;
Florin Coras68810622017-07-24 17:40:28 -0700595
Florin Corascea194d2017-10-02 00:18:51 -0700596 st = session_table_get (table_index);
597 if (!st)
598 return SESSION_INVALID_INDEX;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800599 ASSERT (st->is_local);
600
Florin Corascea194d2017-10-02 00:18:51 -0700601 if (sep->is_ip4)
Florin Coras68810622017-07-24 17:40:28 -0700602 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800603 session_kv4_t kv4;
604 ip4_address_t lcl4;
605
606 /*
607 * Check if endpoint has special rules associated
608 */
Dave Barachb7b92992018-10-17 10:38:51 -0400609 clib_memset (&lcl4, 0, sizeof (lcl4));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800610 srt = &st->session_rules[sep->transport_proto];
611 ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
612 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800613 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800614 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800615
616 /*
617 * Check if session endpoint is a listener
618 */
Florin Corascea194d2017-10-02 00:18:51 -0700619 make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
620 sep->transport_proto);
621 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
622 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800623 return kv4.value;
Florin Corascea194d2017-10-02 00:18:51 -0700624
625 /*
626 * Zero out the ip. Logic is that connect to local ips, say
627 * 127.0.0.1:port, can match 0.0.0.0:port
628 */
Florin Coras477e91a2018-02-27 10:05:57 -0800629 if (ip4_is_local_host (&sep->ip.ip4))
630 {
631 kv4.key[0] = 0;
632 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
633 if (rv == 0)
634 return kv4.value;
635 }
636 else
637 {
638 kv4.key[0] = 0;
639 }
Florin Corasdbd44562017-11-09 19:30:17 -0800640
641 /*
642 * Zero out the port and check if we have proxy
643 */
644 kv4.key[1] = 0;
645 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
646 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800647 return kv4.value;
Florin Coras68810622017-07-24 17:40:28 -0700648 }
649 else
650 {
Florin Corasa2ff7b82017-11-08 17:55:03 -0800651 session_kv6_t kv6;
652 ip6_address_t lcl6;
653
Dave Barachb7b92992018-10-17 10:38:51 -0400654 clib_memset (&lcl6, 0, sizeof (lcl6));
Florin Corasa2ff7b82017-11-08 17:55:03 -0800655 srt = &st->session_rules[sep->transport_proto];
656 ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
657 sep->port);
Florin Corasdff48db2017-11-19 18:06:58 -0800658 if (session_lookup_action_index_is_valid (ai))
Florin Corasf8f516a2018-02-08 15:10:09 -0800659 return session_lookup_action_to_handle (ai);
Florin Corasa2ff7b82017-11-08 17:55:03 -0800660
Florin Corascea194d2017-10-02 00:18:51 -0700661 make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
662 sep->transport_proto);
663 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
664 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800665 return kv6.value;
Florin Corascea194d2017-10-02 00:18:51 -0700666
667 /*
668 * Zero out the ip. Same logic as above.
669 */
Florin Coras477e91a2018-02-27 10:05:57 -0800670
671 if (ip6_is_local_host (&sep->ip.ip6))
672 {
673 kv6.key[0] = kv6.key[1] = 0;
674 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
675 if (rv == 0)
676 return kv6.value;
677 }
678 else
679 {
680 kv6.key[0] = kv6.key[1] = 0;
681 }
Florin Corasdbd44562017-11-09 19:30:17 -0800682
683 /*
684 * Zero out the port. Same logic as above.
685 */
686 kv6.key[4] = kv6.key[5] = 0;
687 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
688 if (rv == 0)
Florin Corasf8f516a2018-02-08 15:10:09 -0800689 return kv6.value;
Florin Coras04e53442017-07-16 17:12:15 -0700690 }
Florin Corasf8f516a2018-02-08 15:10:09 -0800691 return SESSION_INVALID_HANDLE;
Florin Coras04e53442017-07-16 17:12:15 -0700692}
693
Florin Coras288eaab2019-02-03 15:26:14 -0800694static inline session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700695session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl,
Florin Coras477e91a2018-02-27 10:05:57 -0800696 u16 lcl_port, u8 proto, u8 use_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700697{
Florin Coras04e53442017-07-16 17:12:15 -0700698 session_kv4_t kv4;
699 int rv;
700
Florin Corasdbd44562017-11-09 19:30:17 -0800701 /*
702 * First, try a fully formed listener
703 */
Florin Coras04e53442017-07-16 17:12:15 -0700704 make_v4_listener_kv (&kv4, lcl, lcl_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700705 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700706 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700707 return listen_session_get ((u32) kv4.value);
Florin Coras04e53442017-07-16 17:12:15 -0700708
Florin Corasdbd44562017-11-09 19:30:17 -0800709 /*
710 * Zero out the lcl ip and check if any 0/0 port binds have been done
711 */
Florin Coras477e91a2018-02-27 10:05:57 -0800712 if (use_wildcard)
713 {
714 kv4.key[0] = 0;
715 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
716 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700717 return listen_session_get ((u32) kv4.value);
Florin Coras477e91a2018-02-27 10:05:57 -0800718 }
719 else
720 {
721 kv4.key[0] = 0;
722 }
Florin Coras04e53442017-07-16 17:12:15 -0700723
Florin Corasdbd44562017-11-09 19:30:17 -0800724 /*
725 * Zero out port and check if we have a proxy set up for our ip
726 */
727 make_v4_proxy_kv (&kv4, lcl, proto);
728 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
729 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700730 return listen_session_get ((u32) kv4.value);
Florin Corasdbd44562017-11-09 19:30:17 -0800731
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_listener4 (u32 fib_index, ip4_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_IP4, fib_index);
741 if (!st)
742 return 0;
Yu Pingb092b772019-12-27 04:04:33 +0800743 return session_lookup_listener4_i (st, lcl, lcl_port, proto, use_wildcard);
Florin Coras04e53442017-07-16 17:12:15 -0700744}
745
Florin Coras288eaab2019-02-03 15:26:14 -0800746static session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700747session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl,
Florin Coras477e91a2018-02-27 10:05:57 -0800748 u16 lcl_port, u8 proto, u8 ip_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700749{
Florin Coras04e53442017-07-16 17:12:15 -0700750 session_kv6_t kv6;
751 int rv;
752
753 make_v6_listener_kv (&kv6, lcl, lcl_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700754 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -0700755 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700756 return listen_session_get ((u32) kv6.value);
Florin Coras04e53442017-07-16 17:12:15 -0700757
758 /* Zero out the lcl ip */
Florin Coras477e91a2018-02-27 10:05:57 -0800759 if (ip_wildcard)
760 {
761 kv6.key[0] = kv6.key[1] = 0;
762 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
763 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700764 return listen_session_get ((u32) kv6.value);
Florin Coras477e91a2018-02-27 10:05:57 -0800765 }
766 else
767 {
768 kv6.key[0] = kv6.key[1] = 0;
769 }
Florin Coras04e53442017-07-16 17:12:15 -0700770
Florin Corasdbd44562017-11-09 19:30:17 -0800771 make_v6_proxy_kv (&kv6, lcl, proto);
772 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
773 if (rv == 0)
Florin Coras5c9083d2018-04-13 06:39:07 -0700774 return listen_session_get ((u32) kv6.value);
Florin Coras04e53442017-07-16 17:12:15 -0700775 return 0;
776}
777
Florin Coras288eaab2019-02-03 15:26:14 -0800778session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700779session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port,
Yu Pingb092b772019-12-27 04:04:33 +0800780 u8 proto, u8 use_wildcard)
Florin Coras04e53442017-07-16 17:12:15 -0700781{
Florin Corascea194d2017-10-02 00:18:51 -0700782 session_table_t *st;
783 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
784 if (!st)
785 return 0;
Yu Pingb092b772019-12-27 04:04:33 +0800786 return session_lookup_listener6_i (st, lcl, lcl_port, proto, use_wildcard);
Florin Coras04e53442017-07-16 17:12:15 -0700787}
788
Florin Coras477e91a2018-02-27 10:05:57 -0800789/**
790 * Lookup listener, exact or proxy (inaddr_any:0) match
791 */
Florin Coras288eaab2019-02-03 15:26:14 -0800792session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700793session_lookup_listener (u32 table_index, session_endpoint_t * sep)
Florin Coras04e53442017-07-16 17:12:15 -0700794{
Florin Corascea194d2017-10-02 00:18:51 -0700795 session_table_t *st;
796 st = session_table_get (table_index);
797 if (!st)
798 return 0;
799 if (sep->is_ip4)
800 return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port,
Florin Coras477e91a2018-02-27 10:05:57 -0800801 sep->transport_proto, 0);
Florin Corascea194d2017-10-02 00:18:51 -0700802 else
803 return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port,
Florin Coras477e91a2018-02-27 10:05:57 -0800804 sep->transport_proto, 0);
Florin Coras04e53442017-07-16 17:12:15 -0700805 return 0;
806}
807
Florin Coras9f1a5432019-03-10 21:03:20 -0700808/**
809 * Lookup listener wildcard match
810 */
811session_t *
812session_lookup_listener_wildcard (u32 table_index, session_endpoint_t * sep)
813{
814 session_table_t *st;
815 st = session_table_get (table_index);
816 if (!st)
817 return 0;
818 if (sep->is_ip4)
819 return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port,
820 sep->transport_proto,
821 1 /* use_wildcard */ );
822 else
823 return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port,
824 sep->transport_proto,
825 1 /* use_wildcard */ );
826 return 0;
827}
828
Florin Corascea194d2017-10-02 00:18:51 -0700829int
830session_lookup_add_half_open (transport_connection_t * tc, u64 value)
831{
832 session_table_t *st;
833 session_kv4_t kv4;
834 session_kv6_t kv6;
835
836 st = session_table_get_or_alloc_for_connection (tc);
837 if (!st)
838 return 0;
839 if (tc->is_ip4)
840 {
841 make_v4_ss_kv_from_tc (&kv4, tc);
842 kv4.value = value;
843 return clib_bihash_add_del_16_8 (&st->v4_half_open_hash, &kv4,
844 1 /* is_add */ );
845 }
846 else
847 {
848 make_v6_ss_kv_from_tc (&kv6, tc);
849 kv6.value = value;
850 return clib_bihash_add_del_48_8 (&st->v6_half_open_hash, &kv6,
851 1 /* is_add */ );
852 }
853}
854
855int
856session_lookup_del_half_open (transport_connection_t * tc)
857{
858 session_table_t *st;
859 session_kv4_t kv4;
860 session_kv6_t kv6;
861
862 st = session_table_get_for_connection (tc);
863 if (!st)
864 return -1;
865 if (tc->is_ip4)
866 {
867 make_v4_ss_kv_from_tc (&kv4, tc);
868 return clib_bihash_add_del_16_8 (&st->v4_half_open_hash, &kv4,
869 0 /* is_add */ );
870 }
871 else
872 {
873 make_v6_ss_kv_from_tc (&kv6, tc);
874 return clib_bihash_add_del_48_8 (&st->v6_half_open_hash, &kv6,
875 0 /* is_add */ );
876 }
877}
878
Florin Coras04e53442017-07-16 17:12:15 -0700879u64
Florin Corascea194d2017-10-02 00:18:51 -0700880session_lookup_half_open_handle (transport_connection_t * tc)
Florin Coras04e53442017-07-16 17:12:15 -0700881{
Florin Corascea194d2017-10-02 00:18:51 -0700882 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700883 session_kv4_t kv4;
884 session_kv6_t kv6;
885 int rv;
886
Florin Corascea194d2017-10-02 00:18:51 -0700887 st = session_table_get_for_fib_index (transport_connection_fib_proto (tc),
888 tc->fib_index);
889 if (!st)
890 return HALF_OPEN_LOOKUP_INVALID_VALUE;
891 if (tc->is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700892 {
Florin Corascea194d2017-10-02 00:18:51 -0700893 make_v4_ss_kv (&kv4, &tc->lcl_ip.ip4, &tc->rmt_ip.ip4, tc->lcl_port,
Florin Coras3cbc04b2017-10-02 00:18:51 -0700894 tc->rmt_port, tc->proto);
Florin Corascea194d2017-10-02 00:18:51 -0700895 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700896 if (rv == 0)
897 return kv4.value;
Florin Corascea194d2017-10-02 00:18:51 -0700898 }
899 else
900 {
901 make_v6_ss_kv (&kv6, &tc->lcl_ip.ip6, &tc->rmt_ip.ip6, tc->lcl_port,
Florin Coras3cbc04b2017-10-02 00:18:51 -0700902 tc->rmt_port, tc->proto);
Florin Corascea194d2017-10-02 00:18:51 -0700903 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -0700904 if (rv == 0)
905 return kv6.value;
Florin Coras04e53442017-07-16 17:12:15 -0700906 }
907 return HALF_OPEN_LOOKUP_INVALID_VALUE;
908}
909
910transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -0700911session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4)
Florin Coras04e53442017-07-16 17:12:15 -0700912{
Florin Coras04e53442017-07-16 17:12:15 -0700913 if (handle != HALF_OPEN_LOOKUP_INVALID_VALUE)
Florin Corascea194d2017-10-02 00:18:51 -0700914 {
Florin Coras1ee78302019-02-05 15:51:15 -0800915 u32 sst = session_type_from_proto_and_ip (proto, is_ip4);
916 return transport_get_half_open (sst, handle & 0xFFFFFFFF);
Florin Corascea194d2017-10-02 00:18:51 -0700917 }
Florin Coras04e53442017-07-16 17:12:15 -0700918 return 0;
919}
920
Florin Corascea194d2017-10-02 00:18:51 -0700921/**
922 * Lookup connection with ip4 and transport layer information
923 *
924 * This is used on the fast path so it needs to be fast. Thereby,
925 * duplication of code and 'hacks' allowed.
926 *
927 * The lookup is incremental and returns whenever something is matched. The
928 * steps are:
929 * - Try to find an established session
Florin Corascea194d2017-10-02 00:18:51 -0700930 * - Try to find a half-open connection
Florin Coras1c710452017-10-17 00:03:13 -0700931 * - Try session rules table
Florin Corasa2ff7b82017-11-08 17:55:03 -0800932 * - Try to find a fully-formed or local source wildcarded (listener bound to
933 * all interfaces) listener session
Florin Corascea194d2017-10-02 00:18:51 -0700934 * - return 0
935 *
936 * @param fib_index index of fib wherein the connection was received
937 * @param lcl local ip4 address
938 * @param rmt remote ip4 address
939 * @param lcl_port local port
940 * @param rmt_port remote port
941 * @param proto transport protocol (e.g., tcp, udp)
942 * @param thread_index thread index for request
Florin Corasdff48db2017-11-19 18:06:58 -0800943 * @param is_filtered return flag that indicates if connection was filtered.
Florin Corascea194d2017-10-02 00:18:51 -0700944 *
945 * @return pointer to transport connection, if one is found, 0 otherwise
946 */
Florin Coras04e53442017-07-16 17:12:15 -0700947transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -0700948session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
949 ip4_address_t * rmt, u16 lcl_port,
Florin Corasdff48db2017-11-19 18:06:58 -0800950 u16 rmt_port, u8 proto, u32 thread_index,
Florin Corasb5e55a22019-01-10 12:42:47 -0800951 u8 * result)
Florin Coras04e53442017-07-16 17:12:15 -0700952{
Florin Corascea194d2017-10-02 00:18:51 -0700953 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -0700954 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -0800955 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -0800956 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -0700957 int rv;
958
Florin Corascea194d2017-10-02 00:18:51 -0700959 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
960 if (PREDICT_FALSE (!st))
961 return 0;
962
Florin Corasa2ff7b82017-11-08 17:55:03 -0800963 /*
964 * Lookup session amongst established ones
965 */
Florin Coras04e53442017-07-16 17:12:15 -0700966 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -0700967 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700968 if (rv == 0)
969 {
Florin Corasb5e55a22019-01-10 12:42:47 -0800970 if (PREDICT_FALSE ((u32) (kv4.value >> 32) != thread_index))
971 {
972 *result = SESSION_LOOKUP_RESULT_WRONG_THREAD;
973 return 0;
974 }
Florin Corascea194d2017-10-02 00:18:51 -0700975 s = session_get (kv4.value & 0xFFFFFFFFULL, thread_index);
Florin Coras1ee78302019-02-05 15:51:15 -0800976 return transport_get_connection (proto, s->connection_index,
977 thread_index);
Florin Coras04e53442017-07-16 17:12:15 -0700978 }
979
Florin Corasa2ff7b82017-11-08 17:55:03 -0800980 /*
981 * Try half-open connections
982 */
Florin Corascea194d2017-10-02 00:18:51 -0700983 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -0700984 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -0800985 return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
Florin Coras1c710452017-10-17 00:03:13 -0700986
Florin Corasa2ff7b82017-11-08 17:55:03 -0800987 /*
988 * Check the session rules table
989 */
990 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
991 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -0800992 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -0800993 {
Florin Corasb5e55a22019-01-10 12:42:47 -0800994 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
995 {
996 *result = SESSION_LOOKUP_RESULT_FILTERED;
997 return 0;
998 }
Florin Corasdff48db2017-11-19 18:06:58 -0800999 if ((s = session_lookup_action_to_session (action_index,
1000 FIB_PROTOCOL_IP4, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001001 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001002 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001003 }
1004
1005 /*
1006 * If nothing is found, check if any listener is available
1007 */
Florin Coras477e91a2018-02-27 10:05:57 -08001008 s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001009 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001010 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001011
1012 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001013}
1014
Florin Corascea194d2017-10-02 00:18:51 -07001015/**
1016 * Lookup connection with ip4 and transport layer information
1017 *
Florin Corasb5e55a22019-01-10 12:42:47 -08001018 * Not optimized. Lookup logic is identical to that of
1019 * @ref session_lookup_connection_wt4
Florin Corascea194d2017-10-02 00:18:51 -07001020 *
1021 * @param fib_index index of the fib wherein the connection was received
1022 * @param lcl local ip4 address
1023 * @param rmt remote ip4 address
1024 * @param lcl_port local port
1025 * @param rmt_port remote port
1026 * @param proto transport protocol (e.g., tcp, udp)
1027 *
1028 * @return pointer to transport connection, if one is found, 0 otherwise
1029 */
Florin Coras04e53442017-07-16 17:12:15 -07001030transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -07001031session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
1032 ip4_address_t * rmt, u16 lcl_port, u16 rmt_port,
1033 u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -07001034{
Florin Corascea194d2017-10-02 00:18:51 -07001035 session_table_t *st;
Florin Coras04e53442017-07-16 17:12:15 -07001036 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -08001037 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001038 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -07001039 int rv;
1040
Florin Corascea194d2017-10-02 00:18:51 -07001041 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
1042 if (PREDICT_FALSE (!st))
1043 return 0;
1044
Florin Corasa2ff7b82017-11-08 17:55:03 -08001045 /*
1046 * Lookup session amongst established ones
1047 */
Florin Coras04e53442017-07-16 17:12:15 -07001048 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001049 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -07001050 if (rv == 0)
1051 {
Florin Corascea194d2017-10-02 00:18:51 -07001052 s = session_get_from_handle (kv4.value);
Florin Coras1ee78302019-02-05 15:51:15 -08001053 return transport_get_connection (proto, s->connection_index,
1054 s->thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001055 }
1056
Florin Corasa2ff7b82017-11-08 17:55:03 -08001057 /*
1058 * Try half-open connections
1059 */
Florin Corascea194d2017-10-02 00:18:51 -07001060 rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
Florin Coras04e53442017-07-16 17:12:15 -07001061 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001062 return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001063
1064 /*
1065 * Check the session rules table
1066 */
1067 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
1068 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001069 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001070 {
Florin Corasdff48db2017-11-19 18:06:58 -08001071 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1072 return 0;
1073 if ((s = session_lookup_action_to_session (action_index,
1074 FIB_PROTOCOL_IP4, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001075 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001076 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001077 }
1078
1079 /*
1080 * If nothing is found, check if any listener is available
1081 */
Florin Coras477e91a2018-02-27 10:05:57 -08001082 s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001083 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001084 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001085
1086 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001087}
1088
Florin Corascea194d2017-10-02 00:18:51 -07001089/**
1090 * Lookup session with ip4 and transport layer information
1091 *
Florin Coras6bd8d3f2022-03-14 21:17:25 -07001092 * Important note: this may look into another thread's pool table
Florin Coras3cbc04b2017-10-02 00:18:51 -07001093 *
1094 * Lookup logic is similar to that of @ref session_lookup_connection_wt4 but
1095 * this returns a session as opposed to a transport connection and it does not
1096 * try to lookup half-open sessions.
1097 *
1098 * Typically used by dgram connections
Florin Corascea194d2017-10-02 00:18:51 -07001099 */
Florin Coras288eaab2019-02-03 15:26:14 -08001100session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001101session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt,
1102 u16 lcl_port, u16 rmt_port, u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -07001103{
Florin Corascea194d2017-10-02 00:18:51 -07001104 session_table_t *st;
1105 session_kv4_t kv4;
Florin Coras288eaab2019-02-03 15:26:14 -08001106 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001107 u32 action_index;
Florin Corascea194d2017-10-02 00:18:51 -07001108 int rv;
1109
1110 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
1111 if (PREDICT_FALSE (!st))
1112 return 0;
1113
Florin Corasa2ff7b82017-11-08 17:55:03 -08001114 /*
1115 * Lookup session amongst established ones
1116 */
Florin Corascea194d2017-10-02 00:18:51 -07001117 make_v4_ss_kv (&kv4, lcl, rmt, lcl_port, rmt_port, proto);
1118 rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
1119 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -07001120 return session_get_from_handle_safe (kv4.value);
Florin Corascea194d2017-10-02 00:18:51 -07001121
Florin Corasa2ff7b82017-11-08 17:55:03 -08001122 /*
1123 * Check the session rules table
1124 */
1125 action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
1126 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001127 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001128 {
Florin Corasdff48db2017-11-19 18:06:58 -08001129 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1130 return 0;
1131 return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
1132 proto);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001133 }
1134
1135 /*
1136 * If nothing is found, check if any listener is available
1137 */
Florin Coras477e91a2018-02-27 10:05:57 -08001138 if ((s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1)))
Florin Corascea194d2017-10-02 00:18:51 -07001139 return s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001140
1141 return 0;
Florin Corascea194d2017-10-02 00:18:51 -07001142}
1143
1144/**
1145 * Lookup connection with ip6 and transport layer information
1146 *
1147 * This is used on the fast path so it needs to be fast. Thereby,
1148 * duplication of code and 'hacks' allowed.
1149 *
1150 * The lookup is incremental and returns whenever something is matched. The
1151 * steps are:
1152 * - Try to find an established session
Florin Corascea194d2017-10-02 00:18:51 -07001153 * - Try to find a half-open connection
Florin Coras1c710452017-10-17 00:03:13 -07001154 * - Try session rules table
Florin Corasa2ff7b82017-11-08 17:55:03 -08001155 * - Try to find a fully-formed or local source wildcarded (listener bound to
1156 * all interfaces) listener session
Florin Corascea194d2017-10-02 00:18:51 -07001157 * - return 0
1158 *
1159 * @param fib_index index of the fib wherein the connection was received
1160 * @param lcl local ip6 address
1161 * @param rmt remote ip6 address
1162 * @param lcl_port local port
1163 * @param rmt_port remote port
1164 * @param proto transport protocol (e.g., tcp, udp)
1165 * @param thread_index thread index for request
1166 *
1167 * @return pointer to transport connection, if one is found, 0 otherwise
1168 */
1169transport_connection_t *
1170session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
1171 ip6_address_t * rmt, u16 lcl_port,
Florin Corasdff48db2017-11-19 18:06:58 -08001172 u16 rmt_port, u8 proto, u32 thread_index,
Florin Corasb5e55a22019-01-10 12:42:47 -08001173 u8 * result)
Florin Corascea194d2017-10-02 00:18:51 -07001174{
1175 session_table_t *st;
Florin Coras288eaab2019-02-03 15:26:14 -08001176 session_t *s;
Florin Coras04e53442017-07-16 17:12:15 -07001177 session_kv6_t kv6;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001178 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -07001179 int rv;
1180
Florin Corascea194d2017-10-02 00:18:51 -07001181 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1182 if (PREDICT_FALSE (!st))
1183 return 0;
1184
Florin Coras04e53442017-07-16 17:12:15 -07001185 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001186 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001187 if (rv == 0)
1188 {
Florin Corasb5e55a22019-01-10 12:42:47 -08001189 if (PREDICT_FALSE ((u32) (kv6.value >> 32) != thread_index))
1190 {
1191 *result = SESSION_LOOKUP_RESULT_WRONG_THREAD;
1192 return 0;
1193 }
Florin Corascea194d2017-10-02 00:18:51 -07001194 s = session_get (kv6.value & 0xFFFFFFFFULL, thread_index);
Florin Coras1ee78302019-02-05 15:51:15 -08001195 return transport_get_connection (proto, s->connection_index,
1196 thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001197 }
1198
Florin Corasa2ff7b82017-11-08 17:55:03 -08001199 /* Try half-open connections */
Florin Corascea194d2017-10-02 00:18:51 -07001200 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001201 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001202 return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
Florin Coras04e53442017-07-16 17:12:15 -07001203
Florin Corasa2ff7b82017-11-08 17:55:03 -08001204 /* Check the session rules table */
1205 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1206 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001207 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001208 {
Florin Corasb5e55a22019-01-10 12:42:47 -08001209 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1210 {
1211 *result = SESSION_LOOKUP_RESULT_FILTERED;
1212 return 0;
1213 }
Florin Corasdff48db2017-11-19 18:06:58 -08001214 if ((s = session_lookup_action_to_session (action_index,
1215 FIB_PROTOCOL_IP6, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001216 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001217 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001218 }
1219
1220 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001221 s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001222 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001223 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001224
1225 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001226}
1227
Florin Corascea194d2017-10-02 00:18:51 -07001228/**
1229 * Lookup connection with ip6 and transport layer information
1230 *
1231 * Not optimized. This is used on the fast path so it needs to be fast.
1232 * Thereby, duplication of code and 'hacks' allowed. Lookup logic is identical
1233 * to that of @ref session_lookup_connection_wt4
1234 *
1235 * @param fib_index index of the fib wherein the connection was received
1236 * @param lcl local ip6 address
1237 * @param rmt remote ip6 address
1238 * @param lcl_port local port
1239 * @param rmt_port remote port
1240 * @param proto transport protocol (e.g., tcp, udp)
1241 *
1242 * @return pointer to transport connection, if one is found, 0 otherwise
1243 */
Florin Coras04e53442017-07-16 17:12:15 -07001244transport_connection_t *
Florin Corascea194d2017-10-02 00:18:51 -07001245session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
1246 ip6_address_t * rmt, u16 lcl_port, u16 rmt_port,
1247 u8 proto)
Florin Coras04e53442017-07-16 17:12:15 -07001248{
Florin Corascea194d2017-10-02 00:18:51 -07001249 session_table_t *st;
Florin Coras288eaab2019-02-03 15:26:14 -08001250 session_t *s;
Florin Coras04e53442017-07-16 17:12:15 -07001251 session_kv6_t kv6;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001252 u32 action_index;
Florin Coras04e53442017-07-16 17:12:15 -07001253 int rv;
1254
Florin Corascea194d2017-10-02 00:18:51 -07001255 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1256 if (PREDICT_FALSE (!st))
1257 return 0;
1258
Florin Coras04e53442017-07-16 17:12:15 -07001259 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
Florin Corascea194d2017-10-02 00:18:51 -07001260 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001261 if (rv == 0)
1262 {
Florin Corascea194d2017-10-02 00:18:51 -07001263 s = session_get_from_handle (kv6.value);
Florin Coras1ee78302019-02-05 15:51:15 -08001264 return transport_get_connection (proto, s->connection_index,
1265 s->thread_index);
Florin Coras04e53442017-07-16 17:12:15 -07001266 }
1267
Florin Corasa2ff7b82017-11-08 17:55:03 -08001268 /* Try half-open connections */
Florin Corascea194d2017-10-02 00:18:51 -07001269 rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
Florin Coras04e53442017-07-16 17:12:15 -07001270 if (rv == 0)
Florin Coras1ee78302019-02-05 15:51:15 -08001271 return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
Florin Coras04e53442017-07-16 17:12:15 -07001272
Florin Corasa2ff7b82017-11-08 17:55:03 -08001273 /* Check the session rules table */
1274 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1275 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001276 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001277 {
Florin Corasdff48db2017-11-19 18:06:58 -08001278 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1279 return 0;
1280 if ((s = session_lookup_action_to_session (action_index,
1281 FIB_PROTOCOL_IP6, proto)))
Florin Coras1ee78302019-02-05 15:51:15 -08001282 return transport_get_listener (proto, s->connection_index);
Florin Corasdff48db2017-11-19 18:06:58 -08001283 return 0;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001284 }
1285
1286 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001287 s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001288 if (s)
Florin Coras1ee78302019-02-05 15:51:15 -08001289 return transport_get_listener (proto, s->connection_index);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001290
1291 return 0;
Florin Coras04e53442017-07-16 17:12:15 -07001292}
1293
Florin Corascea194d2017-10-02 00:18:51 -07001294/**
1295 * Lookup session with ip6 and transport layer information
1296 *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001297 * Important note: this may look into another thread's pool table and
1298 * register as 'peeker'. Caller should call @ref session_pool_remove_peeker as
1299 * if needed as soon as possible.
1300 *
1301 * Lookup logic is similar to that of @ref session_lookup_connection_wt6 but
1302 * this returns a session as opposed to a transport connection and it does not
1303 * try to lookup half-open sessions.
1304 *
1305 * Typically used by dgram connections
Florin Corascea194d2017-10-02 00:18:51 -07001306 */
Florin Coras288eaab2019-02-03 15:26:14 -08001307session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -07001308session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt,
1309 u16 lcl_port, u16 rmt_port, u8 proto)
Florin Corascea194d2017-10-02 00:18:51 -07001310{
1311 session_table_t *st;
1312 session_kv6_t kv6;
Florin Coras288eaab2019-02-03 15:26:14 -08001313 session_t *s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001314 u32 action_index;
Florin Corascea194d2017-10-02 00:18:51 -07001315 int rv;
1316
1317 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1318 if (PREDICT_FALSE (!st))
1319 return 0;
1320
1321 make_v6_ss_kv (&kv6, lcl, rmt, lcl_port, rmt_port, proto);
1322 rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
1323 if (rv == 0)
Florin Coras3cbc04b2017-10-02 00:18:51 -07001324 return session_get_from_handle_safe (kv6.value);
Florin Corascea194d2017-10-02 00:18:51 -07001325
Florin Corasa2ff7b82017-11-08 17:55:03 -08001326 /* Check the session rules table */
1327 action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
1328 rmt, lcl_port, rmt_port);
Florin Corasdff48db2017-11-19 18:06:58 -08001329 if (session_lookup_action_index_is_valid (action_index))
Florin Corasa2ff7b82017-11-08 17:55:03 -08001330 {
Florin Corasdff48db2017-11-19 18:06:58 -08001331 if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
1332 return 0;
1333 return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6,
1334 proto);
Florin Corasa2ff7b82017-11-08 17:55:03 -08001335 }
1336
Florin Corascea194d2017-10-02 00:18:51 -07001337 /* If nothing is found, check if any listener is available */
Florin Coras477e91a2018-02-27 10:05:57 -08001338 if ((s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1)))
Florin Corascea194d2017-10-02 00:18:51 -07001339 return s;
Florin Corasa2ff7b82017-11-08 17:55:03 -08001340 return 0;
Florin Corascea194d2017-10-02 00:18:51 -07001341}
1342
Florin Coras57660d92020-04-04 22:45:34 +00001343transport_connection_t *
1344session_lookup_connection (u32 fib_index, ip46_address_t * lcl,
1345 ip46_address_t * rmt, u16 lcl_port, u16 rmt_port,
1346 u8 proto, u8 is_ip4)
1347{
1348 if (is_ip4)
1349 return session_lookup_connection4 (fib_index, &lcl->ip4, &rmt->ip4,
1350 lcl_port, rmt_port, proto);
1351 else
1352 return session_lookup_connection6 (fib_index, &lcl->ip6, &rmt->ip6,
1353 lcl_port, rmt_port, proto);
1354}
1355
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001356session_error_t
1357vnet_session_rule_add_del (session_rule_add_del_args_t *args)
Florin Coras1c710452017-10-17 00:03:13 -07001358{
1359 app_namespace_t *app_ns = app_namespace_get (args->appns_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001360 session_rules_table_t *srt;
Florin Coras1c710452017-10-17 00:03:13 -07001361 session_table_t *st;
1362 u32 fib_index;
1363 u8 fib_proto;
Florin Corasc1a42652019-02-08 18:27:29 -08001364 int rv = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001365
1366 if (!app_ns)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001367 return SESSION_E_INVALID_NS;
Florin Corasc1a42652019-02-08 18:27:29 -08001368
Florin Coras1c710452017-10-17 00:03:13 -07001369 if (args->scope > 3)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001370 return SESSION_E_INVALID;
Florin Corasc1a42652019-02-08 18:27:29 -08001371
Florin Corasc97a7392017-11-05 23:07:07 -08001372 if (args->transport_proto != TRANSPORT_PROTO_TCP
1373 && args->transport_proto != TRANSPORT_PROTO_UDP)
Filip Tehlar0028e6f2023-06-28 10:47:32 +02001374 return SESSION_E_INVALID;
Florin Corasc1a42652019-02-08 18:27:29 -08001375
Florin Coras1c710452017-10-17 00:03:13 -07001376 if ((args->scope & SESSION_RULE_SCOPE_GLOBAL) || args->scope == 0)
1377 {
1378 fib_proto = args->table_args.rmt.fp_proto;
1379 fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
1380 st = session_table_get_for_fib_index (fib_proto, fib_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001381 srt = &st->session_rules[args->transport_proto];
Florin Corasc1a42652019-02-08 18:27:29 -08001382 if ((rv = session_rules_table_add_del (srt, &args->table_args)))
1383 return rv;
Florin Coras1c710452017-10-17 00:03:13 -07001384 }
1385 if (args->scope & SESSION_RULE_SCOPE_LOCAL)
1386 {
Dave Barachb7b92992018-10-17 10:38:51 -04001387 clib_memset (&args->table_args.lcl, 0, sizeof (args->table_args.lcl));
Florin Corasa2ff7b82017-11-08 17:55:03 -08001388 args->table_args.lcl.fp_proto = args->table_args.rmt.fp_proto;
1389 args->table_args.lcl_port = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001390 st = app_namespace_get_local_table (app_ns);
Florin Corasc97a7392017-11-05 23:07:07 -08001391 srt = &st->session_rules[args->transport_proto];
Florin Corasc1a42652019-02-08 18:27:29 -08001392 rv = session_rules_table_add_del (srt, &args->table_args);
Florin Coras1c710452017-10-17 00:03:13 -07001393 }
Florin Corasc1a42652019-02-08 18:27:29 -08001394 return rv;
Florin Coras1c710452017-10-17 00:03:13 -07001395}
1396
Steven Luong5682ca82024-07-17 16:16:05 -07001397static void
1398session_lookup_fib_table_lock (u32 fib_index, u32 protocol)
1399{
1400 fib_table_lock (fib_index, protocol, sl_main.fib_src);
1401 vec_validate (fib_index_to_lock_count[protocol], fib_index);
1402 fib_index_to_lock_count[protocol][fib_index]++;
1403 ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0);
1404}
1405
1406static void
1407session_lookup_fib_table_unlock (u32 fib_index, u32 protocol)
1408{
1409 fib_table_unlock (fib_index, protocol, sl_main.fib_src);
1410 ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0);
1411 fib_index_to_lock_count[protocol][fib_index]--;
1412}
1413
Florin Coras6c36f532017-11-03 18:32:34 -07001414/**
1415 * Mark (global) tables as pertaining to app ns
1416 */
1417void
1418session_lookup_set_tables_appns (app_namespace_t * app_ns)
1419{
1420 session_table_t *st;
1421 u32 fib_index;
1422 u8 fp;
1423
1424 for (fp = 0; fp < ARRAY_LEN (fib_index_to_table_index); fp++)
1425 {
1426 fib_index = app_namespace_get_fib_index (app_ns, fp);
Florin Coras95cd8642019-12-30 21:53:19 -08001427 st = session_table_get_or_alloc (fp, fib_index);
Florin Coras6c36f532017-11-03 18:32:34 -07001428 if (st)
Steven Luong5682ca82024-07-17 16:16:05 -07001429 {
1430 st->appns_index = app_namespace_index (app_ns);
1431 session_lookup_fib_table_lock (fib_index, fp);
1432 }
Florin Coras6c36f532017-11-03 18:32:34 -07001433 }
1434}
1435
Florin Corascea194d2017-10-02 00:18:51 -07001436u8 *
1437format_ip4_session_lookup_kvp (u8 * s, va_list * args)
1438{
1439 clib_bihash_kv_16_8_t *kvp = va_arg (*args, clib_bihash_kv_16_8_t *);
Florin Coras2b81e3c2019-02-27 07:55:46 -08001440 u32 is_local = va_arg (*args, u32);
Florin Coras15531972018-08-12 23:50:53 -07001441 v4_connection_key_t *key = (v4_connection_key_t *) kvp->key;
Florin Coras288eaab2019-02-03 15:26:14 -08001442 session_t *session;
Florin Coras15531972018-08-12 23:50:53 -07001443 app_worker_t *app_wrk;
Florin Coras053a0e42018-11-13 15:52:38 -08001444 const u8 *app_name;
1445 u8 *str = 0;
Florin Corascea194d2017-10-02 00:18:51 -07001446
Florin Corascea194d2017-10-02 00:18:51 -07001447 if (!is_local)
1448 {
1449 session = session_get_from_handle (kvp->value);
Florin Coras15531972018-08-12 23:50:53 -07001450 app_wrk = app_worker_get (session->app_wrk_index);
1451 app_name = application_name_from_index (app_wrk->app_index);
Florin Coras561af9b2017-12-09 10:19:43 -08001452 str = format (0, "[%U] %U:%d->%U:%d", format_transport_proto_short,
1453 key->proto, format_ip4_address, &key->src,
1454 clib_net_to_host_u16 (key->src_port), format_ip4_address,
1455 &key->dst, clib_net_to_host_u16 (key->dst_port));
Florin Corascea194d2017-10-02 00:18:51 -07001456 s = format (s, "%-40v%-30v", str, app_name);
1457 }
1458 else
1459 {
Florin Coras2b81e3c2019-02-27 07:55:46 -08001460 session = session_get_from_handle (kvp->value);
1461 app_wrk = app_worker_get (session->app_wrk_index);
Florin Coras15531972018-08-12 23:50:53 -07001462 app_name = application_name_from_index (app_wrk->app_index);
Florin Coras561af9b2017-12-09 10:19:43 -08001463 str = format (0, "[%U] %U:%d", format_transport_proto_short, key->proto,
1464 format_ip4_address, &key->src,
1465 clib_net_to_host_u16 (key->src_port));
Florin Corascea194d2017-10-02 00:18:51 -07001466 s = format (s, "%-30v%-30v", str, app_name);
1467 }
Florin Corascea194d2017-10-02 00:18:51 -07001468 return s;
1469}
1470
1471typedef struct _ip4_session_table_show_ctx_t
1472{
1473 vlib_main_t *vm;
1474 u8 is_local;
1475} ip4_session_table_show_ctx_t;
1476
1477static int
1478ip4_session_table_show (clib_bihash_kv_16_8_t * kvp, void *arg)
1479{
1480 ip4_session_table_show_ctx_t *ctx = arg;
1481 vlib_cli_output (ctx->vm, "%U", format_ip4_session_lookup_kvp, kvp,
1482 ctx->is_local);
1483 return 1;
1484}
1485
1486void
1487session_lookup_show_table_entries (vlib_main_t * vm, session_table_t * table,
1488 u8 type, u8 is_local)
1489{
1490 ip4_session_table_show_ctx_t ctx = {
1491 .vm = vm,
1492 .is_local = is_local,
1493 };
1494 if (!is_local)
1495 vlib_cli_output (vm, "%-40s%-30s", "Session", "Application");
1496 else
1497 vlib_cli_output (vm, "%-30s%-30s", "Listener", "Application");
1498 switch (type)
1499 {
1500 /* main table v4 */
1501 case 0:
1502 ip4_session_table_walk (&table->v4_session_hash, ip4_session_table_show,
1503 &ctx);
1504 break;
1505 default:
1506 clib_warning ("not supported");
1507 }
1508}
Florin Coras66b11312017-07-31 17:18:03 -07001509
Florin Coras1c710452017-10-17 00:03:13 -07001510static clib_error_t *
1511session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
1512 vlib_cli_command_t * cmd)
1513{
Florin Corasc97a7392017-11-05 23:07:07 -08001514 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen = 0, rmt_plen = 0;
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001515 clib_error_t *error = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001516 u32 appns_index, scope = 0;
1517 ip46_address_t lcl_ip, rmt_ip;
1518 u8 is_ip4 = 1, conn_set = 0;
1519 u8 fib_proto, is_add = 1, *ns_id = 0;
Florin Corasc97a7392017-11-05 23:07:07 -08001520 u8 *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -07001521 app_namespace_t *app_ns;
Florin Corasc1a42652019-02-08 18:27:29 -08001522 int rv;
Florin Coras1c710452017-10-17 00:03:13 -07001523
Guanghua Zhangfcd5e122019-08-24 10:52:19 +08001524 session_cli_return_if_not_enabled ();
1525
Dave Barachb7b92992018-10-17 10:38:51 -04001526 clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
1527 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Florin Coras1c710452017-10-17 00:03:13 -07001528 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1529 {
1530 if (unformat (input, "del"))
1531 is_add = 0;
1532 else if (unformat (input, "add"))
1533 ;
1534 else if (unformat (input, "appns %_%v%_", &ns_id))
1535 ;
1536 else if (unformat (input, "scope global"))
1537 scope = SESSION_RULE_SCOPE_GLOBAL;
1538 else if (unformat (input, "scope local"))
1539 scope = SESSION_RULE_SCOPE_LOCAL;
1540 else if (unformat (input, "scope all"))
1541 scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
1542 else if (unformat (input, "proto %U", unformat_transport_proto, &proto))
1543 ;
1544 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip4_address,
1545 &lcl_ip.ip4, &lcl_plen, &lcl_port,
1546 unformat_ip4_address, &rmt_ip.ip4, &rmt_plen,
1547 &rmt_port))
1548 {
1549 is_ip4 = 1;
1550 conn_set = 1;
1551 }
1552 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip6_address,
1553 &lcl_ip.ip6, &lcl_plen, &lcl_port,
1554 unformat_ip6_address, &rmt_ip.ip6, &rmt_plen,
1555 &rmt_port))
1556 {
1557 is_ip4 = 0;
1558 conn_set = 1;
1559 }
1560 else if (unformat (input, "action %d", &action))
1561 ;
Florin Corasc97a7392017-11-05 23:07:07 -08001562 else if (unformat (input, "tag %_%v%_", &tag))
1563 ;
Florin Coras1c710452017-10-17 00:03:13 -07001564 else
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001565 {
1566 error = clib_error_return (0, "unknown input `%U'",
1567 format_unformat_error, input);
1568 goto done;
1569 }
Florin Coras1c710452017-10-17 00:03:13 -07001570 }
1571
Florin Corasc97a7392017-11-05 23:07:07 -08001572 if (proto == ~0)
1573 {
1574 vlib_cli_output (vm, "proto must be set");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001575 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001576 }
1577 if (is_add && !conn_set && action == ~0)
1578 {
1579 vlib_cli_output (vm, "connection and action must be set for add");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001580 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001581 }
1582 if (!is_add && !tag && !conn_set)
1583 {
1584 vlib_cli_output (vm, "connection or tag must be set for delete");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001585 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001586 }
1587 if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
1588 {
1589 vlib_cli_output (vm, "tag too long (max u64)");
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001590 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001591 }
Florin Coras1c710452017-10-17 00:03:13 -07001592
1593 if (ns_id)
1594 {
1595 app_ns = app_namespace_get_from_id (ns_id);
1596 if (!app_ns)
Florin Corasc97a7392017-11-05 23:07:07 -08001597 {
1598 vlib_cli_output (vm, "namespace %v does not exist", ns_id);
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001599 goto done;
Florin Corasc97a7392017-11-05 23:07:07 -08001600 }
Florin Coras1c710452017-10-17 00:03:13 -07001601 }
1602 else
1603 {
1604 app_ns = app_namespace_get_default ();
1605 }
1606 appns_index = app_namespace_index (app_ns);
1607
1608 fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
1609 session_rule_add_del_args_t args = {
zhanglimaoa04ebb82019-03-13 10:36:54 +08001610 .transport_proto = proto,
Florin Coras1c710452017-10-17 00:03:13 -07001611 .table_args.lcl.fp_addr = lcl_ip,
1612 .table_args.lcl.fp_len = lcl_plen,
1613 .table_args.lcl.fp_proto = fib_proto,
1614 .table_args.rmt.fp_addr = rmt_ip,
1615 .table_args.rmt.fp_len = rmt_plen,
1616 .table_args.rmt.fp_proto = fib_proto,
1617 .table_args.lcl_port = lcl_port,
1618 .table_args.rmt_port = rmt_port,
1619 .table_args.action_index = action,
1620 .table_args.is_add = is_add,
Florin Corasc97a7392017-11-05 23:07:07 -08001621 .table_args.tag = tag,
Florin Coras1c710452017-10-17 00:03:13 -07001622 .appns_index = appns_index,
1623 .scope = scope,
1624 };
Florin Corasc1a42652019-02-08 18:27:29 -08001625 if ((rv = vnet_session_rule_add_del (&args)))
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001626 error = clib_error_return (0, "rule add del returned %u", rv);
Florin Corasc1a42652019-02-08 18:27:29 -08001627
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001628done:
1629 vec_free (ns_id);
Florin Corasc97a7392017-11-05 23:07:07 -08001630 vec_free (tag);
Nathan Skrzypczak1a9e2f92021-07-28 19:35:08 +02001631 return error;
Florin Coras1c710452017-10-17 00:03:13 -07001632}
1633
Florin Coras1c710452017-10-17 00:03:13 -07001634VLIB_CLI_COMMAND (session_rule_command, static) =
1635{
1636 .path = "session rule",
1637 .short_help = "session rule [add|del] appns <ns_id> proto <proto> "
1638 "<lcl-ip/plen> <lcl-port> <rmt-ip/plen> <rmt-port> action <action>",
1639 .function = session_rule_command_fn,
1640};
Florin Coras1c710452017-10-17 00:03:13 -07001641
Florin Coras7999e832017-10-31 01:51:04 -07001642void
1643session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
1644 u8 transport_proto)
1645{
1646 vlib_main_t *vm = vlib_get_main ();
Florin Corasc97a7392017-11-05 23:07:07 -08001647 session_rules_table_t *srt;
Florin Coras7999e832017-10-31 01:51:04 -07001648 session_table_t *st;
1649 st = session_table_get_for_fib_index (fib_index, fib_proto);
Florin Corasc97a7392017-11-05 23:07:07 -08001650 srt = &st->session_rules[transport_proto];
1651 session_rules_table_cli_dump (vm, srt, fib_proto);
Florin Coras7999e832017-10-31 01:51:04 -07001652}
1653
1654void
1655session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto,
1656 u8 transport_proto)
1657{
1658 vlib_main_t *vm = vlib_get_main ();
Florin Corasc97a7392017-11-05 23:07:07 -08001659 session_rules_table_t *srt;
Florin Coras7999e832017-10-31 01:51:04 -07001660 session_table_t *st;
1661 st = session_table_get (table_index);
Florin Corasc97a7392017-11-05 23:07:07 -08001662 srt = &st->session_rules[transport_proto];
1663 session_rules_table_cli_dump (vm, srt, fib_proto);
Florin Coras7999e832017-10-31 01:51:04 -07001664}
1665
Florin Coras1c710452017-10-17 00:03:13 -07001666static clib_error_t *
1667show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
1668 vlib_cli_command_t * cmd)
1669{
1670 u32 transport_proto = ~0, lcl_port, rmt_port, lcl_plen, rmt_plen;
1671 u32 fib_index, scope = 0;
1672 ip46_address_t lcl_ip, rmt_ip;
1673 u8 is_ip4 = 1, show_one = 0;
1674 app_namespace_t *app_ns;
Florin Corasc97a7392017-11-05 23:07:07 -08001675 session_rules_table_t *srt;
Florin Coras1c710452017-10-17 00:03:13 -07001676 session_table_t *st;
1677 u8 *ns_id = 0, fib_proto;
1678
Guanghua Zhangfcd5e122019-08-24 10:52:19 +08001679 session_cli_return_if_not_enabled ();
1680
Dave Barachb7b92992018-10-17 10:38:51 -04001681 clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
1682 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Florin Coras1c710452017-10-17 00:03:13 -07001683 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1684 {
1685 if (unformat (input, "%U", unformat_transport_proto, &transport_proto))
1686 ;
1687 else if (unformat (input, "appns %_%v%_", &ns_id))
1688 ;
1689 else if (unformat (input, "scope global"))
Steven Luonge87a03f2024-07-18 09:10:48 -07001690 scope = SESSION_RULE_SCOPE_GLOBAL;
Florin Coras1c710452017-10-17 00:03:13 -07001691 else if (unformat (input, "scope local"))
Steven Luonge87a03f2024-07-18 09:10:48 -07001692 scope = SESSION_RULE_SCOPE_LOCAL;
Florin Coras1c710452017-10-17 00:03:13 -07001693 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip4_address,
1694 &lcl_ip.ip4, &lcl_plen, &lcl_port,
1695 unformat_ip4_address, &rmt_ip.ip4, &rmt_plen,
1696 &rmt_port))
1697 {
1698 is_ip4 = 1;
1699 show_one = 1;
1700 }
1701 else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip6_address,
1702 &lcl_ip.ip6, &lcl_plen, &lcl_port,
1703 unformat_ip6_address, &rmt_ip.ip6, &rmt_plen,
1704 &rmt_port))
1705 {
1706 is_ip4 = 0;
1707 show_one = 1;
1708 }
1709 else
1710 return clib_error_return (0, "unknown input `%U'",
1711 format_unformat_error, input);
1712 }
1713
1714 if (transport_proto == ~0)
1715 {
1716 vlib_cli_output (vm, "transport proto must be set");
1717 return 0;
1718 }
1719
1720 if (ns_id)
1721 {
1722 app_ns = app_namespace_get_from_id (ns_id);
1723 if (!app_ns)
1724 {
1725 vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
1726 return 0;
1727 }
1728 }
1729 else
1730 {
1731 app_ns = app_namespace_get_default ();
1732 }
1733
Steven Luonge87a03f2024-07-18 09:10:48 -07001734 if (scope == SESSION_RULE_SCOPE_GLOBAL || scope == 0)
Florin Coras1c710452017-10-17 00:03:13 -07001735 {
1736 fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
1737 fib_index = is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
1738 st = session_table_get_for_fib_index (fib_proto, fib_index);
1739 }
1740 else
1741 {
1742 st = app_namespace_get_local_table (app_ns);
1743 }
1744
1745 if (show_one)
1746 {
Florin Corasc97a7392017-11-05 23:07:07 -08001747 srt = &st->session_rules[transport_proto];
1748 session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip,
1749 rmt_port, is_ip4);
Florin Coras1c710452017-10-17 00:03:13 -07001750 return 0;
1751 }
1752
Florin Corasc97a7392017-11-05 23:07:07 -08001753 vlib_cli_output (vm, "%U rules table", format_transport_proto,
1754 transport_proto);
Steven Luonge87a03f2024-07-18 09:10:48 -07001755 if (scope == SESSION_RULE_SCOPE_LOCAL)
1756 {
1757 if (st)
1758 {
1759 srt = &st->session_rules[transport_proto];
1760 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
1761 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
1762 }
1763 }
1764 else
1765 {
1766 /*
1767 * 2 separate session tables for global entries, 1 for ip4 and 1 for ip6
1768 */
1769 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4,
1770 app_ns->ip4_fib_index);
1771 if (st)
1772 {
1773 srt = &st->session_rules[transport_proto];
1774 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
1775 }
1776
1777 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6,
1778 app_ns->ip6_fib_index);
1779 if (st)
1780 {
1781 srt = &st->session_rules[transport_proto];
1782 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
1783 }
1784 }
Florin Coras1c710452017-10-17 00:03:13 -07001785
1786 vec_free (ns_id);
1787 return 0;
1788}
1789
Florin Coras1c710452017-10-17 00:03:13 -07001790VLIB_CLI_COMMAND (show_session_rules_command, static) =
1791{
1792 .path = "show session rules",
Florin Corasdff48db2017-11-19 18:06:58 -08001793 .short_help = "show session rules [<proto> appns <id> <lcl-ip/plen> "
1794 "<lcl-port> <rmt-ip/plen> <rmt-port> scope <scope>]",
Florin Coras1c710452017-10-17 00:03:13 -07001795 .function = show_session_rules_command_fn,
1796};
Florin Coras1c710452017-10-17 00:03:13 -07001797
Florin Coras894d0a62023-11-17 16:35:04 -08001798u8 *
1799format_session_lookup_tables (u8 *s, va_list *args)
1800{
1801 u32 fib_proto = va_arg (*args, u32);
1802 u32 *fibs, num_fibs = 0, fib_index, indent;
1803 session_table_t *st;
1804 u64 total_mem = 0;
1805
1806 fibs = fib_index_to_table_index[fib_proto];
1807
1808 for (fib_index = 0; fib_index < vec_len (fibs); fib_index++)
1809 {
1810 if (fibs[fib_index] == ~0)
1811 continue;
1812
1813 num_fibs += 1;
1814 st = session_table_get (fibs[fib_index]);
1815 total_mem += session_table_memory_size (st);
1816 }
1817
1818 indent = format_get_indent (s);
1819 s = format (s, "active fibs:\t%u\n", num_fibs);
1820 s = format (s, "%Umax fib-index:\t%u\n", format_white_space, indent,
1821 vec_len (fibs) - 1);
1822 s = format (s, "%Utable memory:\t%U\n", format_white_space, indent,
1823 format_memory_size, total_mem);
1824 s = format (s, "%Uvec memory:\t%U\n", format_white_space, indent,
1825 format_memory_size, vec_mem_size (fibs));
1826
1827 return s;
1828}
1829
1830static clib_error_t *
1831show_session_lookup_command_fn (vlib_main_t *vm, unformat_input_t *input,
1832 vlib_cli_command_t *cmd)
1833{
1834 session_table_t *st;
1835 u32 fib_index = ~0;
1836
1837 session_cli_return_if_not_enabled ();
1838 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1839 {
1840 if (unformat (input, "table %u", &fib_index))
1841 ;
1842 else
1843 return clib_error_return (0, "unknown input `%U'",
1844 format_unformat_error, input);
1845 }
1846
1847 if (fib_index != ~0)
1848 {
1849 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
1850 if (st)
1851 vlib_cli_output (vm, "%U", format_session_table, st);
1852 else
1853 vlib_cli_output (vm, "no ip4 table for fib-index %u", fib_index);
1854 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
1855 if (st)
1856 vlib_cli_output (vm, "%U", format_session_table, st);
1857 else
1858 vlib_cli_output (vm, "no ip6 table for fib-index %u", fib_index);
1859 goto done;
1860 }
1861
1862 vlib_cli_output (vm, "ip4 fib lookup tables:\n %U",
1863 format_session_lookup_tables, FIB_PROTOCOL_IP4);
1864 vlib_cli_output (vm, "ip6 fib lookup tables:\n %U",
1865 format_session_lookup_tables, FIB_PROTOCOL_IP6);
1866
1867done:
1868 return 0;
1869}
1870
1871VLIB_CLI_COMMAND (show_session_lookup_command, static) = {
1872 .path = "show session lookup",
1873 .short_help = "show session lookup [table <fib-index>]",
1874 .function = show_session_lookup_command_fn,
1875};
1876
Florin Coras04e53442017-07-16 17:12:15 -07001877void
1878session_lookup_init (void)
1879{
Florin Corasf9bdc032024-02-02 13:01:07 -08001880 session_lookup_main_t *slm = &sl_main;
1881
1882 clib_spinlock_init (&slm->st_alloc_lock);
1883
Steven Luong5682ca82024-07-17 16:16:05 -07001884 /* We are not contributing any route to the fib. But we allocate a fib source
1885 * so that when we lock the fib table, we can view that we have a lock on the
1886 * particular fib table in case we wonder why the fib table is not free after
1887 * "ip table del"
1888 */
1889 slm->fib_src = fib_source_allocate (
1890 "session lookup", FIB_SOURCE_PRIORITY_LOW, FIB_SOURCE_BH_SIMPLE);
1891
Florin Corascea194d2017-10-02 00:18:51 -07001892 /*
1893 * Allocate default table and map it to fib_index 0
1894 */
1895 session_table_t *st = session_table_alloc ();
1896 vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP4], 0);
1897 fib_index_to_table_index[FIB_PROTOCOL_IP4][0] = session_table_index (st);
Florin Coras6c36f532017-11-03 18:32:34 -07001898 st->active_fib_proto = FIB_PROTOCOL_IP4;
1899 session_table_init (st, FIB_PROTOCOL_IP4);
Florin Corascea194d2017-10-02 00:18:51 -07001900 st = session_table_alloc ();
1901 vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP6], 0);
1902 fib_index_to_table_index[FIB_PROTOCOL_IP6][0] = session_table_index (st);
Florin Coras6c36f532017-11-03 18:32:34 -07001903 st->active_fib_proto = FIB_PROTOCOL_IP6;
1904 session_table_init (st, FIB_PROTOCOL_IP6);
Florin Coras04e53442017-07-16 17:12:15 -07001905}
1906
Steven Luong5682ca82024-07-17 16:16:05 -07001907void
1908session_lookup_table_cleanup (u32 fib_proto, u32 fib_index)
1909{
1910 session_table_t *st;
1911 u32 table_index;
1912
1913 session_lookup_fib_table_unlock (fib_index, fib_proto);
1914 if (fib_index_to_lock_count[fib_proto][fib_index] == 0)
1915 {
1916 table_index = session_lookup_get_index_for_fib (fib_proto, fib_index);
1917 st = session_table_get (table_index);
1918 if (st)
1919 {
1920 session_table_free (st, fib_proto);
1921 if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index)
1922 fib_index_to_table_index[fib_proto][fib_index] = ~0;
1923 }
1924 }
1925}
1926
Florin Coras04e53442017-07-16 17:12:15 -07001927/*
1928 * fd.io coding-style-patch-verification: ON
1929 *
1930 * Local Variables:
1931 * eval: (c-set-style "gnu")
1932 * End:
1933 */