aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/session/session_cli.c5
-rw-r--r--src/vnet/session/session_sdl.c122
-rw-r--r--src/vnet/session/session_sdl.h36
-rw-r--r--src/vnet/session/session_table.h2
-rw-r--r--src/vnet/tcp/tcp.c8
-rw-r--r--src/vnet/tcp/tcp.h3
-rw-r--r--src/vnet/tcp/tcp_output.c28
-rw-r--r--src/vnet/tcp/tcp_sdl.h27
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:
+ */