http_static: fix reply data leak
[vpp.git] / src / plugins / acl / dataplane_node.c
index 0bdcc85..027afc0 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <vlib/vlib.h>
 #include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
 #include <vppinfra/error.h>
 
 
@@ -45,7 +44,6 @@ typedef struct
   u8 action;
 } acl_fa_trace_t;
 
-/* *INDENT-OFF* */
 #define foreach_acl_fa_error \
 _(ACL_DROP, "ACL deny packets")  \
 _(ACL_PERMIT, "ACL permit packets")  \
@@ -64,228 +62,6 @@ typedef enum
     ACL_FA_N_ERROR,
 } acl_fa_error_t;
 
-/* *INDENT-ON* */
-
-typedef struct
-{
-  u32 next_index;
-  u32 sw_if_index;
-  u16 ethertype;
-} nonip_in_out_trace_t;
-
-/* packet trace format function */
-static u8 *
-format_nonip_in_out_trace (u8 * s, u32 is_output, va_list * args)
-{
-  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
-  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
-  nonip_in_out_trace_t *t = va_arg (*args, nonip_in_out_trace_t *);
-
-  s = format (s, "%s: sw_if_index %d next_index %x ethertype %x",
-             is_output ? "OUT-ETHER-WHITELIST" : "IN-ETHER-WHITELIST",
-             t->sw_if_index, t->next_index, t->ethertype);
-  return s;
-}
-
-static u8 *
-format_l2_nonip_in_trace (u8 * s, va_list * args)
-{
-  return format_nonip_in_out_trace (s, 0, args);
-}
-
-static u8 *
-format_l2_nonip_out_trace (u8 * s, va_list * args)
-{
-  return format_nonip_in_out_trace (s, 1, args);
-}
-
-#define foreach_nonip_in_error                    \
-_(DROP, "dropped inbound non-whitelisted non-ip packets") \
-_(PERMIT, "permitted inbound whitelisted non-ip packets") \
-
-
-#define foreach_nonip_out_error                    \
-_(DROP, "dropped outbound non-whitelisted non-ip packets") \
-_(PERMIT, "permitted outbound whitelisted non-ip packets") \
-
-
-/* *INDENT-OFF* */
-
-typedef enum
-{
-#define _(sym,str) FA_IN_NONIP_ERROR_##sym,
-  foreach_nonip_in_error
-#undef _
-    FA_IN_NONIP_N_ERROR,
-} l2_in_feat_arc_error_t;
-
-static char *fa_in_nonip_error_strings[] = {
-#define _(sym,string) string,
-  foreach_nonip_in_error
-#undef _
-};
-
-typedef enum
-{
-#define _(sym,str) FA_OUT_NONIP_ERROR_##sym,
-  foreach_nonip_out_error
-#undef _
-    FA_OUT_NONIP_N_ERROR,
-} l2_out_feat_arc_error_t;
-
-static char *fa_out_nonip_error_strings[] = {
-#define _(sym,string) string,
-  foreach_nonip_out_error
-#undef _
-};
-/* *INDENT-ON* */
-
-
-always_inline int
-is_permitted_ethertype (acl_main_t * am, int sw_if_index0, int is_output,
-                       u16 ethertype)
-{
-  u16 **v = is_output
-    ? am->output_etype_whitelist_by_sw_if_index
-    : am->input_etype_whitelist_by_sw_if_index;
-  u16 *whitelist = vec_elt (v, sw_if_index0);
-  int i;
-
-  if (vec_len (whitelist) == 0)
-    return 1;
-
-  for (i = 0; i < vec_len (whitelist); i++)
-    if (whitelist[i] == ethertype)
-      return 1;
-  return 0;
-}
-
-#define get_u16(addr) ( *((u16 *)(addr)) )
-
-always_inline uword
-nonip_in_out_node_fn (vlib_main_t * vm,
-                     vlib_node_runtime_t * node, vlib_frame_t * frame,
-                     int is_output)
-{
-  acl_main_t *am = &acl_main;
-  u32 n_left, *from;
-  u16 nexts[VLIB_FRAME_SIZE], *next;
-  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
-  vlib_node_runtime_t *error_node;
-
-  from = vlib_frame_vector_args (frame);
-  error_node = vlib_node_get_runtime (vm, node->node_index);
-  vlib_get_buffers (vm, from, bufs, frame->n_vectors);
-  /* set the initial values for the current buffer the next pointers */
-  b = bufs;
-  next = nexts;
-
-  n_left = frame->n_vectors;
-  while (n_left > 0)
-    {
-      u32 next_index = 0;
-      u32 sw_if_index0 =
-       vnet_buffer (b[0])->sw_if_index[is_output ? VLIB_TX : VLIB_RX];
-      u16 ethertype = 0;
-
-      int error0 = 0;
-
-      ethernet_header_t *h0 = vlib_buffer_get_current (b[0]);
-      u8 *l3h0 = (u8 *) h0 + vnet_buffer (b[0])->l2.l2_len;
-      ethertype = clib_net_to_host_u16 (get_u16 (l3h0 - 2));
-
-      if (is_permitted_ethertype (am, sw_if_index0, is_output, ethertype))
-       vnet_feature_next (&next_index, b[0]);
-
-      next[0] = next_index;
-
-      if (0 == next[0])
-       b[0]->error = error_node->errors[error0];
-
-      if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
-                        && (b[0]->flags & VLIB_BUFFER_IS_TRACED)))
-       {
-         nonip_in_out_trace_t *t =
-           vlib_add_trace (vm, node, b[0], sizeof (*t));
-         t->sw_if_index = sw_if_index0;
-         t->ethertype = ethertype;
-         t->next_index = next[0];
-       }
-      next[0] = next[0] < node->n_next_nodes ? next[0] : 0;
-
-      next++;
-      b++;
-      n_left--;
-    }
-  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
-
-  return frame->n_vectors;
-}
-
-VLIB_NODE_FN (acl_in_nonip_node) (vlib_main_t * vm,
-                                 vlib_node_runtime_t * node,
-                                 vlib_frame_t * frame)
-{
-  return nonip_in_out_node_fn (vm, node, frame, 0);
-}
-
-VLIB_NODE_FN (acl_out_nonip_node) (vlib_main_t * vm,
-                                  vlib_node_runtime_t * node,
-                                  vlib_frame_t * frame)
-{
-  return nonip_in_out_node_fn (vm, node, frame, 1);
-}
-
-
-/* *INDENT-OFF* */
-
-VLIB_REGISTER_NODE (acl_in_nonip_node) =
-{
-  .name = "acl-plugin-in-nonip-l2",
-  .vector_size = sizeof (u32),
-  .format_trace = format_l2_nonip_in_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN (fa_in_nonip_error_strings),
-  .error_strings = fa_in_nonip_error_strings,
-  .n_next_nodes = ACL_FA_N_NEXT,
-  .next_nodes =
-  {
-    [ACL_FA_ERROR_DROP] = "error-drop",
-  }
-};
-
-VNET_FEATURE_INIT (acl_in_l2_nonip_fa_feature, static) =
-{
-  .arc_name = "l2-input-nonip",
-  .node_name = "acl-plugin-in-nonip-l2",
-  .runs_before = VNET_FEATURES ("l2-input-feat-arc-end"),
-};
-
-VLIB_REGISTER_NODE (acl_out_nonip_node) =
-{
-  .name = "acl-plugin-out-nonip-l2",
-  .vector_size = sizeof (u32),
-  .format_trace = format_l2_nonip_out_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  .n_errors = ARRAY_LEN (fa_out_nonip_error_strings),
-  .error_strings = fa_out_nonip_error_strings,
-  .n_next_nodes = ACL_FA_N_NEXT,
-  .next_nodes =
-  {
-    [ACL_FA_ERROR_DROP] = "error-drop",
-  }
-};
-
-VNET_FEATURE_INIT (acl_out_l2_nonip_fa_feature, static) =
-{
-  .arc_name = "l2-output-nonip",
-  .node_name = "acl-plugin-out-nonip-l2",
-  .runs_before = VNET_FEATURES ("l2-output-feat-arc-end"),
-};
-
-/* *INDENT-ON* */
-
-
 
 always_inline u16
 get_current_policy_epoch (acl_main_t * am, int is_input, u32 sw_if_index0)
@@ -398,7 +174,7 @@ prefetch_session_entry (acl_main_t * am, fa_full_session_id_t f_sess_id)
 {
   fa_session_t *sess = get_session_ptr_no_check (am, f_sess_id.thread_index,
                                                 f_sess_id.session_index);
-  CLIB_PREFETCH (sess, 2 * CLIB_CACHE_LINE_BYTES, STORE);
+  CLIB_PREFETCH (sess, sizeof (*sess), STORE);
 }
 
 always_inline u8
@@ -499,7 +275,7 @@ acl_fa_node_common_prepare_fn (vlib_main_t * vm,
        for (ii = ACL_PLUGIN_PREFETCH_GAP * vec_sz;
             ii < (ACL_PLUGIN_PREFETCH_GAP + 1) * vec_sz; ii++)
          {
-           CLIB_PREFETCH (b[ii], CLIB_CACHE_LINE_BYTES, LOAD);
+           clib_prefetch_load (b[ii]);
            CLIB_PREFETCH (b[ii]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
          }
       }
@@ -548,7 +324,7 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
                      int with_stateful_datapath, int node_trace_on,
                      int reclassify_sessions)
 {
-  u32 n_left, *from;
+  u32 n_left;
   u32 pkts_exist_session = 0;
   u32 pkts_new_session = 0;
   u32 pkts_acl_permit = 0;
@@ -565,8 +341,12 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
   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];
@@ -636,7 +416,7 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
                    {
                      trace_bitmap |= 0x80000000;
                    }
-                 ASSERT (f_sess_id.thread_index < vec_len (vlib_mains));
+                 ASSERT (f_sess_id.thread_index < vlib_get_n_threads ());
                  b[0]->error = no_error_existing_session;
                  acl_check_needed = 0;
                  pkts_exist_session += 1;
@@ -690,13 +470,34 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
                  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)
@@ -752,11 +553,10 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
            }
 
          {
-           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))
@@ -776,7 +576,15 @@ acl_fa_inner_node_fn (vlib_main_t * vm,
        }
     }
 
-  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);
@@ -834,13 +642,19 @@ acl_fa_node_fn (vlib_main_t * vm,
 {
   /* select the reclassify/no-reclassify version of the datapath */
   acl_main_t *am = &acl_main;
+  acl_fa_per_worker_data_t *pw = &am->per_worker_data[vm->thread_index];
+  uword rv;
 
   if (am->fa_sessions_hash_is_initialized)
-    return acl_fa_outer_node_fn (vm, node, frame, is_ip6, is_input,
-                                is_l2_path, 1);
+    rv = acl_fa_outer_node_fn (vm, node, frame, is_ip6, is_input,
+                              is_l2_path, 1);
   else
-    return acl_fa_outer_node_fn (vm, node, frame, is_ip6, is_input,
-                                is_l2_path, 0);
+    rv = acl_fa_outer_node_fn (vm, node, frame, is_ip6, is_input,
+                              is_l2_path, 0);
+
+  vlib_buffer_enqueue_to_next (vm, node, vlib_frame_vector_args (frame),
+                              pw->nexts, frame->n_vectors);
+  return rv;
 }
 
 
@@ -912,7 +726,6 @@ format_acl_plugin_trace (u8 * s, va_list * args)
   return s;
 }
 
-/* *INDENT-OFF* */
 
 static char *acl_fa_error_strings[] = {
 #define _(sym,string) string,
@@ -1129,11 +942,10 @@ VLIB_REGISTER_NODE (acl_out_fa_ip6_node) =
   }
 };
 
-VNET_FEATURE_INIT (acl_out_ip6_fa_feature, static) =
-{
+VNET_FEATURE_INIT (acl_out_ip6_fa_feature, static) = {
   .arc_name = "ip6-output",
   .node_name = "acl-plugin-out-ip6-fa",
-  .runs_before = VNET_FEATURES ("interface-output"),
+  .runs_before = VNET_FEATURES ("ip6-dvr-reinject", "interface-output"),
 };
 
 VLIB_REGISTER_NODE (acl_out_fa_ip4_node) =
@@ -1152,14 +964,12 @@ VLIB_REGISTER_NODE (acl_out_fa_ip4_node) =
   }
 };
 
-VNET_FEATURE_INIT (acl_out_ip4_fa_feature, static) =
-{
+VNET_FEATURE_INIT (acl_out_ip4_fa_feature, static) = {
   .arc_name = "ip4-output",
   .node_name = "acl-plugin-out-ip4-fa",
-  .runs_before = VNET_FEATURES ("interface-output"),
+  .runs_before = VNET_FEATURES ("ip4-dvr-reinject", "interface-output"),
 };
 
-/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON