diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/session/session_cli.c | 5 | ||||
-rw-r--r-- | src/vnet/session/session_sdl.c | 122 | ||||
-rw-r--r-- | src/vnet/session/session_sdl.h | 36 | ||||
-rw-r--r-- | src/vnet/session/session_table.h | 2 | ||||
-rw-r--r-- | src/vnet/tcp/tcp.c | 8 | ||||
-rw-r--r-- | src/vnet/tcp/tcp.h | 3 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_output.c | 28 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_sdl.h | 27 |
8 files changed, 198 insertions, 33 deletions
diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c index 0ed2876469b..aff102a6989 100644 --- a/src/vnet/session/session_cli.c +++ b/src/vnet/session/session_cli.c @@ -976,7 +976,7 @@ static clib_error_t * session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - session_enable_disable_args_t args; + session_enable_disable_args_t args = {}; session_main_t *smm = &session_main; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -1010,6 +1010,9 @@ session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input, return clib_error_return ( 0, "session is already enable. Must disable first"); + if ((smm->is_enabled == 0) && (args.is_en == 0)) + return clib_error_return (0, "session is already disabled"); + return vnet_session_enable_disable (vm, &args); } diff --git a/src/vnet/session/session_sdl.c b/src/vnet/session/session_sdl.c index f1dfac4e1ab..a18674cd83b 100644 --- a/src/vnet/session/session_sdl.c +++ b/src/vnet/session/session_sdl.c @@ -29,8 +29,8 @@ VLIB_REGISTER_LOG_CLASS (session_sdl_log, static) = { .class_name = "session", #define log_err(fmt, ...) \ vlib_log_err (session_sdl_log.class, fmt, __VA_ARGS__) -static fib_source_t sdl_fib_src; -static dpo_type_t sdl_dpo_type; +static session_sdl_main_t sdl_main; +static session_sdl_main_t *sdlm = &sdl_main; const static char *const *const session_sdl_dpo_nodes[DPO_PROTO_NUM] = { [DPO_PROTO_IP4] = (const char *const[]){ "ip4-drop", 0 }, @@ -89,7 +89,7 @@ session_sdl_lookup6 (u32 srtg_handle, u32 proto, ip6_address_t *lcl_ip, return SESSION_TABLE_INVALID_INDEX; lbi = ip6_fib_table_fwding_lookup (sdlb->ip6_fib_index, rmt_ip); dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0); - if (dpo->dpoi_type != sdl_dpo_type) + if (dpo->dpoi_type != sdlm->dpo_type) return SESSION_TABLE_INVALID_INDEX; return (dpo->dpoi_index); } @@ -107,7 +107,7 @@ session_sdl_lookup4 (u32 srtg_handle, u32 proto, ip4_address_t *lcl_ip, return SESSION_TABLE_INVALID_INDEX; lbi = ip4_fib_forwarding_lookup (sdlb->ip_fib_index, rmt_ip); dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0); - if (dpo->dpoi_type != sdl_dpo_type) + if (dpo->dpoi_type != sdlm->dpo_type) return SESSION_TABLE_INVALID_INDEX; return (dpo->dpoi_index); } @@ -184,7 +184,8 @@ session_sdl4_fib_table_show_one (session_rules_table_t *srt, u32 fib_index, fib = ip4_fib_get (fib_index); fei = ip4_fib_table_lookup (fib, address, mask_len); - if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src)) + if (fei != FIB_NODE_INDEX_INVALID && + fib_entry_is_sourced (fei, sdlm->fib_src)) { u8 *tag = session_rules_table_rule_tag (srt, fei, 1); fib_entry_t *fib_entry = fib_entry_get (fei); @@ -206,7 +207,8 @@ session_sdl6_fib_table_show_one (session_rules_table_t *srt, u32 fib_index, fib_node_index_t fei; fei = ip6_fib_table_lookup (fib_index, address, mask_len); - if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src)) + if (fei != FIB_NODE_INDEX_INVALID && + fib_entry_is_sourced (fei, sdlm->fib_src)) { u8 *tag = session_rules_table_rule_tag (srt, fei, 0); fib_entry_t *fib_entry = fib_entry_get (fei); @@ -264,7 +266,7 @@ session_sdl_table_init (session_table_t *st, u8 fib_proto) snprintf (name, sizeof (name), "sdl4 %s", app_ns->ns_id); sdlb->ip_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP4); sdlb->ip_fib_index = fib_table_find_or_create_and_lock_w_name ( - FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdl_fib_src, (const u8 *) name); + FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdlm->fib_src, (const u8 *) name); } if (fib_proto == FIB_PROTOCOL_IP6 || all) @@ -272,7 +274,8 @@ session_sdl_table_init (session_table_t *st, u8 fib_proto) snprintf (name, sizeof (name), "sdl6 %s", app_ns->ns_id); sdlb->ip6_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP6); sdlb->ip6_fib_index = fib_table_find_or_create_and_lock_w_name ( - FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdl_fib_src, (const u8 *) name); + FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdlm->fib_src, + (const u8 *) name); } srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword)); @@ -285,18 +288,33 @@ session_sdl_table_free (session_table_t *st, u8 fib_proto) session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, 0); session_sdl_block_t *sdlb; u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0; + u32 fib_index, appns_index = *vec_elt_at_index (st->appns_index, 0); + app_namespace_t *app_ns = app_namespace_get (appns_index); + session_sdl_callback_fn_t *cb; ASSERT (st->is_local == 0); + if (st->is_local == 1) + return; sdlb = &srt->sdl_block; if ((fib_proto == FIB_PROTOCOL_IP4 || all) && (sdlb->ip_fib_index != ~0)) { - fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src); - fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src); + fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4); + session_sdl_callback_t args = { .fib_proto = FIB_PROTOCOL_IP4, + .fib_index = fib_index }; + vec_foreach (cb, sdlm->sdl_callbacks) + (*cb) (SESSION_SDL_CALLBACK_TABLE_CLEAN_UP, &args); + fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdlm->fib_src); + fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdlm->fib_src); } if ((fib_proto == FIB_PROTOCOL_IP6 || all) && (sdlb->ip6_fib_index != ~0)) { - fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src); - fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src); + fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6); + session_sdl_callback_t args = { .fib_proto = FIB_PROTOCOL_IP6, + .fib_index = fib_index }; + vec_foreach (cb, sdlm->sdl_callbacks) + (*cb) (SESSION_SDL_CALLBACK_TABLE_CLEAN_UP, &args); + fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdlm->fib_src); + fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdlm->fib_src); } hash_free (srt->tags_by_rules); @@ -345,8 +363,8 @@ session_sdl_add_del (u32 srtg_handle, u32 proto, err = SESSION_E_IPINUSE; goto done; } - dpo_set (&paths->dpo, sdl_dpo_type, dpo_proto, args->action_index); - fei = fib_table_entry_path_add2 (fib_index, &pfx, sdl_fib_src, + dpo_set (&paths->dpo, sdlm->dpo_type, dpo_proto, args->action_index); + fei = fib_table_entry_path_add2 (fib_index, &pfx, sdlm->fib_src, FIB_ENTRY_FLAG_EXCLUSIVE, paths); session_rules_table_add_tag (srt, args->tag, fei, is_ip4); dpo_reset (&paths->dpo); @@ -364,7 +382,7 @@ session_sdl_add_del (u32 srtg_handle, u32 proto, } } - if (!fib_entry_is_sourced (fei, sdl_fib_src)) + if (!fib_entry_is_sourced (fei, sdlm->fib_src)) { err = SESSION_E_NOROUTE; goto done; @@ -372,7 +390,7 @@ session_sdl_add_del (u32 srtg_handle, u32 proto, fib_entry_t *fib_entry = fib_entry_get (fei); pfx = fib_entry->fe_prefix; - fib_table_entry_special_remove (fib_index, &pfx, sdl_fib_src); + fib_table_entry_special_remove (fib_index, &pfx, sdlm->fib_src); session_rules_table_del_tag (srt, args->tag, is_ip4); } done: @@ -393,16 +411,15 @@ static const session_rt_engine_vft_t session_sdl_vft = { }; static void -session_sdl_fib_init (void) +session_sdl_init (void) { - static u32 session_fib_inited = 0; - - if (session_fib_inited) + if (sdlm->sdl_inited) return; - session_fib_inited = 1; - sdl_fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW, - FIB_SOURCE_BH_SIMPLE); - sdl_dpo_type = + + sdlm->sdl_inited = 1; + sdlm->fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW, + FIB_SOURCE_BH_SIMPLE); + sdlm->dpo_type = dpo_register_new_type (&session_sdl_dpo_vft, session_sdl_dpo_nodes); } @@ -431,6 +448,9 @@ clib_error_t * session_sdl_enable_disable (int enable) { clib_error_t *error = 0; + session_sdl_callback_fn_t *cb; + session_sdl_callback_t args; + session_sdl_callback_fn_t *callbacks; if (enable) { @@ -440,7 +460,7 @@ session_sdl_enable_disable (int enable) log_err ("error in enabling sdl: %U", format_clib_error, error); return error; } - session_sdl_fib_init (); + session_sdl_init (); } else { @@ -449,6 +469,18 @@ session_sdl_enable_disable (int enable) error = session_rule_table_deregister_engine (&session_sdl_vft); if (error) log_err ("error in disabling sdl: %U", format_clib_error, error); + + /* + * Disabling sdl also disables auto sdl. + * But first, make a copy of the callbacks since the callback function + * may delete the callbacks, deregistering. + */ + callbacks = vec_dup (sdlm->sdl_callbacks); + + clib_memset (&args, 0, sizeof (args)); + vec_foreach (cb, callbacks) + (*cb) (SESSION_SDL_CALLBACK_CONFIG_DISABLE, &args); + vec_free (callbacks); } return error; @@ -520,9 +552,8 @@ session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input, } } else - { - app_ns = app_namespace_get_default (); - } + app_ns = app_namespace_get_default (); + appns_index = app_namespace_index (app_ns); if (is_add && !conn_set && action == 0) @@ -563,7 +594,7 @@ done: VLIB_CLI_COMMAND (session_sdl_command, static) = { .path = "session sdl", - .short_help = "session sdl [add|del] [appns <ns_id>] <rmt-ip/plen> action " + .short_help = "session sdl <add|del> [appns <ns_id>] <rmt-ip/plen> action " "<action> [tag <tag>]", .function = session_sdl_command_fn, .is_mp_safe = 1, @@ -672,7 +703,7 @@ session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn, vec_foreach (fei, ctx.ifsw_indicies) { if (*fei != FIB_NODE_INDEX_INVALID && - fib_entry_is_sourced (*fei, sdl_fib_src)) + fib_entry_is_sourced (*fei, sdlm->fib_src)) { u8 *tag = session_rules_table_rule_tag (srt, *fei, 1); fib_entry_t *fib_entry = fib_entry_get (*fei); @@ -712,7 +743,7 @@ session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn, vec_foreach (fei, ctx.entries) { if (*fei != FIB_NODE_INDEX_INVALID && - fib_entry_is_sourced (*fei, sdl_fib_src)) + fib_entry_is_sourced (*fei, sdlm->fib_src)) { u8 *tag = session_rules_table_rule_tag (srt, *fei, 0); fib_entry_t *fib_entry = fib_entry_get (*fei); @@ -730,6 +761,35 @@ session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn, vec_free (ctx.entries); } +int +session_sdl_register_callbacks (session_sdl_callback_fn_t cb) +{ + int i; + + vec_foreach_index (i, sdlm->sdl_callbacks) + { + if (cb == *vec_elt_at_index (sdlm->sdl_callbacks, i)) + return -1; + } + vec_add1 (sdlm->sdl_callbacks, cb); + return 0; +} + +void +session_sdl_deregister_callbacks (session_sdl_callback_fn_t cb) +{ + int i; + + vec_foreach_index (i, sdlm->sdl_callbacks) + { + if (cb == *vec_elt_at_index (sdlm->sdl_callbacks, i)) + { + vec_del1 (sdlm->sdl_callbacks, i); + break; + } + } +} + VLIB_CLI_COMMAND (show_session_sdl_command, static) = { .path = "show session sdl", .short_help = "show session sdl [appns <id> <rmt-ip>]", diff --git a/src/vnet/session/session_sdl.h b/src/vnet/session/session_sdl.h index 8d8b5b2d29e..c5c4b40f05c 100644 --- a/src/vnet/session/session_sdl.h +++ b/src/vnet/session/session_sdl.h @@ -16,6 +16,40 @@ #ifndef SRC_VNET_SESSION_SESSION_SDL_H_ #define SRC_VNET_SESSION_SESSION_SDL_H_ +#include <vnet/fib/fib_types.h> +#include <vnet/fib/fib_source.h> +#include <vnet/dpo/dpo.h> + +typedef enum +{ + SESSION_SDL_CALLBACK_TABLE_CLEAN_UP, + SESSION_SDL_CALLBACK_CONFIG_DISABLE, +} session_sdl_callback_event_t; + +typedef struct session_sdl_callback_ +{ + union + { + /* For table clean up */ + struct + { + u32 fib_proto; + u32 fib_index; + }; + }; +} session_sdl_callback_t; + +typedef void (*session_sdl_callback_fn_t) (int which, + session_sdl_callback_t *args); +typedef struct session_sdl_main +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + fib_source_t fib_src; + dpo_type_t dpo_type; + u8 sdl_inited; + session_sdl_callback_fn_t *sdl_callbacks; +} session_sdl_main_t; + clib_error_t *session_sdl_enable_disable (int enable); typedef void (*session_sdl_table_walk_fn_t) (u32 fei, ip46_address_t *lcl_ip, @@ -25,6 +59,8 @@ void session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn, void *args); void session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn, void *args); +int session_sdl_register_callbacks (session_sdl_callback_fn_t cb); +void session_sdl_deregister_callbacks (session_sdl_callback_fn_t cb); #endif /* SRC_VNET_SESSION_SESSION_SDL_H_ */ /* diff --git a/src/vnet/session/session_table.h b/src/vnet/session/session_table.h index 126e849beae..e3d5c4db91c 100644 --- a/src/vnet/session/session_table.h +++ b/src/vnet/session/session_table.h @@ -46,7 +46,7 @@ typedef struct _session_lookup_table /** For global tables only one fib proto is active. This is a * byproduct of fib table ids not necessarily being the same for - * identical fib idices of v4 and v6 fib protos */ + * identical fib indices of v4 and v6 fib protos */ u8 active_fib_proto; /* Required for pool_get_aligned(...) */ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index 1afc07918b7..aea49558882 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -1616,6 +1616,14 @@ tcp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add) tm->punt_unknown6 = is_add; } +void +tcp_sdl_enable_disable (tcp_sdl_cb_fn_t fp) +{ + tcp_main_t *tm = &tcp_main; + + tm->sdl_cb = fp; +} + /** * Initialize default values for tcp parameters */ diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index 8676db413a0..8feac807d59 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -25,6 +25,7 @@ #include <vnet/tcp/tcp_sack.h> #include <vnet/tcp/tcp_bt.h> #include <vnet/tcp/tcp_cc.h> +#include <vnet/tcp/tcp_sdl.h> typedef void (timer_expiration_handler) (tcp_connection_t * tc); @@ -265,6 +266,8 @@ typedef struct _tcp_main /** message ID base for API */ u16 msg_id_base; + + tcp_sdl_cb_fn_t sdl_cb; } tcp_main_t; extern tcp_main_t tcp_main; diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index dd1ec555902..2fd20acf241 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1282,6 +1282,32 @@ tcp_cc_init_rxt_timeout (tcp_connection_t * tc) tcp_recovery_on (tc); } +static void +tcp_check_syn_flood (tcp_connection_t *tc) +{ + tcp_main_t *tm = &tcp_main; + auto_sdl_track_prefix_args_t args = {}; + + if (tm->sdl_cb == 0) + return; + + args.prefix.fp_addr = tc->c_rmt_ip; + if (tc->c_is_ip4) + { + args.prefix.fp_proto = FIB_PROTOCOL_IP4; + args.prefix.fp_len = 32; + } + else + { + args.prefix.fp_proto = FIB_PROTOCOL_IP6; + args.prefix.fp_len = 128; + } + args.fib_index = tc->c_fib_index; + args.action_index = 0; + args.tag = 0; + tm->sdl_cb (&args); +} + void tcp_timer_retransmit_handler (tcp_connection_t * tc) { @@ -1397,6 +1423,8 @@ tcp_timer_retransmit_handler (tcp_connection_t * tc) tcp_connection_timers_reset (tc); tcp_program_cleanup (wrk, tc); tcp_worker_stats_inc (wrk, tr_abort, 1); + + tcp_check_syn_flood (tc); return; } diff --git a/src/vnet/tcp/tcp_sdl.h b/src/vnet/tcp/tcp_sdl.h new file mode 100644 index 00000000000..482881b5b43 --- /dev/null +++ b/src/vnet/tcp/tcp_sdl.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. + */ + +#ifndef _vnet_tcp_sdl_h_ +#define _vnet_tcp_sdl_h_ + +typedef struct _auto_sdl_track_prefix_args +{ + fib_prefix_t prefix; + u8 *tag; + u32 action_index; + u32 fib_index; +} auto_sdl_track_prefix_args_t; + +typedef int (*tcp_sdl_cb_fn_t) (auto_sdl_track_prefix_args_t *args); +extern void tcp_sdl_enable_disable (tcp_sdl_cb_fn_t fp); + +#endif /* _vnet_tcp_sdl_h_ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |