#define foreach_acl_plugin_api_msg \
_(ACL_PLUGIN_GET_VERSION, acl_plugin_get_version) \
+_(ACL_PLUGIN_CONTROL_PING, acl_plugin_control_ping) \
_(ACL_ADD_REPLACE, acl_add_replace) \
_(ACL_DEL, acl_del) \
_(ACL_INTERFACE_ADD_DEL, acl_interface_add_del) \
vl_msg_api_send_shmem (q, (u8 *) & rmp);
}
+static void
+vl_api_acl_plugin_control_ping_t_handler (vl_api_acl_plugin_control_ping_t * mp)
+{
+ vl_api_acl_plugin_control_ping_reply_t *rmp;
+ acl_main_t *am = &acl_main;
+ int rv = 0;
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_ACL_PLUGIN_CONTROL_PING_REPLY,
+ ({
+ rmp->vpe_pid = ntohl (getpid ());
+ }));
+ /* *INDENT-ON* */
+}
static int
acl_add_list (u32 count, vl_api_acl_rule_t rules[],
}
static int
-acl_classify_add_del_table_big (vnet_classify_main_t * cm, u8 * mask,
+acl_classify_add_del_table_tiny (vnet_classify_main_t * cm, u8 * mask,
u32 mask_len, u32 next_table_index,
u32 miss_next_index, u32 * table_index,
int is_add)
{
- u32 nbuckets = 65536;
- u32 memory_size = 2 << 30;
+ u32 nbuckets = 1;
+ u32 memory_size = 2 << 13;
u32 skip = count_skip (mask, mask_len);
u32 match = (mask_len / 16) - skip;
u8 *skip_mask_ptr = mask + 16 * skip;
ip4_table_index =
am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index];
am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index] = ~0;
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip4,
&ip4_table_index, 0);
ip6_table_index =
am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index];
am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index] = ~0;
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip6,
&ip6_table_index, 0);
ip4_table_index =
am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index];
am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index] = ~0;
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip4,
&ip4_table_index, 0);
ip6_table_index =
am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index];
am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index] = ~0;
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip6,
&ip6_table_index, 0);
/* in case there were previous tables attached */
acl_unhook_l2_input_classify (am, sw_if_index);
rv =
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip4,
&ip4_table_index, 1);
if (rv)
return rv;
rv =
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip6,
&ip6_table_index, 1);
if (rv)
{
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip4,
&ip4_table_index, 0);
sw_if_index, ip4_table_index, ip6_table_index);
if (rv)
{
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip6,
&ip6_table_index, 0);
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_input_classify_next_acl_ip4,
&ip4_table_index, 0);
/* in case there were previous tables attached */
acl_unhook_l2_output_classify (am, sw_if_index);
rv =
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip4,
&ip4_table_index, 1);
if (rv)
return rv;
rv =
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip6,
&ip6_table_index, 1);
if (rv)
{
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip4,
&ip4_table_index, 0);
sw_if_index, ip4_table_index, ip6_table_index);
if (rv)
{
- acl_classify_add_del_table_big (cm, ip6_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
sizeof (ip6_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip6,
&ip6_table_index, 0);
- acl_classify_add_del_table_big (cm, ip4_5tuple_mask,
+ acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
sizeof (ip4_5tuple_mask) - 1, ~0,
am->l2_output_classify_next_acl_ip4,
&ip4_table_index, 0);
return rv;
}
+/*
+ * If the client does not allocate enough memory for a variable-length
+ * message, and then proceed to use it as if the full memory allocated,
+ * absent the check we happily consume that on the VPP side, and go
+ * along as if nothing happened. However, the resulting
+ * effects range from just garbage in the API decode
+ * (because the decoder snoops too far), to potential memory
+ * corruptions.
+ *
+ * This verifies that the actual length of the message is
+ * at least expected_len, and complains loudly if it is not.
+ *
+ * A failing check here is 100% a software bug on the API user side,
+ * so we might as well yell.
+ *
+ */
+static int verify_message_len(void *mp, u32 expected_len, char *where)
+{
+ u32 supplied_len = vl_msg_api_get_msg_length (mp);
+ if (supplied_len < expected_len) {
+ clib_warning("%s: Supplied message length %d is less than expected %d",
+ where, supplied_len, expected_len);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
/* API message handler */
static void
vl_api_acl_add_replace_t_handler (vl_api_acl_add_replace_t * mp)
acl_main_t *am = &acl_main;
int rv;
u32 acl_list_index = ntohl (mp->acl_index);
+ u32 acl_count = ntohl (mp->count);
+ u32 expected_len = sizeof(*mp) + acl_count*sizeof(mp->r[0]);
- rv = acl_add_list (ntohl (mp->count), mp->r, &acl_list_index, mp->tag);
+ if (verify_message_len(mp, expected_len, "acl_add_replace")) {
+ rv = acl_add_list (acl_count, mp->r, &acl_list_index, mp->tag);
+ } else {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_ACL_ADD_REPLACE_REPLY,
acl_main_t *am = &acl_main;
int rv;
u32 acl_list_index = ~0;
+ u32 acl_count = ntohl (mp->count);
+ u32 expected_len = sizeof(*mp) + acl_count*sizeof(mp->r[0]);
- rv =
- macip_acl_add_list (ntohl (mp->count), mp->r, &acl_list_index, mp->tag);
+ if (verify_message_len(mp, expected_len, "macip_acl_add")) {
+ rv = macip_acl_add_list (acl_count, mp->r, &acl_list_index, mp->tag);
+ } else {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_MACIP_ACL_ADD_REPLY,
if (0 == is_add) {
vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index,
ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX, sw_if_index);
+ /* also unapply any ACLs in case the users did not do so. */
+ macip_acl_interface_del_acl(am, sw_if_index);
+ acl_interface_reset_inout_acls (sw_if_index, 0);
+ acl_interface_reset_inout_acls (sw_if_index, 1);
}
return 0;
}
return error;
}
+
static clib_error_t *
acl_show_aclplugin_fn (vlib_main_t * vm,
unformat_input_t * input,
if (unformat (input, "sessions"))
{
u8 * out0 = 0;
+ u16 wk;
pool_foreach (swif, im->sw_interfaces,
({
u32 sw_if_index = swif->sw_if_index;
u64 n_dels = sw_if_index < vec_len(am->fa_session_dels_by_sw_if_index) ? am->fa_session_dels_by_sw_if_index[sw_if_index] : 0;
out0 = format(out0, "sw_if_index %d: add %lu - del %lu = %lu\n", sw_if_index, n_adds, n_dels, n_adds - n_dels);
}));
+ {
+ u64 n_adds = am->fa_session_total_adds;
+ u64 n_dels = am->fa_session_total_dels;
+ out0 = format(out0, "TOTAL: add %lu - del %lu = %lu\n", n_adds, n_dels, n_adds - n_dels);
+ }
+ out0 = format(out0, "\n\nPer-worker data:\n");
+ for (wk = 0; wk < vec_len (am->per_worker_data); wk++) {
+ acl_fa_per_worker_data_t *pw = &am->per_worker_data[wk];
+ out0 = format(out0, "Worker #%d:\n", wk);
+ out0 = format(out0, " Next expiry time: %lu\n", pw->next_expiry_time);
+ out0 = format(out0, " Requeue until time: %lu\n", pw->requeue_until_time);
+ out0 = format(out0, " Current time wait interval: %lu\n", pw->current_time_wait_interval);
+ out0 = format(out0, " Count of deleted sessions: %lu\n", pw->cnt_deleted_sessions);
+ out0 = format(out0, " Delete already deleted: %lu\n", pw->cnt_already_deleted_sessions);
+ out0 = format(out0, " Session timers restarted: %lu\n", pw->cnt_session_timer_restarted);
+ out0 = format(out0, " Swipe until this time: %lu\n", pw->swipe_end_time);
+ out0 = format(out0, " sw_if_index serviced bitmap: %U\n", format_bitmap_hex, pw->serviced_sw_if_index_bitmap);
+ out0 = format(out0, " pending clear intfc bitmap : %U\n", format_bitmap_hex, pw->pending_clear_sw_if_index_bitmap);
+ out0 = format(out0, " clear in progress: %u\n", pw->clear_in_process);
+ out0 = format(out0, " interrupt is pending: %d\n", pw->interrupt_is_pending);
+ out0 = format(out0, " interrupt is needed: %d\n", pw->interrupt_is_needed);
+ out0 = format(out0, " interrupt is unwanted: %d\n", pw->interrupt_is_unwanted);
+ }
out0 = format(out0, "\n\nConn cleaner thread counters:\n");
#define _(cnt, desc) out0 = format(out0, " %20lu: %s\n", am->cnt, desc);
foreach_fa_cleaner_counter;
am->fa_conn_table_hash_num_buckets = ACL_FA_CONN_TABLE_DEFAULT_HASH_NUM_BUCKETS;
am->fa_conn_table_hash_memory_size = ACL_FA_CONN_TABLE_DEFAULT_HASH_MEMORY_SIZE;
am->fa_conn_table_max_entries = ACL_FA_CONN_TABLE_DEFAULT_MAX_ENTRIES;
-
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+ vec_validate(am->per_worker_data, tm->n_vlib_mains-1);
{
+ u16 wk;
u8 tt;
- for(tt = 0; tt < ACL_N_TIMEOUTS; tt++) {
- am->fa_conn_list_head[tt] = ~0;
- am->fa_conn_list_tail[tt] = ~0;
+ for (wk = 0; wk < vec_len (am->per_worker_data); wk++) {
+ acl_fa_per_worker_data_t *pw = &am->per_worker_data[wk];
+ vec_validate(pw->fa_conn_list_head, ACL_N_TIMEOUTS-1);
+ vec_validate(pw->fa_conn_list_tail, ACL_N_TIMEOUTS-1);
+ for(tt = 0; tt < ACL_N_TIMEOUTS; tt++) {
+ pw->fa_conn_list_head[tt] = ~0;
+ pw->fa_conn_list_tail[tt] = ~0;
+ }
}
}
am->fa_cleaner_cnt_delete_by_sw_index = 0;
am->fa_cleaner_cnt_delete_by_sw_index_ok = 0;
am->fa_cleaner_cnt_unknown_event = 0;
- am->fa_cleaner_cnt_deleted_sessions = 0;
am->fa_cleaner_cnt_timer_restarted = 0;
am->fa_cleaner_cnt_wait_with_timeout = 0;