#define ACL_PLUGIN_VECTOR_SIZE 4
#define ACL_PLUGIN_PREFETCH_GAP 3
-always_inline uword
-acl_fa_inner_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame,
- int is_ip6, int is_input, int is_l2_path,
- int with_stateful_datapath, int node_trace_on,
- int reclassify_sessions)
+always_inline void
+acl_fa_node_common_prepare_fn (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame, int is_ip6, int is_input,
+ int is_l2_path, int with_stateful_datapath)
+ /* , int node_trace_on,
+ int reclassify_sessions) */
{
u32 n_left, *from;
- u32 pkts_exist_session = 0;
- u32 pkts_new_session = 0;
- u32 pkts_acl_permit = 0;
- u32 trace_bitmap = 0;
acl_main_t *am = &acl_main;
- vlib_node_runtime_t *error_node;
- vlib_error_t no_error_existing_session;
- u64 now = clib_cpu_time_now ();
uword thread_index = os_get_thread_index ();
acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
- u16 *next;
vlib_buffer_t **b;
u32 *sw_if_index;
fa_5tuple_t *fa_5tuple;
from = vlib_frame_vector_args (frame);
- error_node = vlib_node_get_runtime (vm, node->node_index);
- no_error_existing_session =
- error_node->errors[ACL_FA_ERROR_ACL_EXIST_SESSION];
-
vlib_get_buffers (vm, from, pw->bufs, frame->n_vectors);
/* set the initial values for the current buffer the next pointers */
b = pw->bufs;
- next = pw->nexts;
sw_if_index = pw->sw_if_indices;
fa_5tuple = pw->fa_5tuples;
hash = pw->hashes;
sw_if_index += vec_sz;
hash += vec_sz;
}
+}
+
+
+always_inline uword
+acl_fa_inner_node_fn (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame,
+ int is_ip6, int is_input, int is_l2_path,
+ int with_stateful_datapath, int node_trace_on,
+ int reclassify_sessions)
+{
+ u32 n_left, *from;
+ u32 pkts_exist_session = 0;
+ u32 pkts_new_session = 0;
+ u32 pkts_acl_permit = 0;
+ u32 trace_bitmap = 0;
+ acl_main_t *am = &acl_main;
+ vlib_node_runtime_t *error_node;
+ vlib_error_t no_error_existing_session;
+ u64 now = clib_cpu_time_now ();
+ uword thread_index = os_get_thread_index ();
+ acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
+
+ u16 *next;
+ vlib_buffer_t **b;
+ u32 *sw_if_index;
+ fa_5tuple_t *fa_5tuple;
+ u64 *hash;
+ /* for the delayed counters */
+ u32 saved_matched_acl_index = 0;
+ u32 saved_matched_ace_index = 0;
+ u32 saved_packet_count = 0;
+ u32 saved_byte_count = 0;
+
+ from = vlib_frame_vector_args (frame);
+ error_node = vlib_node_get_runtime (vm, node->node_index);
+ no_error_existing_session =
+ error_node->errors[ACL_FA_ERROR_ACL_EXIST_SESSION];
b = pw->bufs;
next = pw->nexts;
am->output_lc_index_by_sw_if_index[sw_if_index[0]];
action = 0; /* deny by default */
- acl_plugin_match_5tuple_inline (am, lc_index0,
- (fa_5tuple_opaque_t *) &
- fa_5tuple[0], is_ip6, &action,
- &match_acl_pos,
- &match_acl_in_index,
- &match_rule_index,
- &trace_bitmap);
+ int is_match = acl_plugin_match_5tuple_inline (am, lc_index0,
+ (fa_5tuple_opaque_t *) & fa_5tuple[0], is_ip6,
+ &action,
+ &match_acl_pos,
+ &match_acl_in_index,
+ &match_rule_index,
+ &trace_bitmap);
+ if (PREDICT_FALSE
+ (is_match && am->interface_acl_counters_enabled))
+ {
+ u32 buf_len = vlib_buffer_length_in_chain (vm, b[0]);
+ vlib_increment_combined_counter (am->combined_acl_counters +
+ saved_matched_acl_index,
+ thread_index,
+ saved_matched_ace_index,
+ saved_packet_count,
+ saved_byte_count);
+ saved_matched_acl_index = match_acl_in_index;
+ saved_matched_ace_index = match_rule_index;
+ saved_packet_count = 1;
+ saved_byte_count = buf_len;
+ /* prefetch the counter that we are going to increment */
+ vlib_prefetch_combined_counter (am->combined_acl_counters +
+ saved_matched_acl_index,
+ thread_index,
+ saved_matched_ace_index);
+ }
+
b[0]->error = error_node->errors[action];
if (1 == action)
}
{
- u32 next0;
/* speculatively get the next0 */
- vnet_feature_next (&next0, b[0]);
+ vnet_feature_next_u16 (&next[0], b[0]);
/* if the action is not deny - then use that next */
- next[0] = action ? next0 : 0;
+ next[0] = action ? next[0] : 0;
}
if (node_trace_on) // PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
vlib_buffer_enqueue_to_next (vm, node, from, pw->nexts, frame->n_vectors);
+ /*
+ * if we were had an acl match then we have a counter to increment.
+ * else it is all zeroes, so this will be harmless.
+ */
+ vlib_increment_combined_counter (am->combined_acl_counters +
+ saved_matched_acl_index,
+ thread_index,
+ saved_matched_ace_index,
+ saved_packet_count, saved_byte_count);
+
vlib_node_increment_counter (vm, node->node_index,
ACL_FA_ERROR_ACL_CHECK, frame->n_vectors);
vlib_node_increment_counter (vm, node->node_index,
acl_fa_outer_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * frame,
int is_ip6, int is_input, int is_l2_path,
- int do_reclassify)
+ int do_stateful_datapath)
{
acl_main_t *am = &acl_main;
- if (am->fa_sessions_hash_is_initialized)
+ acl_fa_node_common_prepare_fn (vm, node, frame, is_ip6, is_input,
+ is_l2_path, do_stateful_datapath);
+
+ if (am->reclassify_sessions)
{
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
return acl_fa_inner_node_fn (vm, node, frame, is_ip6, is_input,
- is_l2_path, 1 /* stateful */ ,
+ is_l2_path, do_stateful_datapath,
1 /* trace */ ,
- do_reclassify);
+ 1 /* reclassify */ );
else
return acl_fa_inner_node_fn (vm, node, frame, is_ip6, is_input,
- is_l2_path, 1 /* stateful */ , 0,
- do_reclassify);
+ is_l2_path, do_stateful_datapath, 0,
+ 1 /* reclassify */ );
}
else
{
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
return acl_fa_inner_node_fn (vm, node, frame, is_ip6, is_input,
- is_l2_path, 0 /* no state */ ,
+ is_l2_path, do_stateful_datapath,
1 /* trace */ ,
- do_reclassify);
+ 0);
else
return acl_fa_inner_node_fn (vm, node, frame, is_ip6, is_input,
- is_l2_path, 0 /* no state */ , 0,
- do_reclassify);
+ is_l2_path, do_stateful_datapath, 0, 0);
}
}
/* select the reclassify/no-reclassify version of the datapath */
acl_main_t *am = &acl_main;
- if (am->reclassify_sessions)
+ if (am->fa_sessions_hash_is_initialized)
return acl_fa_outer_node_fn (vm, node, frame, is_ip6, is_input,
is_l2_path, 1);
else
is_l2_path, 0);
}
-VLIB_NODE_FN (acl_in_l2_ip6_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 1, 1, 1);
-}
-
-VLIB_NODE_FN (acl_in_l2_ip4_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 0, 1, 1);
-}
-
-VLIB_NODE_FN (acl_out_l2_ip6_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 1, 0, 1);
-}
-
-VLIB_NODE_FN (acl_out_l2_ip4_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 0, 0, 1);
-}
-
-/**** L3 processing path nodes ****/
-
-VLIB_NODE_FN (acl_in_fa_ip6_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 1, 1, 0);
-}
-
-VLIB_NODE_FN (acl_in_fa_ip4_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 0, 1, 0);
-}
-
-VLIB_NODE_FN (acl_out_fa_ip6_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 1, 0, 0);
-}
-
-VLIB_NODE_FN (acl_out_fa_ip4_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return acl_fa_node_fn (vm, node, frame, 0, 0, 0);
-}
static u8 *
format_fa_5tuple (u8 * s, va_list * args)
#undef _
};
+VLIB_NODE_FN (acl_in_l2_ip6_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 1, 1, 1);
+}
+
+VLIB_NODE_FN (acl_in_l2_ip4_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 0, 1, 1);
+}
+
+VLIB_NODE_FN (acl_out_l2_ip6_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 1, 0, 1);
+}
+
+VLIB_NODE_FN (acl_out_l2_ip4_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 0, 0, 1);
+}
+
+/**** L3 processing path nodes ****/
+
+VLIB_NODE_FN (acl_in_fa_ip6_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 1, 1, 0);
+}
+
+VLIB_NODE_FN (acl_in_fa_ip4_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 0, 1, 0);
+}
+
+VLIB_NODE_FN (acl_out_fa_ip6_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 1, 0, 0);
+}
+
+VLIB_NODE_FN (acl_out_fa_ip4_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return acl_fa_node_fn (vm, node, frame, 0, 0, 0);
+}
+
VLIB_REGISTER_NODE (acl_in_l2_ip6_node) =
{
.name = "acl-plugin-in-ip6-l2",