diff options
Diffstat (limited to 'src/vnet/session/session_lookup.c')
-rw-r--r-- | src/vnet/session/session_lookup.c | 357 |
1 files changed, 236 insertions, 121 deletions
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 9d028dbb28c..0d580ba35c6 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -28,6 +28,7 @@ #include <vnet/session/session_lookup.h> #include <vnet/session/session.h> #include <vnet/session/application.h> +#include <vnet/session/session_rules_table.h> static session_lookup_main_t sl_main; @@ -37,6 +38,8 @@ static session_lookup_main_t sl_main; */ static u32 *fib_index_to_table_index[2]; +static u32 *fib_index_to_lock_count[2]; + /* 16 octets */ typedef CLIB_PACKED (struct { union @@ -239,7 +242,7 @@ session_table_get_for_connection (transport_connection_t * tc) session_table_get (fib_index_to_table_index[fib_proto][tc->fib_index]); } -static session_table_t * +session_table_t * session_table_get_for_fib_index (u32 fib_proto, u32 fib_index) { if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index) @@ -476,10 +479,10 @@ session_lookup_rules_table_session4 (session_table_t * st, u8 proto, ip4_address_t * lcl, u16 lcl_port, ip4_address_t * rmt, u16 rmt_port) { - session_rules_table_t *srt = &st->session_rules[proto]; u32 action_index, app_index; - action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port, - rmt_port); + + action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl, rmt, + lcl_port, rmt_port); app_index = session_lookup_action_to_handle (action_index); /* Nothing sophisticated for now, action index is app index */ return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4, @@ -492,10 +495,10 @@ session_lookup_rules_table_session6 (session_table_t * st, u8 proto, ip6_address_t * lcl, u16 lcl_port, ip6_address_t * rmt, u16 rmt_port) { - session_rules_table_t *srt = &st->session_rules[proto]; u32 action_index, app_index; - action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port, - rmt_port); + + action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl, rmt, + lcl_port, rmt_port); app_index = session_lookup_action_to_handle (action_index); return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6, proto); @@ -515,7 +518,6 @@ u64 session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep, u8 use_rules) { - session_rules_table_t *srt; session_table_t *st; u32 ai; int rv; @@ -535,10 +537,12 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep, return kv4.value; if (use_rules) { + if (st->srtg_handle == SESSION_SRTG_HANDLE_INVALID) + return SESSION_INVALID_HANDLE; clib_memset (&lcl4, 0, sizeof (lcl4)); - srt = &st->session_rules[sep->transport_proto]; - ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0, - sep->port); + ai = + session_rules_table_lookup4 (st->srtg_handle, sep->transport_proto, + &lcl4, &sep->ip.ip4, 0, sep->port); if (session_lookup_action_index_is_valid (ai)) return session_lookup_action_to_handle (ai); } @@ -556,10 +560,12 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep, if (use_rules) { + if (st->srtg_handle == SESSION_SRTG_HANDLE_INVALID) + return SESSION_INVALID_HANDLE; clib_memset (&lcl6, 0, sizeof (lcl6)); - srt = &st->session_rules[sep->transport_proto]; - ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0, - sep->port); + ai = + session_rules_table_lookup6 (st->srtg_handle, sep->transport_proto, + &lcl6, &sep->ip.ip6, 0, sep->port); if (session_lookup_action_index_is_valid (ai)) return session_lookup_action_to_handle (ai); } @@ -586,14 +592,13 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep, u64 session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) { - session_rules_table_t *srt; session_table_t *st; u32 ai; int rv; st = session_table_get (table_index); if (!st) - return SESSION_INVALID_INDEX; + return SESSION_INVALID_HANDLE; ASSERT (st->is_local); if (sep->is_ip4) @@ -601,15 +606,18 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) session_kv4_t kv4; ip4_address_t lcl4; - /* - * Check if endpoint has special rules associated - */ - clib_memset (&lcl4, 0, sizeof (lcl4)); - srt = &st->session_rules[sep->transport_proto]; - ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0, - sep->port); - if (session_lookup_action_index_is_valid (ai)) - return session_lookup_action_to_handle (ai); + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) + { + /* + * Check if endpoint has special rules associated + */ + clib_memset (&lcl4, 0, sizeof (lcl4)); + ai = + session_rules_table_lookup4 (st->srtg_handle, sep->transport_proto, + &lcl4, &sep->ip.ip4, 0, sep->port); + if (session_lookup_action_index_is_valid (ai)) + return session_lookup_action_to_handle (ai); + } /* * Check if session endpoint is a listener @@ -649,12 +657,15 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) session_kv6_t kv6; ip6_address_t lcl6; - clib_memset (&lcl6, 0, sizeof (lcl6)); - srt = &st->session_rules[sep->transport_proto]; - ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0, - sep->port); - if (session_lookup_action_index_is_valid (ai)) - return session_lookup_action_to_handle (ai); + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) + { + clib_memset (&lcl6, 0, sizeof (lcl6)); + ai = + session_rules_table_lookup6 (st->srtg_handle, sep->transport_proto, + &lcl6, &sep->ip.ip6, 0, sep->port); + if (session_lookup_action_index_is_valid (ai)) + return session_lookup_action_to_handle (ai); + } make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port, sep->transport_proto); @@ -982,22 +993,25 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, if (rv == 0) return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF); - /* - * Check the session rules table - */ - action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + /* + * Check the session rules table + */ + action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) { - *result = SESSION_LOOKUP_RESULT_FILTERED; + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + { + *result = SESSION_LOOKUP_RESULT_FILTERED; + return 0; + } + if ((s = session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP4, proto))) + return transport_get_listener (proto, s->connection_index); return 0; } - if ((s = session_lookup_action_to_session (action_index, - FIB_PROTOCOL_IP4, proto))) - return transport_get_listener (proto, s->connection_index); - return 0; } /* @@ -1059,19 +1073,22 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, if (rv == 0) return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF); - /* - * Check the session rules table - */ - action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) - return 0; - if ((s = session_lookup_action_to_session (action_index, - FIB_PROTOCOL_IP4, proto))) - return transport_get_listener (proto, s->connection_index); - return 0; + /* + * Check the session rules table + */ + action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) + { + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + return 0; + if ((s = session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP4, proto))) + return transport_get_listener (proto, s->connection_index); + return 0; + } } /* @@ -1117,17 +1134,20 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt, if (rv == 0) return session_get_from_handle_safe (kv4.value); - /* - * Check the session rules table - */ - action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) - return 0; - return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4, - proto); + /* + * Check the session rules table + */ + action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) + { + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + return 0; + return session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP4, proto); + } } /* @@ -1184,7 +1204,6 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); if (rv == 0) { - ASSERT ((u32) (kv6.value >> 32) == thread_index); if (PREDICT_FALSE ((u32) (kv6.value >> 32) != thread_index)) { *result = SESSION_LOOKUP_RESULT_WRONG_THREAD; @@ -1200,20 +1219,23 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, if (rv == 0) return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF); - /* Check the session rules table */ - action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + /* Check the session rules table */ + action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) { - *result = SESSION_LOOKUP_RESULT_FILTERED; + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + { + *result = SESSION_LOOKUP_RESULT_FILTERED; + return 0; + } + if ((s = session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP6, proto))) + return transport_get_listener (proto, s->connection_index); return 0; } - if ((s = session_lookup_action_to_session (action_index, - FIB_PROTOCOL_IP6, proto))) - return transport_get_listener (proto, s->connection_index); - return 0; } /* If nothing is found, check if any listener is available */ @@ -1269,17 +1291,20 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, if (rv == 0) return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF); - /* Check the session rules table */ - action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) - return 0; - if ((s = session_lookup_action_to_session (action_index, - FIB_PROTOCOL_IP6, proto))) - return transport_get_listener (proto, s->connection_index); - return 0; + /* Check the session rules table */ + action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) + { + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + return 0; + if ((s = session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP6, proto))) + return transport_get_listener (proto, s->connection_index); + return 0; + } } /* If nothing is found, check if any listener is available */ @@ -1322,15 +1347,18 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt, if (rv == 0) return session_get_from_handle_safe (kv6.value); - /* Check the session rules table */ - action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl, - rmt, lcl_port, rmt_port); - if (session_lookup_action_index_is_valid (action_index)) + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { - if (action_index == SESSION_RULES_TABLE_ACTION_DROP) - return 0; - return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6, - proto); + /* Check the session rules table */ + action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl, + rmt, lcl_port, rmt_port); + if (session_lookup_action_index_is_valid (action_index)) + { + if (action_index == SESSION_RULES_TABLE_ACTION_DROP) + return 0; + return session_lookup_action_to_session (action_index, + FIB_PROTOCOL_IP6, proto); + } } /* If nothing is found, check if any listener is available */ @@ -1356,7 +1384,6 @@ session_error_t vnet_session_rule_add_del (session_rule_add_del_args_t *args) { app_namespace_t *app_ns = app_namespace_get (args->appns_index); - session_rules_table_t *srt; session_table_t *st; u32 fib_index; u8 fib_proto; @@ -1377,8 +1404,9 @@ vnet_session_rule_add_del (session_rule_add_del_args_t *args) fib_proto = args->table_args.rmt.fp_proto; fib_index = app_namespace_get_fib_index (app_ns, fib_proto); st = session_table_get_for_fib_index (fib_proto, fib_index); - srt = &st->session_rules[args->transport_proto]; - if ((rv = session_rules_table_add_del (srt, &args->table_args))) + session_rules_table_init (st, fib_proto); + if ((rv = session_rules_table_add_del ( + st->srtg_handle, args->transport_proto, &args->table_args))) return rv; } if (args->scope & SESSION_RULE_SCOPE_LOCAL) @@ -1387,12 +1415,30 @@ vnet_session_rule_add_del (session_rule_add_del_args_t *args) args->table_args.lcl.fp_proto = args->table_args.rmt.fp_proto; args->table_args.lcl_port = 0; st = app_namespace_get_local_table (app_ns); - srt = &st->session_rules[args->transport_proto]; - rv = session_rules_table_add_del (srt, &args->table_args); + session_rules_table_init (st, args->table_args.rmt.fp_proto); + rv = session_rules_table_add_del (st->srtg_handle, args->transport_proto, + &args->table_args); } return rv; } +static void +session_lookup_fib_table_lock (u32 fib_index, u32 protocol) +{ + fib_table_lock (fib_index, protocol, sl_main.fib_src); + vec_validate (fib_index_to_lock_count[protocol], fib_index); + fib_index_to_lock_count[protocol][fib_index]++; + ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0); +} + +static void +session_lookup_fib_table_unlock (u32 fib_index, u32 protocol) +{ + fib_table_unlock (fib_index, protocol, sl_main.fib_src); + ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0); + fib_index_to_lock_count[protocol][fib_index]--; +} + /** * Mark (global) tables as pertaining to app ns */ @@ -1408,7 +1454,10 @@ session_lookup_set_tables_appns (app_namespace_t * app_ns) fib_index = app_namespace_get_fib_index (app_ns, fp); st = session_table_get_or_alloc (fp, fib_index); if (st) - st->appns_index = app_namespace_index (app_ns); + { + st->appns_index = app_namespace_index (app_ns); + session_lookup_fib_table_lock (fib_index, fp); + } } } @@ -1502,6 +1551,9 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, session_cli_return_if_not_enabled (); + if (session_rule_table_is_enabled () == 0) + return clib_error_return (0, "session rule table engine is not enabled"); + clib_memset (&lcl_ip, 0, sizeof (lcl_ip)); clib_memset (&rmt_ip, 0, sizeof (rmt_ip)); while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -1623,11 +1675,12 @@ session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto, u8 transport_proto) { vlib_main_t *vm = vlib_get_main (); - session_rules_table_t *srt; session_table_t *st; st = session_table_get_for_fib_index (fib_index, fib_proto); - srt = &st->session_rules[transport_proto]; - session_rules_table_cli_dump (vm, srt, fib_proto); + if (st == 0) + return; + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + fib_proto); } void @@ -1635,11 +1688,12 @@ session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto, u8 transport_proto) { vlib_main_t *vm = vlib_get_main (); - session_rules_table_t *srt; session_table_t *st; st = session_table_get (table_index); - srt = &st->session_rules[transport_proto]; - session_rules_table_cli_dump (vm, srt, fib_proto); + if (st == 0) + return; + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + fib_proto); } static clib_error_t * @@ -1651,7 +1705,6 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, ip46_address_t lcl_ip, rmt_ip; u8 is_ip4 = 1, show_one = 0; app_namespace_t *app_ns; - session_rules_table_t *srt; session_table_t *st; u8 *ns_id = 0, fib_proto; @@ -1666,9 +1719,9 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, else if (unformat (input, "appns %_%v%_", &ns_id)) ; else if (unformat (input, "scope global")) - scope = 1; + scope = SESSION_RULE_SCOPE_GLOBAL; else if (unformat (input, "scope local")) - scope = 2; + scope = SESSION_RULE_SCOPE_LOCAL; else if (unformat (input, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip.ip4, &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip.ip4, &rmt_plen, @@ -1686,14 +1739,17 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, show_one = 1; } else - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); + { + vec_free (ns_id); + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + } } if (transport_proto == ~0) { vlib_cli_output (vm, "transport proto must be set"); - return 0; + goto done; } if (ns_id) @@ -1702,7 +1758,7 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, if (!app_ns) { vlib_cli_output (vm, "appns %v doesn't exist", ns_id); - return 0; + goto done; } } else @@ -1710,7 +1766,7 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, app_ns = app_namespace_get_default (); } - if (scope == 1 || scope == 0) + if (scope == SESSION_RULE_SCOPE_GLOBAL || scope == 0) { fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; fib_index = is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index; @@ -1721,20 +1777,51 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, st = app_namespace_get_local_table (app_ns); } + if (session_rule_table_is_enabled () == 0) + { + vlib_cli_output (vm, "session rule table engine is not enabled"); + goto done; + } + if (show_one) { - srt = &st->session_rules[transport_proto]; - session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip, - rmt_port, is_ip4); - return 0; + if (st) + session_rules_table_show_rule (vm, st->srtg_handle, transport_proto, + &lcl_ip, lcl_port, &rmt_ip, rmt_port, + is_ip4); + goto done; } vlib_cli_output (vm, "%U rules table", format_transport_proto, transport_proto); - srt = &st->session_rules[transport_proto]; - session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4); - session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6); + if (scope == SESSION_RULE_SCOPE_LOCAL) + { + if (st) + { + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + FIB_PROTOCOL_IP4); + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + FIB_PROTOCOL_IP6); + } + } + else + { + /* + * 2 separate session tables for global entries, 1 for ip4 and 1 for ip6 + */ + st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, + app_ns->ip4_fib_index); + if (st) + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + FIB_PROTOCOL_IP4); + st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, + app_ns->ip6_fib_index); + if (st) + session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto, + FIB_PROTOCOL_IP6); + } +done: vec_free (ns_id); return 0; } @@ -1833,6 +1920,14 @@ session_lookup_init (void) clib_spinlock_init (&slm->st_alloc_lock); + /* We are not contributing any route to the fib. But we allocate a fib source + * so that when we lock the fib table, we can view that we have a lock on the + * particular fib table in case we wonder why the fib table is not free after + * "ip table del" + */ + slm->fib_src = fib_source_allocate ( + "session lookup", FIB_SOURCE_PRIORITY_LOW, FIB_SOURCE_BH_SIMPLE); + /* * Allocate default table and map it to fib_index 0 */ @@ -1848,6 +1943,26 @@ session_lookup_init (void) session_table_init (st, FIB_PROTOCOL_IP6); } +void +session_lookup_table_cleanup (u32 fib_proto, u32 fib_index) +{ + session_table_t *st; + u32 table_index; + + session_lookup_fib_table_unlock (fib_index, fib_proto); + if (fib_index_to_lock_count[fib_proto][fib_index] == 0) + { + table_index = session_lookup_get_index_for_fib (fib_proto, fib_index); + st = session_table_get (table_index); + if (st) + { + session_table_free (st, fib_proto); + if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index) + fib_index_to_table_index[fib_proto][fib_index] = ~0; + } + } +} + /* * fd.io coding-style-patch-verification: ON * |