blob: 9505ba1689f8b406521a0c598e1e63dda771765a [file] [log] [blame]
Steven Luongc4b5d102024-07-30 13:44:01 -07001/*
2 * Copyright (c) 2024 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <vnet/session/session.h>
17#include <vnet/ip/ip4_forward.h>
18#include <vnet/ip/ip6_forward.h>
19#include <vnet/session/session_rules_table.h>
20#include <vnet/session/session_sdl.h>
21
22VLIB_REGISTER_LOG_CLASS (session_sdl_log, static) = { .class_name = "session",
23 .subclass_name = "sdl" };
24
25#define log_debug(fmt, ...) \
26 vlib_log_debug (session_sdl_log.class, "%s: " fmt, __func__, __VA_ARGS__)
27#define log_warn(fmt, ...) \
28 vlib_log_warn (session_sdl_log.class, fmt, __VA_ARGS__)
29#define log_err(fmt, ...) \
30 vlib_log_err (session_sdl_log.class, fmt, __VA_ARGS__)
31
32static fib_source_t sdl_fib_src;
33static dpo_type_t sdl_dpo_type;
34
35const static char *const *const session_sdl_dpo_nodes[DPO_PROTO_NUM] = {
36 [DPO_PROTO_IP4] = (const char *const[]){ "ip4-drop", 0 },
37 [DPO_PROTO_IP6] = (const char *const[]){ "ip6-drop", 0 },
38};
39
40static fib_route_path_t *
41session_sdl_fib_create_route_paths (u32 fib_index, dpo_proto_t dpo_proto)
42{
43 fib_route_path_t *paths = 0;
44 fib_route_path_t path = {
45 .frp_proto = dpo_proto,
46 .frp_flags = FIB_ROUTE_PATH_EXCLUSIVE,
47 .frp_fib_index = fib_index,
48 .frp_sw_if_index = ~0,
49 .frp_weight = 1,
50 };
51 vec_add1 (paths, path);
52 return paths;
53}
54
55static void
56session_sdl_dpo_lock (dpo_id_t *dpo)
57{
58}
59
60static void
61session_sdl_dpo_unlock (dpo_id_t *dpo)
62{
63}
64
65static u8 *
66format_session_sdl_dpo (u8 *s, va_list *va)
67{
68 index_t index = va_arg (*va, index_t);
69
70 return format (s, "sdl: [index: %u, deny]", index);
71}
72
73static const dpo_vft_t session_sdl_dpo_vft = {
74 .dv_lock = session_sdl_dpo_lock,
75 .dv_unlock = session_sdl_dpo_unlock,
76 .dv_format = format_session_sdl_dpo,
77};
78
79static u32
80session_sdl_lookup6 (u32 srtg_handle, u32 proto, ip6_address_t *lcl_ip,
81 ip6_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
82{
83 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
84 session_sdl_block_t *sdlb = &srt->sdl_block;
85 index_t lbi;
86 const dpo_id_t *dpo;
87
88 if (sdlb->ip6_fib_index == ~0)
89 return SESSION_TABLE_INVALID_INDEX;
Steven Luong6f173172024-09-27 08:35:45 -070090 lbi = ip6_fib_table_fwding_lookup (sdlb->ip6_fib_index, rmt_ip);
Steven Luongc4b5d102024-07-30 13:44:01 -070091 dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
92 if (dpo->dpoi_type != sdl_dpo_type)
93 return SESSION_TABLE_INVALID_INDEX;
94 return (dpo->dpoi_index);
95}
96
97static u32
98session_sdl_lookup4 (u32 srtg_handle, u32 proto, ip4_address_t *lcl_ip,
99 ip4_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
100{
101 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
102 session_sdl_block_t *sdlb = &srt->sdl_block;
103 index_t lbi;
104 const dpo_id_t *dpo;
105
106 if (sdlb->ip_fib_index == ~0)
107 return SESSION_TABLE_INVALID_INDEX;
Steven Luong6f173172024-09-27 08:35:45 -0700108 lbi = ip4_fib_forwarding_lookup (sdlb->ip_fib_index, rmt_ip);
Steven Luongc4b5d102024-07-30 13:44:01 -0700109 dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
110 if (dpo->dpoi_type != sdl_dpo_type)
111 return SESSION_TABLE_INVALID_INDEX;
112 return (dpo->dpoi_index);
113}
114
115typedef struct session_sdl4_fib_show_walk_ctx_t_
116{
117 fib_node_index_t *ifsw_indicies;
118} session_sdl4_fib_show_walk_ctx_t;
119
120static fib_table_walk_rc_t
121session_sdl4_fib_show_walk_cb (fib_node_index_t fei, void *arg)
122{
123 session_sdl4_fib_show_walk_ctx_t *ctx = arg;
124
125 vec_add1 (ctx->ifsw_indicies, fei);
126
127 return (FIB_TABLE_WALK_CONTINUE);
128}
129
130typedef struct session_sdl6_fib_show_ctx_t_
131{
132 fib_node_index_t *entries;
133} session_sdl6_fib_show_ctx_t;
134
135static fib_table_walk_rc_t
136session_sdl6_fib_table_show_walk (fib_node_index_t fei, void *arg)
137{
138 session_sdl6_fib_show_ctx_t *ctx = arg;
139
140 vec_add1 (ctx->entries, fei);
141
142 return (FIB_TABLE_WALK_CONTINUE);
143}
144
145static void
Steven Luong6f173172024-09-27 08:35:45 -0700146session_sdl_fib_table_show (u32 fei, ip46_address_t *rmt_ip, u16 fp_len,
Steven Luongc4b5d102024-07-30 13:44:01 -0700147 u32 action_index, u32 fp_proto, u8 *tag,
148 void *args)
149{
150 vlib_main_t *vm = args;
151 u32 type = (fp_proto == FIB_PROTOCOL_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;
152
153 vlib_cli_output (vm, "[%d] rule: %U/%d action: %d tag %U", fei,
Steven Luong6f173172024-09-27 08:35:45 -0700154 format_ip46_address, rmt_ip, type, fp_len, action_index,
Steven Luongc4b5d102024-07-30 13:44:01 -0700155 format_session_rule_tag, tag);
156}
157
158static void
159session_sdl_cli_dump (vlib_main_t *vm, u32 srtg_handle, u32 proto,
160 u8 fib_proto)
161{
162 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
163 session_sdl_block_t *sdlb = &srt->sdl_block;
164
165 if (fib_proto == FIB_PROTOCOL_IP4)
166 {
167 vlib_cli_output (vm, "IP4 rules, fib index %d", sdlb->ip_fib_index);
168 session_sdl_table_walk4 (srtg_handle, session_sdl_fib_table_show, vm);
169 }
170 else if (fib_proto == FIB_PROTOCOL_IP6)
171 {
172 vlib_cli_output (vm, "IP6 rules, fib index %d", sdlb->ip6_fib_index);
173 session_sdl_table_walk6 (srtg_handle, session_sdl_fib_table_show, vm);
174 }
175}
176
177static void
178session_sdl4_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
179 vlib_main_t *vm, ip4_address_t *address,
180 u32 mask_len)
181{
182 ip4_fib_t *fib;
183 fib_node_index_t fei;
184
185 fib = ip4_fib_get (fib_index);
186 fei = ip4_fib_table_lookup (fib, address, mask_len);
187 if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
188 {
189 u8 *tag = session_rules_table_rule_tag (srt, fei, 1);
190 fib_entry_t *fib_entry = fib_entry_get (fei);
191 fib_prefix_t pfx = fib_entry->fe_prefix;
192 index_t lbi = ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
193 const dpo_id_t *dpo =
194 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
195
196 session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
197 dpo->dpoi_index, FIB_PROTOCOL_IP4, tag, vm);
198 }
199}
200
201static void
202session_sdl6_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
203 vlib_main_t *vm, ip6_address_t *address,
204 u32 mask_len)
205{
206 fib_node_index_t fei;
207
208 fei = ip6_fib_table_lookup (fib_index, address, mask_len);
209 if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
210 {
211 u8 *tag = session_rules_table_rule_tag (srt, fei, 0);
212 fib_entry_t *fib_entry = fib_entry_get (fei);
213 fib_prefix_t pfx = fib_entry->fe_prefix;
214 index_t lbi = ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
215 const dpo_id_t *dpo =
216 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
217
218 session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
219 dpo->dpoi_index, FIB_PROTOCOL_IP6, tag, vm);
220 }
221}
222
223static void
224session_sdl_show_rule (vlib_main_t *vm, u32 srtg_handle, u32 proto,
225 ip46_address_t *lcl_ip, u16 lcl_port,
226 ip46_address_t *rmt_ip, u16 rmt_port, u8 is_ip4)
227{
228 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
229 session_sdl_block_t *sdlb;
230
231 sdlb = &srt->sdl_block;
232 if (is_ip4)
Steven Luong6f173172024-09-27 08:35:45 -0700233 session_sdl4_fib_table_show_one (srt, sdlb->ip_fib_index, vm, &rmt_ip->ip4,
Steven Luongc4b5d102024-07-30 13:44:01 -0700234 32);
235 else
236 session_sdl6_fib_table_show_one (srt, sdlb->ip6_fib_index, vm,
Steven Luong6f173172024-09-27 08:35:45 -0700237 &rmt_ip->ip6, 128);
Steven Luongc4b5d102024-07-30 13:44:01 -0700238}
239
240static void
241session_sdl_table_init (session_table_t *st, u8 fib_proto)
242{
243 session_rules_table_t *srt;
244 session_sdl_block_t *sdlb;
245 u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
246 char name[80];
247 app_namespace_t *app_ns = app_namespace_get (st->appns_index);
248 session_rules_table_group_t *srtg;
249
250 /* Don't support local table */
251 if (st->is_local == 1)
252 return;
253
254 srtg = srtg_instance_alloc (st, 0);
255 srt = srtg->session_rules;
256 sdlb = &srt->sdl_block;
257
258 if (fib_proto == FIB_PROTOCOL_IP4 || all)
259 {
260 snprintf (name, sizeof (name), "sdl4 %s", app_ns->ns_id);
261 sdlb->ip_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP4);
262 sdlb->ip_fib_index = fib_table_find_or_create_and_lock_w_name (
263 FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdl_fib_src, (const u8 *) name);
264 }
265
266 if (fib_proto == FIB_PROTOCOL_IP6 || all)
267 {
268 snprintf (name, sizeof (name), "sdl6 %s", app_ns->ns_id);
269 sdlb->ip6_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP6);
270 sdlb->ip6_fib_index = fib_table_find_or_create_and_lock_w_name (
271 FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdl_fib_src, (const u8 *) name);
272 }
273
274 srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
275 srt->tags_by_rules = hash_create (0, sizeof (uword));
276}
277
278static void
279session_sdl_table_free (session_table_t *st, u8 fib_proto)
280{
281 session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, 0);
282 session_sdl_block_t *sdlb;
283 u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
284
285 ASSERT (st->is_local == 0);
286 sdlb = &srt->sdl_block;
287 if ((fib_proto == FIB_PROTOCOL_IP4 || all) && (sdlb->ip_fib_index != ~0))
288 {
289 fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
290 fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
291 }
292 if ((fib_proto == FIB_PROTOCOL_IP6 || all) && (sdlb->ip6_fib_index != ~0))
293 {
294 fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
295 fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
296 }
297
298 hash_free (srt->tags_by_rules);
299 hash_free (srt->rules_by_tag);
300
301 srtg_instance_free (st);
302}
303
304static session_error_t
305session_sdl_add_del (u32 srtg_handle, u32 proto,
306 session_rule_table_add_del_args_t *args)
307{
308 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
309 session_sdl_block_t *sdlb = &srt->sdl_block;
310 u32 fib_index;
311 dpo_proto_t dpo_proto;
312 fib_route_path_t *paths = 0;
Steven Luong6f173172024-09-27 08:35:45 -0700313 fib_prefix_t pfx = args->rmt;
Steven Luongc4b5d102024-07-30 13:44:01 -0700314 session_error_t err = SESSION_E_NONE;
315 fib_node_index_t fei;
316 int is_ip4;
317
Steven Luongc4b5d102024-07-30 13:44:01 -0700318 fei = session_rules_table_rule_for_tag (srt, args->tag);
319 if (args->is_add && fei != SESSION_RULES_TABLE_INVALID_INDEX)
320 return SESSION_E_INVALID;
321
Steven Luong6f173172024-09-27 08:35:45 -0700322 if (args->rmt.fp_proto == FIB_PROTOCOL_IP4)
Steven Luongc4b5d102024-07-30 13:44:01 -0700323 {
324 fib_index = sdlb->ip_fib_index;
325 dpo_proto = DPO_PROTO_IP4;
326 is_ip4 = 1;
327 }
328 else
329 {
330 fib_index = sdlb->ip6_fib_index;
331 dpo_proto = DPO_PROTO_IP6;
332 is_ip4 = 0;
333 }
334
335 paths = session_sdl_fib_create_route_paths (fib_index, dpo_proto);
336 if (args->is_add)
337 {
338 fei = fib_table_lookup_exact_match (fib_index, &pfx);
339 if (fei != FIB_NODE_INDEX_INVALID)
340 {
341 err = SESSION_E_IPINUSE;
342 goto done;
343 }
344 dpo_set (&paths->dpo, sdl_dpo_type, dpo_proto, args->action_index);
345 fei = fib_table_entry_path_add2 (fib_index, &pfx, sdl_fib_src,
346 FIB_ENTRY_FLAG_EXCLUSIVE, paths);
347 session_rules_table_add_tag (srt, args->tag, fei, is_ip4);
348 dpo_reset (&paths->dpo);
349 }
350 else
351 {
352 if (fei == SESSION_RULES_TABLE_INVALID_INDEX)
353 {
354 fei = fib_table_lookup_exact_match (fib_index, &pfx);
355
356 if (fei == FIB_NODE_INDEX_INVALID)
357 {
358 err = SESSION_E_NOROUTE;
359 goto done;
360 }
361 }
362
363 if (!fib_entry_is_sourced (fei, sdl_fib_src))
364 {
365 err = SESSION_E_NOROUTE;
366 goto done;
367 }
368
369 fib_entry_t *fib_entry = fib_entry_get (fei);
370 pfx = fib_entry->fe_prefix;
371 fib_table_entry_special_remove (fib_index, &pfx, sdl_fib_src);
372 session_rules_table_del_tag (srt, args->tag, is_ip4);
373 }
374done:
375 vec_free (paths);
376
377 return err;
378}
379
380static const session_rt_engine_vft_t session_sdl_vft = {
381 .backend_engine = RT_BACKEND_ENGINE_SDL,
382 .table_lookup4 = session_sdl_lookup4,
383 .table_lookup6 = session_sdl_lookup6,
384 .table_cli_dump = session_sdl_cli_dump,
385 .table_show_rule = session_sdl_show_rule,
386 .table_add_del = session_sdl_add_del,
387 .table_init = session_sdl_table_init,
388 .table_free = session_sdl_table_free,
389};
390
391static void
392session_sdl_fib_init (void)
393{
394 static u32 session_fib_inited = 0;
395
396 if (session_fib_inited)
397 return;
398 session_fib_inited = 1;
399 sdl_fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW,
400 FIB_SOURCE_BH_SIMPLE);
401 sdl_dpo_type =
402 dpo_register_new_type (&session_sdl_dpo_vft, session_sdl_dpo_nodes);
403}
404
405static void
406session_sdl_app_namespace_walk_cb (app_namespace_t *app_ns, void *ctx)
407{
408 u32 fib_index, table_index;
409 session_table_t *st;
410
411 log_debug ("disable app_ns %s", app_ns->ns_id);
412
413 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
414 table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, fib_index);
415 st = session_table_get (table_index);
416 if (st)
417 session_rules_table_free (st, FIB_PROTOCOL_IP4);
418
419 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
420 table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, fib_index);
421 st = session_table_get (table_index);
422 if (st)
423 session_rules_table_free (st, FIB_PROTOCOL_IP6);
424}
425
426clib_error_t *
427session_sdl_enable_disable (int enable)
428{
429 clib_error_t *error = 0;
430
431 if (enable)
432 {
433 error = session_rule_table_register_engine (&session_sdl_vft);
434 if (error)
435 {
436 log_err ("error in enabling sdl: %U", format_clib_error, error);
437 return error;
438 }
439 session_sdl_fib_init ();
440 }
441 else
442 {
443 app_namespace_walk (session_sdl_app_namespace_walk_cb, 0);
444
445 error = session_rule_table_deregister_engine (&session_sdl_vft);
446 if (error)
447 log_err ("error in disabling sdl: %U", format_clib_error, error);
448 }
449
450 return error;
451}
452
453/*
454 * Source Deny List
455 */
456static clib_error_t *
457session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
458 vlib_cli_command_t *cmd)
459{
460 u32 appns_index;
461 app_namespace_t *app_ns;
Steven Luong6f173172024-09-27 08:35:45 -0700462 u32 rmt_plen = 0, action = 0;
Steven Luongc4b5d102024-07-30 13:44:01 -0700463 clib_error_t *error = 0;
Steven Luong6f173172024-09-27 08:35:45 -0700464 ip46_address_t rmt_ip;
Steven Luongc4b5d102024-07-30 13:44:01 -0700465 u8 conn_set = 0;
466 u8 fib_proto = -1, is_add = 1, *ns_id = 0;
467 u8 *tag = 0, tag_only = 0;
468 int rv;
469 session_rule_add_del_args_t args;
470
471 session_cli_return_if_not_enabled ();
472
473 if (session_sdl_is_enabled () == 0)
474 return clib_error_return (0, "session sdl engine is not enabled");
475
476 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
477 {
478 if (unformat (input, "del"))
479 is_add = 0;
480 else if (unformat (input, "add"))
481 ;
482 else if (unformat (input, "appns %_%v%_", &ns_id))
483 ;
Steven Luong6f173172024-09-27 08:35:45 -0700484 else if (unformat (input, "%U/%d", unformat_ip4_address, &rmt_ip.ip4,
485 &rmt_plen))
Steven Luongc4b5d102024-07-30 13:44:01 -0700486 {
487 fib_proto = FIB_PROTOCOL_IP4;
488 conn_set = 1;
489 }
Steven Luong6f173172024-09-27 08:35:45 -0700490 else if (unformat (input, "%U/%d", unformat_ip6_address, &rmt_ip.ip6,
491 &rmt_plen))
Steven Luongc4b5d102024-07-30 13:44:01 -0700492 {
493 fib_proto = FIB_PROTOCOL_IP6;
494 conn_set = 1;
495 }
496 else if (unformat (input, "action %d", &action))
497 ;
498 else if (unformat (input, "tag %_%v%_", &tag))
499 ;
500 else
501 {
502 error = clib_error_return (0, "unknown input `%U'",
503 format_unformat_error, input);
504 goto done;
505 }
506 }
507
508 if (ns_id)
509 {
510 app_ns = app_namespace_get_from_id (ns_id);
511 if (!app_ns)
512 {
513 vlib_cli_output (vm, "namespace %v does not exist", ns_id);
514 goto done;
515 }
516 }
517 else
518 {
519 app_ns = app_namespace_get_default ();
520 }
521 appns_index = app_namespace_index (app_ns);
522
523 if (is_add && !conn_set && action == 0)
524 {
525 vlib_cli_output (vm, "connection and action must be set for add");
526 goto done;
527 }
528 if (!is_add && !tag && !conn_set)
529 {
530 vlib_cli_output (vm, "connection or tag must be set for delete");
531 goto done;
532 }
533 if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
534 {
535 vlib_cli_output (vm, "tag too long (max u64)");
536 goto done;
537 }
538
539 /* Delete with only tag entered. Try v4 first and then v6 if failed */
540 if ((is_add == 0) && (fib_proto == (u8) ~0))
541 {
542 fib_proto = FIB_PROTOCOL_IP4;
543 tag_only = 1;
544 }
545
546 memset (&args, 0, sizeof (args));
547 args.transport_proto = TRANSPORT_PROTO_TCP;
Steven Luong6f173172024-09-27 08:35:45 -0700548 args.table_args.rmt.fp_addr = rmt_ip;
549 args.table_args.rmt.fp_len = rmt_plen;
Steven Luongc4b5d102024-07-30 13:44:01 -0700550 args.table_args.rmt.fp_proto = fib_proto;
551 args.table_args.action_index = action;
552 args.table_args.is_add = is_add;
553 args.table_args.tag = tag;
554 args.appns_index = appns_index;
555 args.scope = SESSION_RULE_SCOPE_GLOBAL;
556
557 if ((rv = vnet_session_rule_add_del (&args)))
558 {
559 /* Try tag only delete on v6 */
560 if (rv && tag_only)
561 {
562 args.table_args.rmt.fp_proto = FIB_PROTOCOL_IP6;
563 args.table_args.lcl.fp_proto = FIB_PROTOCOL_IP6;
564 if ((rv = vnet_session_rule_add_del (&args)))
565 {
566 error = clib_error_return (0, "sdl add del returned %u", rv);
567 }
568 }
569 else
570 {
571 error = clib_error_return (0, "sdl add del returned %u", rv);
572 }
573 }
574
575done:
576 vec_free (ns_id);
577 vec_free (tag);
578 return error;
579}
580
581VLIB_CLI_COMMAND (session_sdl_command, static) = {
582 .path = "session sdl",
Steven Luong6f173172024-09-27 08:35:45 -0700583 .short_help = "session sdl [add|del] [appns <ns_id>] <rmt-ip/plen> action "
Steven Luongc4b5d102024-07-30 13:44:01 -0700584 "<action> [tag <tag>]",
585 .function = session_sdl_command_fn,
586 .is_mp_safe = 1,
587};
588
589static clib_error_t *
590show_session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
591 vlib_cli_command_t *cmd)
592{
593 u32 fib_index;
Steven Luong6f173172024-09-27 08:35:45 -0700594 ip46_address_t rmt_ip;
Steven Luongc4b5d102024-07-30 13:44:01 -0700595 u8 show_one = 0;
596 app_namespace_t *app_ns;
597 session_table_t *st;
598 u8 *ns_id = 0, fib_proto = FIB_PROTOCOL_IP4;
599
600 session_cli_return_if_not_enabled ();
601
Steven Luong6f173172024-09-27 08:35:45 -0700602 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Steven Luongc4b5d102024-07-30 13:44:01 -0700603 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
604 {
605 if (unformat (input, "appns %_%s%_", &ns_id))
606 ;
Steven Luong6f173172024-09-27 08:35:45 -0700607 else if (unformat (input, "%U", unformat_ip4_address, &rmt_ip.ip4))
Steven Luongc4b5d102024-07-30 13:44:01 -0700608 {
609 fib_proto = FIB_PROTOCOL_IP4;
610 show_one = 1;
611 }
Steven Luong6f173172024-09-27 08:35:45 -0700612 else if (unformat (input, "%U", unformat_ip6_address, &rmt_ip.ip6))
Steven Luongc4b5d102024-07-30 13:44:01 -0700613 {
614 fib_proto = FIB_PROTOCOL_IP6;
615 show_one = 1;
616 }
617 else
618 {
619 vec_free (ns_id);
620 return clib_error_return (0, "unknown input `%U'",
621 format_unformat_error, input);
622 }
623 }
624
625 if (ns_id)
626 {
627 app_ns = app_namespace_get_from_id (ns_id);
628 if (!app_ns)
629 {
630 vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
631 goto done;
632 }
633 }
634 else
635 {
636 app_ns = app_namespace_get_default ();
637 }
638
639 if (session_sdl_is_enabled () == 0)
640 {
641 vlib_cli_output (vm, "session sdl engine is not enabled");
642 goto done;
643 }
644
645 if (show_one)
646 {
647 fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
648 st = session_table_get_for_fib_index (fib_proto, fib_index);
649 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
Steven Luong6f173172024-09-27 08:35:45 -0700650 session_rules_table_show_rule (vm, st->srtg_handle, 0, &rmt_ip, 0, 0,
Steven Luongc4b5d102024-07-30 13:44:01 -0700651 0, (fib_proto == FIB_PROTOCOL_IP4));
652 goto done;
653 }
654
655 /* 2 separate session tables for global entries, 1 for ip4 and 1 for ip6 */
656 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
657 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
658 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
659 session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP4);
660
661 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
662 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
663 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
664 session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP6);
665done:
666 vec_free (ns_id);
667 return 0;
668}
669
670void
671session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
672 void *args)
673{
674 ip4_fib_t *fib;
675 session_sdl4_fib_show_walk_ctx_t ctx = {
676 .ifsw_indicies = NULL,
677 };
678 fib_node_index_t *fei;
679 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
680 session_sdl_block_t *sdlb = &srt->sdl_block;
681 u32 fib_index = sdlb->ip_fib_index;
682
683 if (fib_index == ~0)
684 return;
685 fib = ip4_fib_get (fib_index);
686 ip4_fib_table_walk (fib, session_sdl4_fib_show_walk_cb, &ctx);
687 vec_sort_with_function (ctx.ifsw_indicies, fib_entry_cmp_for_sort);
688
689 vec_foreach (fei, ctx.ifsw_indicies)
690 {
691 if (*fei != FIB_NODE_INDEX_INVALID &&
692 fib_entry_is_sourced (*fei, sdl_fib_src))
693 {
694 u8 *tag = session_rules_table_rule_tag (srt, *fei, 1);
695 fib_entry_t *fib_entry = fib_entry_get (*fei);
696 fib_prefix_t pfx = fib_entry->fe_prefix;
697 index_t lbi =
698 ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
699 const dpo_id_t *dpo =
700 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
701
702 fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
703 FIB_PROTOCOL_IP4, tag, args);
704 }
705 }
706
707 vec_free (ctx.ifsw_indicies);
708}
709
710void
711session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
712 void *args)
713{
714 ip6_fib_t *fib;
715 fib_node_index_t *fei;
716 session_sdl6_fib_show_ctx_t ctx = {
717 .entries = NULL,
718 };
719 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
720 session_sdl_block_t *sdlb = &srt->sdl_block;
721 u32 fib_index = sdlb->ip6_fib_index;
722
723 if (fib_index == ~0)
724 return;
725 fib = ip6_fib_get (fib_index);
726 ip6_fib_table_walk (fib->index, session_sdl6_fib_table_show_walk, &ctx);
727 vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);
728
729 vec_foreach (fei, ctx.entries)
730 {
731 if (*fei != FIB_NODE_INDEX_INVALID &&
732 fib_entry_is_sourced (*fei, sdl_fib_src))
733 {
734 u8 *tag = session_rules_table_rule_tag (srt, *fei, 0);
735 fib_entry_t *fib_entry = fib_entry_get (*fei);
736 fib_prefix_t pfx = fib_entry->fe_prefix;
737 index_t lbi =
738 ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
739 const dpo_id_t *dpo =
740 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
741
742 fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
743 FIB_PROTOCOL_IP6, tag, args);
744 }
745 }
746
747 vec_free (ctx.entries);
748}
749
750VLIB_CLI_COMMAND (show_session_sdl_command, static) = {
751 .path = "show session sdl",
Steven Luong6f173172024-09-27 08:35:45 -0700752 .short_help = "show session sdl [appns <id> <rmt-ip>]",
Steven Luongc4b5d102024-07-30 13:44:01 -0700753 .function = show_session_sdl_command_fn,
754 .is_mp_safe = 1,
755};
756
757/*
758 * fd.io coding-style-patch-verification: ON
759 *
760 * Local Variables:
761 * eval: (c-set-style "gnu")
762 * End:
763 */