+ if (i < vec_len (am->input_sw_if_index_vec_by_acl))
+ {
+ vlib_cli_output (vm, " applied inbound on sw_if_index: %U\n",
+ format_vec32, am->input_sw_if_index_vec_by_acl[i],
+ "%d");
+ }
+ if (i < vec_len (am->output_sw_if_index_vec_by_acl))
+ {
+ vlib_cli_output (vm, " applied outbound on sw_if_index: %U\n",
+ format_vec32, am->output_sw_if_index_vec_by_acl[i],
+ "%d");
+ }
+ if (i < vec_len (am->lc_index_vec_by_acl))
+ {
+ vlib_cli_output (vm, " used in lookup context index: %U\n",
+ format_vec32, am->lc_index_vec_by_acl[i], "%d");
+ }
+ }
+}
+
+static clib_error_t *
+acl_show_aclplugin_acl_fn (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ acl_main_t *am = &acl_main;
+
+ u32 acl_index = ~0;
+ (void) unformat (input, "index %u", &acl_index);
+
+ acl_plugin_show_acl (am, acl_index);
+ return error;
+}
+
+static clib_error_t *
+acl_show_aclplugin_lookup_context_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+
+ u32 lc_index = ~0;
+ (void) unformat (input, "index %u", &lc_index);
+
+ acl_plugin_show_lookup_context (lc_index);
+ return error;
+}
+
+static clib_error_t *
+acl_show_aclplugin_lookup_user_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+
+ u32 lc_index = ~0;
+ (void) unformat (input, "index %u", &lc_index);
+
+ acl_plugin_show_lookup_user (lc_index);
+ return error;
+}
+
+
+static void
+acl_plugin_show_interface (acl_main_t * am, u32 sw_if_index, int show_acl,
+ int detail)
+{
+ vlib_main_t *vm = am->vlib_main;
+ u32 swi;
+ u32 *pj;
+ for (swi = 0; (swi < vec_len (am->input_acl_vec_by_sw_if_index)) ||
+ (swi < vec_len (am->output_acl_vec_by_sw_if_index)); swi++)
+ {
+ /* if we need a particular interface, skip all the others */
+ if ((sw_if_index != ~0) && (sw_if_index != swi))
+ continue;
+
+ vlib_cli_output (vm, "sw_if_index %d:\n", swi);
+ if (swi < vec_len (am->input_policy_epoch_by_sw_if_index))
+ vlib_cli_output (vm, " input policy epoch: %x\n",
+ vec_elt (am->input_policy_epoch_by_sw_if_index,
+ swi));
+ if (swi < vec_len (am->output_policy_epoch_by_sw_if_index))
+ vlib_cli_output (vm, " output policy epoch: %x\n",
+ vec_elt (am->output_policy_epoch_by_sw_if_index,
+ swi));
+
+
+ if (intf_has_etype_whitelist (am, swi, 1))
+ {
+ vlib_cli_output (vm, " input etype whitelist: %U", format_vec16,
+ am->input_etype_whitelist_by_sw_if_index[swi],
+ "%04x");
+ }
+ if (intf_has_etype_whitelist (am, swi, 0))
+ {
+ vlib_cli_output (vm, " output etype whitelist: %U", format_vec16,
+ am->output_etype_whitelist_by_sw_if_index[swi],
+ "%04x");
+ }
+
+ if ((swi < vec_len (am->input_acl_vec_by_sw_if_index)) &&
+ (vec_len (am->input_acl_vec_by_sw_if_index[swi]) > 0))
+ {
+ vlib_cli_output (vm, " input acl(s): %U", format_vec32,
+ am->input_acl_vec_by_sw_if_index[swi], "%d");
+ if (show_acl)
+ {
+ vlib_cli_output (vm, "\n");
+ vec_foreach (pj, am->input_acl_vec_by_sw_if_index[swi])
+ {
+ acl_print_acl (vm, am, *pj);
+ }
+ vlib_cli_output (vm, "\n");
+ }
+ }
+
+ if ((swi < vec_len (am->output_acl_vec_by_sw_if_index)) &&
+ (vec_len (am->output_acl_vec_by_sw_if_index[swi]) > 0))
+ {
+ vlib_cli_output (vm, " output acl(s): %U", format_vec32,
+ am->output_acl_vec_by_sw_if_index[swi], "%d");
+ if (show_acl)
+ {
+ vlib_cli_output (vm, "\n");
+ vec_foreach (pj, am->output_acl_vec_by_sw_if_index[swi])
+ {
+ acl_print_acl (vm, am, *pj);
+ }
+ vlib_cli_output (vm, "\n");
+ }
+ }
+ if (detail && (swi < vec_len (am->input_lc_index_by_sw_if_index)))
+ {
+ vlib_cli_output (vm, " input lookup context index: %d",
+ am->input_lc_index_by_sw_if_index[swi]);
+ }
+ if (detail && (swi < vec_len (am->output_lc_index_by_sw_if_index)))
+ {
+ vlib_cli_output (vm, " output lookup context index: %d",
+ am->output_lc_index_by_sw_if_index[swi]);
+ }
+ }
+
+}
+
+
+static clib_error_t *
+acl_show_aclplugin_decode_5tuple_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ u64 five_tuple[6] = { 0, 0, 0, 0, 0, 0 };
+
+ if (unformat
+ (input, "%llx %llx %llx %llx %llx %llx", &five_tuple[0], &five_tuple[1],
+ &five_tuple[2], &five_tuple[3], &five_tuple[4], &five_tuple[5]))
+ vlib_cli_output (vm, "5-tuple structure decode: %U\n\n",
+ format_acl_plugin_5tuple, five_tuple);
+ else
+ error = clib_error_return (0, "expecting 6 hex integers");
+ return error;
+}
+
+
+static clib_error_t *
+acl_show_aclplugin_interface_fn (vlib_main_t * vm,
+ unformat_input_t *
+ input, vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ acl_main_t *am = &acl_main;
+
+ u32 sw_if_index = ~0;
+ (void) unformat (input, "sw_if_index %u", &sw_if_index);
+ int show_acl = unformat (input, "acl");
+ int detail = unformat (input, "detail");
+
+ acl_plugin_show_interface (am, sw_if_index, show_acl, detail);
+ return error;
+}
+
+static clib_error_t *
+acl_show_aclplugin_memory_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ acl_main_t *am = &acl_main;
+
+ vlib_cli_output (vm, "ACL plugin main heap statistics:\n");
+ if (am->acl_mheap)
+ {
+ vlib_cli_output (vm, " %U\n", format_mheap, am->acl_mheap, 1);
+ }
+ else
+ {
+ vlib_cli_output (vm, " Not initialized\n");
+ }
+ vlib_cli_output (vm, "ACL hash lookup support heap statistics:\n");
+ if (am->hash_lookup_mheap)
+ {
+ vlib_cli_output (vm, " %U\n", format_mheap, am->hash_lookup_mheap, 1);
+ }
+ else
+ {
+ vlib_cli_output (vm, " Not initialized\n");
+ }
+ return error;
+}
+
+static void
+acl_plugin_show_sessions (acl_main_t * am,
+ u32 show_session_thread_id,
+ u32 show_session_session_index)
+{
+ vlib_main_t *vm = am->vlib_main;
+ u16 wk;
+ vnet_interface_main_t *im = &am->vnet_main->interface_main;
+ vnet_sw_interface_t *swif;
+ u64 now = clib_cpu_time_now ();
+ u64 clocks_per_second = am->vlib_main->clib_time.clocks_per_second;
+
+ {
+ u64 n_adds = am->fa_session_total_adds;
+ u64 n_dels = am->fa_session_total_dels;
+ u64 n_deact = am->fa_session_total_deactivations;
+ vlib_cli_output (vm, "Sessions total: add %lu - del %lu = %lu", n_adds,
+ n_dels, n_adds - n_dels);
+ vlib_cli_output (vm, "Sessions active: add %lu - deact %lu = %lu", n_adds,
+ n_deact, n_adds - n_deact);
+ vlib_cli_output (vm, "Sessions being purged: deact %lu - del %lu = %lu",
+ n_deact, n_dels, n_deact - n_dels);
+ }
+ vlib_cli_output (vm, "now: %lu clocks per second: %lu", now,
+ clocks_per_second);
+ vlib_cli_output (vm, "\n\nPer-thread data:");
+ for (wk = 0; wk < vec_len (am->per_worker_data); wk++)
+ {
+ acl_fa_per_worker_data_t *pw = &am->per_worker_data[wk];
+ vlib_cli_output (vm, "Thread #%d:", wk);
+ if (show_session_thread_id == wk
+ && show_session_session_index < pool_len (pw->fa_sessions_pool))
+ {
+ vlib_cli_output (vm, " session index %u:",
+ show_session_session_index);
+ fa_session_t *sess =
+ pw->fa_sessions_pool + show_session_session_index;
+ u64 *m = (u64 *) & sess->info;
+ vlib_cli_output (vm,
+ " info: %016llx %016llx %016llx %016llx %016llx %016llx",
+ m[0], m[1], m[2], m[3], m[4], m[5]);
+ vlib_cli_output (vm, " sw_if_index: %u", sess->sw_if_index);
+ vlib_cli_output (vm, " tcp_flags_seen: %x",
+ sess->tcp_flags_seen.as_u16);
+ vlib_cli_output (vm, " last active time: %lu",
+ sess->last_active_time);
+ vlib_cli_output (vm, " thread index: %u", sess->thread_index);
+ vlib_cli_output (vm, " link enqueue time: %lu",
+ sess->link_enqueue_time);
+ vlib_cli_output (vm, " link next index: %u",
+ sess->link_next_idx);
+ vlib_cli_output (vm, " link prev index: %u",
+ sess->link_prev_idx);
+ vlib_cli_output (vm, " link list id: %u", sess->link_list_id);
+ }
+ vlib_cli_output (vm, " connection add/del stats:", wk);
+ /* *INDENT-OFF* */
+ pool_foreach (swif, im->sw_interfaces,
+ ({
+ u32 sw_if_index = swif->sw_if_index;
+ u64 n_adds =
+ (sw_if_index < vec_len (pw->fa_session_adds_by_sw_if_index) ?
+ pw->fa_session_adds_by_sw_if_index[sw_if_index] :
+ 0);
+ u64 n_dels =
+ (sw_if_index < vec_len (pw->fa_session_dels_by_sw_if_index) ?
+ pw->fa_session_dels_by_sw_if_index[sw_if_index] :
+ 0);
+ u64 n_epoch_changes =
+ (sw_if_index < vec_len (pw->fa_session_epoch_change_by_sw_if_index) ?
+ pw->fa_session_epoch_change_by_sw_if_index[sw_if_index] :
+ 0);
+ vlib_cli_output (vm,
+ " sw_if_index %d: add %lu - del %lu = %lu; epoch chg: %lu",
+ sw_if_index,
+ n_adds,
+ n_dels,
+ n_adds -
+ n_dels,
+ n_epoch_changes);
+ }));
+ /* *INDENT-ON* */
+
+ vlib_cli_output (vm, " connection timeout type lists:", wk);
+ u8 tt = 0;
+ for (tt = 0; tt < ACL_N_TIMEOUTS; tt++)
+ {
+ u32 head_session_index = pw->fa_conn_list_head[tt];
+ vlib_cli_output (vm, " fa_conn_list_head[%d]: %d", tt,
+ head_session_index);
+ if (~0 != head_session_index)
+ {
+ fa_session_t *sess = pw->fa_sessions_pool + head_session_index;
+ vlib_cli_output (vm, " last active time: %lu",
+ sess->last_active_time);
+ vlib_cli_output (vm, " link enqueue time: %lu",
+ sess->link_enqueue_time);
+ }
+ }
+
+ vlib_cli_output (vm, " Next expiry time: %lu", pw->next_expiry_time);
+ vlib_cli_output (vm, " Requeue until time: %lu",
+ pw->requeue_until_time);
+ vlib_cli_output (vm, " Current time wait interval: %lu",
+ pw->current_time_wait_interval);
+ vlib_cli_output (vm, " Count of deleted sessions: %lu",
+ pw->cnt_deleted_sessions);
+ vlib_cli_output (vm, " Delete already deleted: %lu",
+ pw->cnt_already_deleted_sessions);
+ vlib_cli_output (vm, " Session timers restarted: %lu",
+ pw->cnt_session_timer_restarted);
+ vlib_cli_output (vm, " Swipe until this time: %lu",
+ pw->swipe_end_time);
+ vlib_cli_output (vm, " sw_if_index serviced bitmap: %U",
+ format_bitmap_hex, pw->serviced_sw_if_index_bitmap);
+ vlib_cli_output (vm, " pending clear intfc bitmap : %U",
+ format_bitmap_hex,
+ pw->pending_clear_sw_if_index_bitmap);
+ vlib_cli_output (vm, " clear in progress: %u", pw->clear_in_process);
+ vlib_cli_output (vm, " interrupt is pending: %d",
+ pw->interrupt_is_pending);
+ vlib_cli_output (vm, " interrupt is needed: %d",
+ pw->interrupt_is_needed);
+ vlib_cli_output (vm, " interrupt is unwanted: %d",
+ pw->interrupt_is_unwanted);
+ vlib_cli_output (vm, " interrupt generation: %d",
+ pw->interrupt_generation);
+ vlib_cli_output (vm, " received session change requests: %d",
+ pw->rcvd_session_change_requests);
+ vlib_cli_output (vm, " sent session change requests: %d",
+ pw->sent_session_change_requests);
+ }
+ vlib_cli_output (vm, "\n\nConn cleaner thread counters:");
+#define _(cnt, desc) vlib_cli_output(vm, " %20lu: %s", am->cnt, desc);
+ foreach_fa_cleaner_counter;
+#undef _
+ vlib_cli_output (vm, "Interrupt generation: %d",
+ am->fa_interrupt_generation);
+ vlib_cli_output (vm,
+ "Sessions per interval: min %lu max %lu increment: %f ms current: %f ms",
+ am->fa_min_deleted_sessions_per_interval,
+ am->fa_max_deleted_sessions_per_interval,
+ am->fa_cleaner_wait_time_increment * 1000.0,
+ ((f64) am->fa_current_cleaner_timer_wait_interval) *
+ 1000.0 / (f64) vm->clib_time.clocks_per_second);
+ vlib_cli_output (vm, "Reclassify sessions: %d", am->reclassify_sessions);
+}
+
+static clib_error_t *
+acl_show_aclplugin_sessions_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ acl_main_t *am = &acl_main;
+
+ u32 show_bihash_verbose = 0;
+ u32 show_session_thread_id = ~0;
+ u32 show_session_session_index = ~0;
+ (void) unformat (input, "thread %u index %u", &show_session_thread_id,
+ &show_session_session_index);
+ (void) unformat (input, "verbose %u", &show_bihash_verbose);
+
+ acl_plugin_show_sessions (am, show_session_thread_id,
+ show_session_session_index);
+ show_fa_sessions_hash (vm, show_bihash_verbose);
+ return error;
+}
+
+static clib_error_t *
+acl_show_aclplugin_tables_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+
+ u32 acl_index = ~0;
+ u32 lc_index = ~0;
+ int show_acl_hash_info = 0;
+ int show_applied_info = 0;
+ int show_mask_type = 0;
+ int show_bihash = 0;
+ u32 show_bihash_verbose = 0;
+
+ if (unformat (input, "acl"))
+ {
+ show_acl_hash_info = 1;
+ /* mask-type is handy to see as well right there */
+ show_mask_type = 1;
+ unformat (input, "index %u", &acl_index);
+ }
+ else if (unformat (input, "applied"))
+ {
+ show_applied_info = 1;
+ unformat (input, "lc_index %u", &lc_index);
+ }
+ else if (unformat (input, "mask"))
+ {
+ show_mask_type = 1;
+ }
+ else if (unformat (input, "hash"))
+ {
+ show_bihash = 1;
+ unformat (input, "verbose %u", &show_bihash_verbose);
+ }
+
+ if (!
+ (show_mask_type || show_acl_hash_info || show_applied_info
+ || show_bihash))
+ {
+ /* if no qualifiers specified, show all */
+ show_mask_type = 1;
+ show_acl_hash_info = 1;
+ show_applied_info = 1;
+ show_bihash = 1;
+ }
+ vlib_cli_output (vm, "Stats counters enabled for interface ACLs: %d",
+ acl_main.interface_acl_counters_enabled);
+ if (show_mask_type)
+ acl_plugin_show_tables_mask_type ();
+ if (show_acl_hash_info)
+ acl_plugin_show_tables_acl_hash_info (acl_index);
+ if (show_applied_info)
+ acl_plugin_show_tables_applied_info (lc_index);
+ if (show_bihash)
+ acl_plugin_show_tables_bihash (show_bihash_verbose);
+
+ return error;
+}
+
+static clib_error_t *
+acl_clear_aclplugin_fn (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ clib_error_t *error = 0;
+ acl_main_t *am = &acl_main;
+ vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index,
+ ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX, ~0);
+ return error;
+}
+
+ /* *INDENT-OFF* */
+VLIB_CLI_COMMAND (aclplugin_set_command, static) = {
+ .path = "set acl-plugin",
+ .short_help = "set acl-plugin session timeout {{udp idle}|tcp {idle|transient}} <seconds>",
+ .function = acl_set_aclplugin_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_acl_command, static) = {
+ .path = "show acl-plugin acl",
+ .short_help = "show acl-plugin acl [index N]",
+ .function = acl_show_aclplugin_acl_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_lookup_context_command, static) = {
+ .path = "show acl-plugin lookup context",
+ .short_help = "show acl-plugin lookup context [index N]",
+ .function = acl_show_aclplugin_lookup_context_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_lookup_user_command, static) = {
+ .path = "show acl-plugin lookup user",
+ .short_help = "show acl-plugin lookup user [index N]",
+ .function = acl_show_aclplugin_lookup_user_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_decode_5tuple_command, static) = {
+ .path = "show acl-plugin decode 5tuple",
+ .short_help = "show acl-plugin decode 5tuple XXXX XXXX XXXX XXXX XXXX XXXX",
+ .function = acl_show_aclplugin_decode_5tuple_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_interface_command, static) = {
+ .path = "show acl-plugin interface",
+ .short_help = "show acl-plugin interface [sw_if_index N] [acl]",
+ .function = acl_show_aclplugin_interface_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_memory_command, static) = {
+ .path = "show acl-plugin memory",
+ .short_help = "show acl-plugin memory",
+ .function = acl_show_aclplugin_memory_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_sessions_command, static) = {
+ .path = "show acl-plugin sessions",
+ .short_help = "show acl-plugin sessions",
+ .function = acl_show_aclplugin_sessions_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_tables_command, static) = {
+ .path = "show acl-plugin tables",
+ .short_help = "show acl-plugin tables [ acl [index N] | applied [ lc_index N ] | mask | hash [verbose N] ]",
+ .function = acl_show_aclplugin_tables_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_macip_acl_command, static) = {
+ .path = "show acl-plugin macip acl",
+ .short_help = "show acl-plugin macip acl [index N]",
+ .function = acl_show_aclplugin_macip_acl_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_show_macip_interface_command, static) = {
+ .path = "show acl-plugin macip interface",
+ .short_help = "show acl-plugin macip interface",
+ .function = acl_show_aclplugin_macip_interface_fn,
+};
+
+VLIB_CLI_COMMAND (aclplugin_clear_command, static) = {
+ .path = "clear acl-plugin sessions",
+ .short_help = "clear acl-plugin sessions",
+ .function = acl_clear_aclplugin_fn,
+};
+
+/*?
+ * [un]Apply an ACL to an interface.
+ * The ACL is applied in a given direction, either input or output.
+ * The ACL being applied must already exist.
+ *
+ * @cliexpar
+ * <b><em> set acl-plugin interface <input|output> acl <index> [del] </b></em>
+ * @cliexend
+ ?*/
+VLIB_CLI_COMMAND (aclplugin_set_interface_command, static) = {
+ .path = "set acl-plugin interface",
+ .short_help = "set acl-plugin interface <interface> <input|output> <acl INDEX> [del] ",
+ .function = acl_set_aclplugin_interface_fn,
+};
+
+/*?
+ * Create an Access Control List (ACL)
+ * an ACL is composed of more than one Access control element (ACE). Multiple
+ * ACEs can be specified with this command using a comma separated list.
+ *
+ * Each ACE describes a tuple of src+dst IP prefix, ip protocol, src+dst port ranges.
+ * (the ACL plugin also support ICMP types/codes instead of UDP/TCP ports, but
+ * this CLI does not).
+ *
+ * An ACL can optionally be assigned a 'tag' - which is an identifier understood
+ * by the client. VPP does not examine it in any way.
+ *
+ * @cliexpar
+ * <b><em> set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto <TCP|UDP> sport <X-Y> dport <X-Y> [tag FOO] </b></em>
+ * @cliexend
+ ?*/
+VLIB_CLI_COMMAND (aclplugin_set_acl_command, static) = {
+ .path = "set acl-plugin acl",
+ .short_help = "set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto X sport X-Y dport X-Y [tag FOO] {use comma separated list for multiple rules}",
+ .function = acl_set_aclplugin_acl_fn,
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
+acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
+{
+ acl_main_t *am = &acl_main;
+ u32 conn_table_hash_buckets;
+ uword conn_table_hash_memory_size;
+ u32 conn_table_max_entries;
+ uword main_heap_size;
+ uword hash_heap_size;
+ u32 hash_lookup_hash_buckets;
+ uword hash_lookup_hash_memory;
+ u32 reclassify_sessions;
+ u32 use_tuple_merge;
+ u32 tuple_merge_split_threshold;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat
+ (input, "connection hash buckets %d", &conn_table_hash_buckets))
+ am->fa_conn_table_hash_num_buckets = conn_table_hash_buckets;
+ else
+ if (unformat
+ (input, "connection hash memory %U", unformat_memory_size,
+ &conn_table_hash_memory_size))
+ am->fa_conn_table_hash_memory_size = conn_table_hash_memory_size;
+ else if (unformat (input, "connection count max %d",
+ &conn_table_max_entries))
+ am->fa_conn_table_max_entries = conn_table_max_entries;
+ else
+ if (unformat
+ (input, "main heap size %U", unformat_memory_size,
+ &main_heap_size))
+ am->acl_mheap_size = main_heap_size;
+ else
+ if (unformat
+ (input, "hash lookup heap size %U", unformat_memory_size,
+ &hash_heap_size))
+ am->hash_lookup_mheap_size = hash_heap_size;
+ else if (unformat (input, "hash lookup hash buckets %d",
+ &hash_lookup_hash_buckets))
+ am->hash_lookup_hash_buckets = hash_lookup_hash_buckets;
+ else
+ if (unformat
+ (input, "hash lookup hash memory %U", unformat_memory_size,
+ &hash_lookup_hash_memory))
+ am->hash_lookup_hash_memory = hash_lookup_hash_memory;
+ else if (unformat (input, "use tuple merge %d", &use_tuple_merge))
+ am->use_tuple_merge = use_tuple_merge;
+ else
+ if (unformat
+ (input, "tuple merge split threshold %d",
+ &tuple_merge_split_threshold))
+ am->tuple_merge_split_threshold = tuple_merge_split_threshold;
+
+ else if (unformat (input, "reclassify sessions %d",
+ &reclassify_sessions))
+ am->reclassify_sessions = reclassify_sessions;
+
+ else
+ return clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, input);
+ }
+ return 0;
+}
+
+VLIB_CONFIG_FUNCTION (acl_plugin_config, "acl-plugin");
+
+/* Set up the API message handling tables */
+#include <vnet/format_fns.h>
+#include <acl/acl.api.c>