#include <vppinfra/bihash_template.c>
#include "fa_node.h"
+#include "hash_lookup.h"
typedef struct
{
}
int
-acl_match_5tuple (acl_main_t * am, u32 acl_index, fa_5tuple_t * pkt_5tuple,
+single_acl_match_5tuple (acl_main_t * am, u32 acl_index, fa_5tuple_t * pkt_5tuple,
int is_ip6, u8 * r_action, u32 * r_acl_match_p,
u32 * r_rule_match_p, u32 * trace_bitmap)
{
}
static u8
-full_acl_match_5tuple (u32 sw_if_index, fa_5tuple_t * pkt_5tuple, int is_l2,
+linear_multi_acl_match_5tuple (u32 sw_if_index, fa_5tuple_t * pkt_5tuple, int is_l2,
int is_ip6, int is_input, u32 * acl_match_p,
u32 * rule_match_p, u32 * trace_bitmap)
{
clib_warning ("ACL_FA_NODE_DBG: Trying to match ACL: %d",
acl_vector[i]);
#endif
- if (acl_match_5tuple
+ if (single_acl_match_5tuple
(am, acl_vector[i], pkt_5tuple, is_ip6, &action,
acl_match_p, rule_match_p, trace_bitmap))
{
return 0;
}
+static u8
+multi_acl_match_5tuple (u32 sw_if_index, fa_5tuple_t * pkt_5tuple, int is_l2,
+ int is_ip6, int is_input, u32 * acl_match_p,
+ u32 * rule_match_p, u32 * trace_bitmap)
+{
+ acl_main_t *am = &acl_main;
+ if (am->use_hash_acl_matching) {
+ return hash_multi_acl_match_5tuple(sw_if_index, pkt_5tuple, is_l2, is_ip6,
+ is_input, acl_match_p, rule_match_p, trace_bitmap);
+ } else {
+ return linear_multi_acl_match_5tuple(sw_if_index, pkt_5tuple, is_l2, is_ip6,
+ is_input, acl_match_p, rule_match_p, trace_bitmap);
+ }
+}
+
static int
offset_within_packet (vlib_buffer_t * b0, int offset)
{
static int
acl_fa_ifc_has_sessions (acl_main_t * am, int sw_if_index0)
{
- int has_sessions =
- clib_bitmap_get (am->fa_sessions_on_sw_if_index, sw_if_index0);
- return has_sessions;
+ return am->fa_sessions_hash_is_initialized;
}
static int
sw_if_index0, am->fa_conn_table_hash_num_buckets,
am->fa_conn_table_hash_memory_size);
#endif
- vec_validate (am->fa_sessions_by_sw_if_index, sw_if_index0);
- BV (clib_bihash_init) (&am->fa_sessions_by_sw_if_index
- [sw_if_index0], "ACL plugin FA session bihash",
+ BV (clib_bihash_init) (&am->fa_sessions_hash,
+ "ACL plugin FA session bihash",
am->fa_conn_table_hash_num_buckets,
am->fa_conn_table_hash_memory_size);
- am->fa_sessions_on_sw_if_index =
- clib_bitmap_set (am->fa_sessions_on_sw_if_index, sw_if_index0, 1);
+ am->fa_sessions_hash_is_initialized = 1;
}
static inline fa_session_t *get_session_ptr(acl_main_t *am, u16 thread_index, u32 session_index)
{
fa_session_t *sess = get_session_ptr(am, sess_id.thread_index, sess_id.session_index);
ASSERT(sess->thread_index == os_get_thread_index ());
- BV (clib_bihash_add_del) (&am->fa_sessions_by_sw_if_index[sw_if_index],
+ BV (clib_bihash_add_del) (&am->fa_sessions_hash,
&sess->info.kv, 0);
acl_fa_per_worker_data_t *pw = &am->per_worker_data[sess_id.thread_index];
pool_put_index (pw->fa_sessions_pool, sess_id.session_index);
as the caller must have dealt with the timers. */
vec_validate (am->fa_session_dels_by_sw_if_index, sw_if_index);
am->fa_session_dels_by_sw_if_index[sw_if_index]++;
+ clib_smp_atomic_add(&am->fa_session_total_dels, 1);
}
static int
acl_fa_can_add_session (acl_main_t * am, int is_input, u32 sw_if_index)
{
- u64 curr_sess;
- vec_validate (am->fa_session_adds_by_sw_if_index, sw_if_index);
- vec_validate (am->fa_session_dels_by_sw_if_index, sw_if_index);
- curr_sess =
- am->fa_session_adds_by_sw_if_index[sw_if_index] -
- am->fa_session_dels_by_sw_if_index[sw_if_index];
- return (curr_sess < am->fa_conn_table_max_entries);
+ u64 curr_sess_count;
+ curr_sess_count = am->fa_session_total_adds - am->fa_session_total_dels;
+ return (curr_sess_count < am->fa_conn_table_max_entries);
}
static u64
acl_fa_ifc_init_sessions (am, sw_if_index);
}
- BV (clib_bihash_add_del) (&am->fa_sessions_by_sw_if_index[sw_if_index],
+ BV (clib_bihash_add_del) (&am->fa_sessions_hash,
&kv, 1);
acl_fa_conn_list_add_session(am, f_sess_id, now);
vec_validate (am->fa_session_adds_by_sw_if_index, sw_if_index);
am->fa_session_adds_by_sw_if_index[sw_if_index]++;
+ clib_smp_atomic_add(&am->fa_session_total_adds, 1);
}
static int
clib_bihash_kv_40_8_t * pvalue_sess)
{
return (BV (clib_bihash_search)
- (&am->fa_sessions_by_sw_if_index[sw_if_index0], &p5tuple->kv,
+ (&am->fa_sessions_hash, &p5tuple->kv,
pvalue_sess) == 0);
}
*/
acl_fill_5tuple (am, b0, is_ip6, is_input, is_l2_path, &fa_5tuple);
+ fa_5tuple.l4.lsb_of_sw_if_index = sw_if_index0 & 0xffff;
acl_make_5tuple_session_key (is_input, &fa_5tuple, &kv_sess);
+ fa_5tuple.pkt.sw_if_index = sw_if_index0;
+ fa_5tuple.pkt.is_ip6 = is_ip6;
+ fa_5tuple.pkt.is_input = is_input;
+ fa_5tuple.pkt.mask_type_index_lsb = ~0;
#ifdef FA_NODE_VERBOSE_DEBUG
clib_warning
("ACL_FA_NODE_DBG: session 5-tuple %016llx %016llx %016llx %016llx %016llx : %016llx",
0x00010000 + ((0xff & old_timeout_type) << 8) +
(0xff & new_timeout_type);
}
+ /*
+ * I estimate the likelihood to be very low - the VPP needs
+ * to have >64K interfaces to start with and then on
+ * exactly 64K indices apart needs to be exactly the same
+ * 5-tuple... Anyway, since this probability is nonzero -
+ * print an error and drop the unlucky packet.
+ * If this shows up in real world, we would need to bump
+ * the hash key length.
+ */
+ if (PREDICT_FALSE(sess->sw_if_index != sw_if_index0)) {
+ clib_warning("BUG: session LSB16(sw_if_index) and 5-tuple collision!");
+ acl_check_needed = 0;
+ action = 0;
+ }
}
}
if (acl_check_needed)
{
action =
- full_acl_match_5tuple (sw_if_index0, &fa_5tuple, is_l2_path,
+ multi_acl_match_5tuple (sw_if_index0, &fa_5tuple, is_l2_path,
is_ip6, is_input, &match_acl_in_index,
&match_rule_index, &trace_bitmap);
error0 = action;
}
}
+void
+show_fa_sessions_hash(vlib_main_t * vm, u32 verbose)
+{
+ acl_main_t *am = &acl_main;
+ if (am->fa_sessions_hash_is_initialized) {
+ vlib_cli_output(vm, "\nSession lookup hash table:\n%U\n\n",
+ BV (format_bihash), &am->fa_sessions_hash, verbose);
+ } else {
+ vlib_cli_output(vm, "\nSession lookup hash table is not allocated.\n\n");
+ }
+}
/* *INDENT-OFF* */