blob: f1dfac4e1ab0122f125ed7a39ee10dcae86ebf09 [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];
Steven Luonge0c4e6e2024-10-22 10:44:07 -0700247 u32 appns_index;
248 app_namespace_t *app_ns;
Steven Luongc4b5d102024-07-30 13:44:01 -0700249 session_rules_table_group_t *srtg;
250
251 /* Don't support local table */
252 if (st->is_local == 1)
253 return;
254
Steven Luonge0c4e6e2024-10-22 10:44:07 -0700255 appns_index =
256 *vec_elt_at_index (st->appns_index, vec_len (st->appns_index) - 1);
257 app_ns = app_namespace_get (appns_index);
Steven Luongc4b5d102024-07-30 13:44:01 -0700258 srtg = srtg_instance_alloc (st, 0);
259 srt = srtg->session_rules;
260 sdlb = &srt->sdl_block;
261
262 if (fib_proto == FIB_PROTOCOL_IP4 || all)
263 {
264 snprintf (name, sizeof (name), "sdl4 %s", app_ns->ns_id);
265 sdlb->ip_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP4);
266 sdlb->ip_fib_index = fib_table_find_or_create_and_lock_w_name (
267 FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdl_fib_src, (const u8 *) name);
268 }
269
270 if (fib_proto == FIB_PROTOCOL_IP6 || all)
271 {
272 snprintf (name, sizeof (name), "sdl6 %s", app_ns->ns_id);
273 sdlb->ip6_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP6);
274 sdlb->ip6_fib_index = fib_table_find_or_create_and_lock_w_name (
275 FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdl_fib_src, (const u8 *) name);
276 }
277
278 srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
279 srt->tags_by_rules = hash_create (0, sizeof (uword));
280}
281
282static void
283session_sdl_table_free (session_table_t *st, u8 fib_proto)
284{
285 session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, 0);
286 session_sdl_block_t *sdlb;
287 u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
288
289 ASSERT (st->is_local == 0);
290 sdlb = &srt->sdl_block;
291 if ((fib_proto == FIB_PROTOCOL_IP4 || all) && (sdlb->ip_fib_index != ~0))
292 {
293 fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
294 fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
295 }
296 if ((fib_proto == FIB_PROTOCOL_IP6 || all) && (sdlb->ip6_fib_index != ~0))
297 {
298 fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
299 fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
300 }
301
302 hash_free (srt->tags_by_rules);
303 hash_free (srt->rules_by_tag);
304
305 srtg_instance_free (st);
306}
307
308static session_error_t
309session_sdl_add_del (u32 srtg_handle, u32 proto,
310 session_rule_table_add_del_args_t *args)
311{
312 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
313 session_sdl_block_t *sdlb = &srt->sdl_block;
314 u32 fib_index;
315 dpo_proto_t dpo_proto;
316 fib_route_path_t *paths = 0;
Steven Luong6f173172024-09-27 08:35:45 -0700317 fib_prefix_t pfx = args->rmt;
Steven Luongc4b5d102024-07-30 13:44:01 -0700318 session_error_t err = SESSION_E_NONE;
319 fib_node_index_t fei;
320 int is_ip4;
321
Steven Luongc4b5d102024-07-30 13:44:01 -0700322 fei = session_rules_table_rule_for_tag (srt, args->tag);
323 if (args->is_add && fei != SESSION_RULES_TABLE_INVALID_INDEX)
324 return SESSION_E_INVALID;
325
Steven Luong6f173172024-09-27 08:35:45 -0700326 if (args->rmt.fp_proto == FIB_PROTOCOL_IP4)
Steven Luongc4b5d102024-07-30 13:44:01 -0700327 {
328 fib_index = sdlb->ip_fib_index;
329 dpo_proto = DPO_PROTO_IP4;
330 is_ip4 = 1;
331 }
332 else
333 {
334 fib_index = sdlb->ip6_fib_index;
335 dpo_proto = DPO_PROTO_IP6;
336 is_ip4 = 0;
337 }
338
339 paths = session_sdl_fib_create_route_paths (fib_index, dpo_proto);
340 if (args->is_add)
341 {
342 fei = fib_table_lookup_exact_match (fib_index, &pfx);
343 if (fei != FIB_NODE_INDEX_INVALID)
344 {
345 err = SESSION_E_IPINUSE;
346 goto done;
347 }
348 dpo_set (&paths->dpo, sdl_dpo_type, dpo_proto, args->action_index);
349 fei = fib_table_entry_path_add2 (fib_index, &pfx, sdl_fib_src,
350 FIB_ENTRY_FLAG_EXCLUSIVE, paths);
351 session_rules_table_add_tag (srt, args->tag, fei, is_ip4);
352 dpo_reset (&paths->dpo);
353 }
354 else
355 {
356 if (fei == SESSION_RULES_TABLE_INVALID_INDEX)
357 {
358 fei = fib_table_lookup_exact_match (fib_index, &pfx);
359
360 if (fei == FIB_NODE_INDEX_INVALID)
361 {
362 err = SESSION_E_NOROUTE;
363 goto done;
364 }
365 }
366
367 if (!fib_entry_is_sourced (fei, sdl_fib_src))
368 {
369 err = SESSION_E_NOROUTE;
370 goto done;
371 }
372
373 fib_entry_t *fib_entry = fib_entry_get (fei);
374 pfx = fib_entry->fe_prefix;
375 fib_table_entry_special_remove (fib_index, &pfx, sdl_fib_src);
376 session_rules_table_del_tag (srt, args->tag, is_ip4);
377 }
378done:
379 vec_free (paths);
380
381 return err;
382}
383
384static const session_rt_engine_vft_t session_sdl_vft = {
385 .backend_engine = RT_BACKEND_ENGINE_SDL,
386 .table_lookup4 = session_sdl_lookup4,
387 .table_lookup6 = session_sdl_lookup6,
388 .table_cli_dump = session_sdl_cli_dump,
389 .table_show_rule = session_sdl_show_rule,
390 .table_add_del = session_sdl_add_del,
391 .table_init = session_sdl_table_init,
392 .table_free = session_sdl_table_free,
393};
394
395static void
396session_sdl_fib_init (void)
397{
398 static u32 session_fib_inited = 0;
399
400 if (session_fib_inited)
401 return;
402 session_fib_inited = 1;
403 sdl_fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW,
404 FIB_SOURCE_BH_SIMPLE);
405 sdl_dpo_type =
406 dpo_register_new_type (&session_sdl_dpo_vft, session_sdl_dpo_nodes);
407}
408
409static void
410session_sdl_app_namespace_walk_cb (app_namespace_t *app_ns, void *ctx)
411{
412 u32 fib_index, table_index;
413 session_table_t *st;
414
415 log_debug ("disable app_ns %s", app_ns->ns_id);
416
417 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
418 table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, fib_index);
419 st = session_table_get (table_index);
420 if (st)
421 session_rules_table_free (st, FIB_PROTOCOL_IP4);
422
423 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
424 table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, fib_index);
425 st = session_table_get (table_index);
426 if (st)
427 session_rules_table_free (st, FIB_PROTOCOL_IP6);
428}
429
430clib_error_t *
431session_sdl_enable_disable (int enable)
432{
433 clib_error_t *error = 0;
434
435 if (enable)
436 {
437 error = session_rule_table_register_engine (&session_sdl_vft);
438 if (error)
439 {
440 log_err ("error in enabling sdl: %U", format_clib_error, error);
441 return error;
442 }
443 session_sdl_fib_init ();
444 }
445 else
446 {
447 app_namespace_walk (session_sdl_app_namespace_walk_cb, 0);
448
449 error = session_rule_table_deregister_engine (&session_sdl_vft);
450 if (error)
451 log_err ("error in disabling sdl: %U", format_clib_error, error);
452 }
453
454 return error;
455}
456
457/*
458 * Source Deny List
459 */
460static clib_error_t *
461session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
462 vlib_cli_command_t *cmd)
463{
464 u32 appns_index;
465 app_namespace_t *app_ns;
Steven Luong6f173172024-09-27 08:35:45 -0700466 u32 rmt_plen = 0, action = 0;
Steven Luong6f173172024-09-27 08:35:45 -0700467 ip46_address_t rmt_ip;
Steven Luongc4b5d102024-07-30 13:44:01 -0700468 u8 conn_set = 0;
469 u8 fib_proto = -1, is_add = 1, *ns_id = 0;
Steven Luong2c52f5e2024-10-02 09:35:33 -0700470 u8 *tag = 0;
Steven Luongc4b5d102024-07-30 13:44:01 -0700471 int rv;
472 session_rule_add_del_args_t args;
473
Steven Luongc4b5d102024-07-30 13:44:01 -0700474 if (session_sdl_is_enabled () == 0)
Steven Luong2c52f5e2024-10-02 09:35:33 -0700475 {
476 vlib_cli_output (vm, "session sdl engine is not enabled");
477 unformat_skip_line (input);
478 goto done;
479 }
Steven Luongc4b5d102024-07-30 13:44:01 -0700480
481 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
482 {
483 if (unformat (input, "del"))
484 is_add = 0;
485 else if (unformat (input, "add"))
486 ;
487 else if (unformat (input, "appns %_%v%_", &ns_id))
488 ;
Steven Luong6f173172024-09-27 08:35:45 -0700489 else if (unformat (input, "%U/%d", unformat_ip4_address, &rmt_ip.ip4,
490 &rmt_plen))
Steven Luongc4b5d102024-07-30 13:44:01 -0700491 {
492 fib_proto = FIB_PROTOCOL_IP4;
493 conn_set = 1;
494 }
Steven Luong6f173172024-09-27 08:35:45 -0700495 else if (unformat (input, "%U/%d", unformat_ip6_address, &rmt_ip.ip6,
496 &rmt_plen))
Steven Luongc4b5d102024-07-30 13:44:01 -0700497 {
498 fib_proto = FIB_PROTOCOL_IP6;
499 conn_set = 1;
500 }
501 else if (unformat (input, "action %d", &action))
502 ;
503 else if (unformat (input, "tag %_%v%_", &tag))
504 ;
505 else
506 {
Steven Luong2c52f5e2024-10-02 09:35:33 -0700507 vlib_cli_output (vm, "unknown input `%U'", format_unformat_error,
508 input);
Steven Luongc4b5d102024-07-30 13:44:01 -0700509 goto done;
510 }
511 }
512
513 if (ns_id)
514 {
515 app_ns = app_namespace_get_from_id (ns_id);
516 if (!app_ns)
517 {
518 vlib_cli_output (vm, "namespace %v does not exist", ns_id);
519 goto done;
520 }
521 }
522 else
523 {
524 app_ns = app_namespace_get_default ();
525 }
526 appns_index = app_namespace_index (app_ns);
527
528 if (is_add && !conn_set && action == 0)
529 {
530 vlib_cli_output (vm, "connection and action must be set for add");
531 goto done;
532 }
533 if (!is_add && !tag && !conn_set)
534 {
535 vlib_cli_output (vm, "connection or tag must be set for delete");
536 goto done;
537 }
538 if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
539 {
540 vlib_cli_output (vm, "tag too long (max u64)");
541 goto done;
542 }
543
Steven Luongc4b5d102024-07-30 13:44:01 -0700544 memset (&args, 0, sizeof (args));
545 args.transport_proto = TRANSPORT_PROTO_TCP;
Steven Luong6f173172024-09-27 08:35:45 -0700546 args.table_args.rmt.fp_addr = rmt_ip;
547 args.table_args.rmt.fp_len = rmt_plen;
Steven Luongc4b5d102024-07-30 13:44:01 -0700548 args.table_args.rmt.fp_proto = fib_proto;
549 args.table_args.action_index = action;
550 args.table_args.is_add = is_add;
551 args.table_args.tag = tag;
552 args.appns_index = appns_index;
553 args.scope = SESSION_RULE_SCOPE_GLOBAL;
554
555 if ((rv = vnet_session_rule_add_del (&args)))
Steven Luong2c52f5e2024-10-02 09:35:33 -0700556 vlib_cli_output (vm, "sdl add del returned %d", rv);
Steven Luongc4b5d102024-07-30 13:44:01 -0700557
558done:
559 vec_free (ns_id);
560 vec_free (tag);
Steven Luong2c52f5e2024-10-02 09:35:33 -0700561 return 0;
Steven Luongc4b5d102024-07-30 13:44:01 -0700562}
563
564VLIB_CLI_COMMAND (session_sdl_command, static) = {
565 .path = "session sdl",
Steven Luong6f173172024-09-27 08:35:45 -0700566 .short_help = "session sdl [add|del] [appns <ns_id>] <rmt-ip/plen> action "
Steven Luongc4b5d102024-07-30 13:44:01 -0700567 "<action> [tag <tag>]",
568 .function = session_sdl_command_fn,
569 .is_mp_safe = 1,
570};
571
572static clib_error_t *
573show_session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
574 vlib_cli_command_t *cmd)
575{
576 u32 fib_index;
Steven Luong6f173172024-09-27 08:35:45 -0700577 ip46_address_t rmt_ip;
Steven Luongc4b5d102024-07-30 13:44:01 -0700578 u8 show_one = 0;
579 app_namespace_t *app_ns;
580 session_table_t *st;
581 u8 *ns_id = 0, fib_proto = FIB_PROTOCOL_IP4;
582
583 session_cli_return_if_not_enabled ();
584
Steven Luong6f173172024-09-27 08:35:45 -0700585 clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
Steven Luongc4b5d102024-07-30 13:44:01 -0700586 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
587 {
588 if (unformat (input, "appns %_%s%_", &ns_id))
589 ;
Steven Luong6f173172024-09-27 08:35:45 -0700590 else if (unformat (input, "%U", unformat_ip4_address, &rmt_ip.ip4))
Steven Luongc4b5d102024-07-30 13:44:01 -0700591 {
592 fib_proto = FIB_PROTOCOL_IP4;
593 show_one = 1;
594 }
Steven Luong6f173172024-09-27 08:35:45 -0700595 else if (unformat (input, "%U", unformat_ip6_address, &rmt_ip.ip6))
Steven Luongc4b5d102024-07-30 13:44:01 -0700596 {
597 fib_proto = FIB_PROTOCOL_IP6;
598 show_one = 1;
599 }
600 else
601 {
602 vec_free (ns_id);
603 return clib_error_return (0, "unknown input `%U'",
604 format_unformat_error, input);
605 }
606 }
607
608 if (ns_id)
609 {
610 app_ns = app_namespace_get_from_id (ns_id);
611 if (!app_ns)
612 {
613 vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
614 goto done;
615 }
616 }
617 else
618 {
619 app_ns = app_namespace_get_default ();
620 }
621
622 if (session_sdl_is_enabled () == 0)
623 {
624 vlib_cli_output (vm, "session sdl engine is not enabled");
625 goto done;
626 }
627
628 if (show_one)
629 {
630 fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
631 st = session_table_get_for_fib_index (fib_proto, fib_index);
632 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
Steven Luong6f173172024-09-27 08:35:45 -0700633 session_rules_table_show_rule (vm, st->srtg_handle, 0, &rmt_ip, 0, 0,
Steven Luongc4b5d102024-07-30 13:44:01 -0700634 0, (fib_proto == FIB_PROTOCOL_IP4));
635 goto done;
636 }
637
638 /* 2 separate session tables for global entries, 1 for ip4 and 1 for ip6 */
639 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
640 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
641 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
642 session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP4);
643
644 fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
645 st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
646 if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
647 session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP6);
648done:
649 vec_free (ns_id);
650 return 0;
651}
652
653void
654session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
655 void *args)
656{
657 ip4_fib_t *fib;
658 session_sdl4_fib_show_walk_ctx_t ctx = {
659 .ifsw_indicies = NULL,
660 };
661 fib_node_index_t *fei;
662 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
663 session_sdl_block_t *sdlb = &srt->sdl_block;
664 u32 fib_index = sdlb->ip_fib_index;
665
666 if (fib_index == ~0)
667 return;
668 fib = ip4_fib_get (fib_index);
669 ip4_fib_table_walk (fib, session_sdl4_fib_show_walk_cb, &ctx);
670 vec_sort_with_function (ctx.ifsw_indicies, fib_entry_cmp_for_sort);
671
672 vec_foreach (fei, ctx.ifsw_indicies)
673 {
674 if (*fei != FIB_NODE_INDEX_INVALID &&
675 fib_entry_is_sourced (*fei, sdl_fib_src))
676 {
677 u8 *tag = session_rules_table_rule_tag (srt, *fei, 1);
678 fib_entry_t *fib_entry = fib_entry_get (*fei);
679 fib_prefix_t pfx = fib_entry->fe_prefix;
680 index_t lbi =
681 ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
682 const dpo_id_t *dpo =
683 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
684
685 fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
686 FIB_PROTOCOL_IP4, tag, args);
687 }
688 }
689
690 vec_free (ctx.ifsw_indicies);
691}
692
693void
694session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
695 void *args)
696{
697 ip6_fib_t *fib;
698 fib_node_index_t *fei;
699 session_sdl6_fib_show_ctx_t ctx = {
700 .entries = NULL,
701 };
702 session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
703 session_sdl_block_t *sdlb = &srt->sdl_block;
704 u32 fib_index = sdlb->ip6_fib_index;
705
706 if (fib_index == ~0)
707 return;
708 fib = ip6_fib_get (fib_index);
709 ip6_fib_table_walk (fib->index, session_sdl6_fib_table_show_walk, &ctx);
710 vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);
711
712 vec_foreach (fei, ctx.entries)
713 {
714 if (*fei != FIB_NODE_INDEX_INVALID &&
715 fib_entry_is_sourced (*fei, sdl_fib_src))
716 {
717 u8 *tag = session_rules_table_rule_tag (srt, *fei, 0);
718 fib_entry_t *fib_entry = fib_entry_get (*fei);
719 fib_prefix_t pfx = fib_entry->fe_prefix;
720 index_t lbi =
721 ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
722 const dpo_id_t *dpo =
723 load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
724
725 fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
726 FIB_PROTOCOL_IP6, tag, args);
727 }
728 }
729
730 vec_free (ctx.entries);
731}
732
733VLIB_CLI_COMMAND (show_session_sdl_command, static) = {
734 .path = "show session sdl",
Steven Luong6f173172024-09-27 08:35:45 -0700735 .short_help = "show session sdl [appns <id> <rmt-ip>]",
Steven Luongc4b5d102024-07-30 13:44:01 -0700736 .function = show_session_sdl_command_fn,
737 .is_mp_safe = 1,
738};
739
740/*
741 * fd.io coding-style-patch-verification: ON
742 *
743 * Local Variables:
744 * eval: (c-set-style "gnu")
745 * End:
746 */