}
static session_table_t *
-session_table_get_or_alloc (u8 fib_proto, u8 fib_index)
+session_table_get_or_alloc (u8 fib_proto, u32 fib_index)
{
session_table_t *st;
u32 table_index;
- if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
+ ASSERT (fib_index != ~0);
+ if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index &&
+ fib_index_to_table_index[fib_proto][fib_index] != ~0)
+ {
+ table_index = fib_index_to_table_index[fib_proto][fib_index];
+ return session_table_get (table_index);
+ }
+ else
{
st = session_table_alloc ();
table_index = session_table_index (st);
- vec_validate (fib_index_to_table_index[fib_proto], fib_index);
+ vec_validate_init_empty (fib_index_to_table_index[fib_proto], fib_index,
+ ~0);
fib_index_to_table_index[fib_proto][fib_index] = table_index;
st->active_fib_proto = fib_proto;
session_table_init (st, fib_proto);
return st;
}
- else
- {
- table_index = fib_index_to_table_index[fib_proto][fib_index];
- return session_table_get (table_index);
- }
}
static session_table_t *
return fib_index_to_table_index[fib_proto][fib_index];
}
+u32
+session_lookup_get_or_alloc_index_for_fib (u32 fib_proto, u32 fib_index)
+{
+ session_table_t *st;
+ st = session_table_get_or_alloc (fib_proto, fib_index);
+ return session_table_index (st);
+}
+
/**
* Add transport connection to a session table
*
}
}
+int
+session_lookup_del_session_endpoint2 (session_endpoint_t * sep)
+{
+ fib_protocol_t fib_proto;
+ session_table_t *st;
+ session_kv4_t kv4;
+ session_kv6_t kv6;
+
+ fib_proto = sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+ st = session_table_get_for_fib_index (fib_proto, sep->fib_index);
+ if (!st)
+ return -1;
+ if (sep->is_ip4)
+ {
+ make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port,
+ sep->transport_proto);
+ return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0);
+ }
+ else
+ {
+ make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
+ sep->transport_proto);
+ return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0);
+ }
+}
+
/**
* Delete transport connection from session table
*
transport_connection_t *ts;
ts = transport_get_connection (session_get_transport_proto (s),
s->connection_index, s->thread_index);
+ if (!ts || (ts->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
+ return 0;
return session_lookup_del_connection (ts);
}
session_t *
session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port,
- u8 proto)
+ u8 proto, u8 use_wildcard)
{
session_table_t *st;
st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
if (!st)
return 0;
- return session_lookup_listener4_i (st, lcl, lcl_port, proto, 0);
+ return session_lookup_listener4_i (st, lcl, lcl_port, proto, use_wildcard);
}
static session_t *
session_t *
session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port,
- u8 proto)
+ u8 proto, u8 use_wildcard)
{
session_table_t *st;
st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
if (!st)
return 0;
- return session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
+ return session_lookup_listener6_i (st, lcl, lcl_port, proto, use_wildcard);
}
/**
return 0;
}
+/**
+ * Lookup listener wildcard match
+ */
+session_t *
+session_lookup_listener_wildcard (u32 table_index, session_endpoint_t * sep)
+{
+ session_table_t *st;
+ st = session_table_get (table_index);
+ if (!st)
+ return 0;
+ if (sep->is_ip4)
+ return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port,
+ sep->transport_proto,
+ 1 /* use_wildcard */ );
+ else
+ return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port,
+ sep->transport_proto,
+ 1 /* use_wildcard */ );
+ return 0;
+}
+
int
session_lookup_add_half_open (transport_connection_t * tc, u64 value)
{
/**
* Lookup session with ip4 and transport layer information
*
- * Important note: this may look into another thread's pool table and
- * register as 'peeker'. Caller should call @ref session_pool_remove_peeker as
- * if needed as soon as possible.
+ * Important note: this may look into another thread's pool table
*
* Lookup logic is similar to that of @ref session_lookup_connection_wt4 but
* this returns a session as opposed to a transport connection and it does not
return 0;
}
+transport_connection_t *
+session_lookup_connection (u32 fib_index, ip46_address_t * lcl,
+ ip46_address_t * rmt, u16 lcl_port, u16 rmt_port,
+ u8 proto, u8 is_ip4)
+{
+ if (is_ip4)
+ return session_lookup_connection4 (fib_index, &lcl->ip4, &rmt->ip4,
+ lcl_port, rmt_port, proto);
+ else
+ return session_lookup_connection6 (fib_index, &lcl->ip6, &rmt->ip6,
+ lcl_port, rmt_port, proto);
+}
+
int
vnet_session_rule_add_del (session_rule_add_del_args_t * args)
{
for (fp = 0; fp < ARRAY_LEN (fib_index_to_table_index); fp++)
{
fib_index = app_namespace_get_fib_index (app_ns, fp);
- st = session_table_get_for_fib_index (fp, fib_index);
+ st = session_table_get_or_alloc (fp, fib_index);
if (st)
st->appns_index = app_namespace_index (app_ns);
}
format_ip4_session_lookup_kvp (u8 * s, va_list * args)
{
clib_bihash_kv_16_8_t *kvp = va_arg (*args, clib_bihash_kv_16_8_t *);
- u32 is_local = va_arg (*args, u32), app_wrk_index, session_index;
+ u32 is_local = va_arg (*args, u32);
v4_connection_key_t *key = (v4_connection_key_t *) kvp->key;
session_t *session;
app_worker_t *app_wrk;
}
else
{
- local_session_parse_handle (kvp->value, &app_wrk_index, &session_index);
- app_wrk = app_worker_get (app_wrk_index);
+ session = session_get_from_handle (kvp->value);
+ app_wrk = app_worker_get (session->app_wrk_index);
app_name = application_name_from_index (app_wrk->app_index);
str = format (0, "[%U] %U:%d", format_transport_proto_short, key->proto,
format_ip4_address, &key->src,
vlib_cli_command_t * cmd)
{
u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen = 0, rmt_plen = 0;
+ clib_error_t *error = 0;
u32 appns_index, scope = 0;
ip46_address_t lcl_ip, rmt_ip;
u8 is_ip4 = 1, conn_set = 0;
app_namespace_t *app_ns;
int rv;
+ session_cli_return_if_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)
else if (unformat (input, "tag %_%v%_", &tag))
;
else
- return clib_error_return (0, "unknown input `%U'",
- format_unformat_error, input);
+ {
+ error = clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ goto done;
+ }
}
if (proto == ~0)
{
vlib_cli_output (vm, "proto must be set");
- return 0;
+ goto done;
}
if (is_add && !conn_set && action == ~0)
{
vlib_cli_output (vm, "connection and action must be set for add");
- return 0;
+ goto done;
}
if (!is_add && !tag && !conn_set)
{
vlib_cli_output (vm, "connection or tag must be set for delete");
- return 0;
+ goto done;
}
if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
{
vlib_cli_output (vm, "tag too long (max u64)");
- return 0;
+ goto done;
}
if (ns_id)
if (!app_ns)
{
vlib_cli_output (vm, "namespace %v does not exist", ns_id);
- return 0;
+ goto done;
}
}
else
fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
session_rule_add_del_args_t args = {
+ .transport_proto = proto,
.table_args.lcl.fp_addr = lcl_ip,
.table_args.lcl.fp_len = lcl_plen,
.table_args.lcl.fp_proto = fib_proto,
.scope = scope,
};
if ((rv = vnet_session_rule_add_del (&args)))
- return clib_error_return (0, "rule add del returned %u", rv);
+ error = clib_error_return (0, "rule add del returned %u", rv);
+done:
+ vec_free (ns_id);
vec_free (tag);
- return 0;
+ return error;
}
/* *INDENT-OFF* */
session_table_t *st;
u8 *ns_id = 0, fib_proto;
+ session_cli_return_if_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)