/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>	/* for ethernet_header_t */
#include <vnet/classify/vnet_classify.h>
#include <vnet/dpo/classify_dpo.h>

typedef struct {
  u32 next_index;
  u32 table_index;
  u32 entry_index;
} ip_classify_trace_t;

/* packet trace format function */
static u8 * format_ip_classify_trace (u8 * s, 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 *);
  ip_classify_trace_t * t = va_arg (*args, ip_classify_trace_t *);
  
  s = format (s, "IP_CLASSIFY: next_index %d, table %d, entry %d",
              t->next_index, t->table_index, t->entry_index);
  return s;
}

vlib_node_registration_t ip4_classify_node;
vlib_node_registration_t ip6_classify_node;

#define foreach_ip_classify_error               \
_(MISS, "Classify misses")                      \
_(HIT, "Classify hits")                         \
_(CHAIN_HIT, "Classify hits after chain walk")

typedef enum {
#define _(sym,str) IP_CLASSIFY_ERROR_##sym,
  foreach_ip_classify_error
#undef _
  IP_CLASSIFY_N_ERROR,
} ip_classify_error_t;

static char * ip_classify_error_strings[] = {
#define _(sym,string) string,
  foreach_ip_classify_error
#undef _
};

static inline uword
ip_classify_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
                    vlib_frame_t * frame, int is_ip4)
{
  u32 n_left_from, * from, * to_next;
  ip_lookup_next_t next_index;
  vnet_classify_main_t * vcm = &vnet_classify_main;
  f64 now = vlib_time_now (vm);
  u32 hits = 0;
  u32 misses = 0;
  u32 chain_hits = 0;
  u32 n_next;

  if (is_ip4) {
    n_next = IP4_LOOKUP_N_NEXT;
  } else {
    n_next = IP6_LOOKUP_N_NEXT;
  }

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;

  /* First pass: compute hashes */

  while (n_left_from > 2)
    {
      vlib_buffer_t * b0, * b1;
      u32 bi0, bi1;
      u8 * h0, * h1;
      u32 cd_index0, cd_index1;
      classify_dpo_t *cd0, * cd1;
      u32 table_index0, table_index1;
      vnet_classify_table_t * t0, * t1;

      /* prefetch next iteration */
        {
          vlib_buffer_t * p1, * p2;
          
          p1 = vlib_get_buffer (vm, from[1]);
          p2 = vlib_get_buffer (vm, from[2]);
          
          vlib_prefetch_buffer_header (p1, STORE);
          CLIB_PREFETCH (p1->data, CLIB_CACHE_LINE_BYTES, STORE);
          vlib_prefetch_buffer_header (p2, STORE);
          CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
        }
        
      bi0 = from[0];
      b0 = vlib_get_buffer (vm, bi0);
      h0 = (void *)vlib_buffer_get_current(b0) -
                ethernet_buffer_header_size(b0);

      bi1 = from[1];
      b1 = vlib_get_buffer (vm, bi1);
      h1 = (void *)vlib_buffer_get_current(b1) -
                ethernet_buffer_header_size(b1);
        
      cd_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
      cd0 = classify_dpo_get(cd_index0);
      table_index0 = cd0->cd_table_index;

      cd_index1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX];
      cd1 = classify_dpo_get(cd_index1);
      table_index1 = cd1->cd_table_index;

      t0 = pool_elt_at_index (vcm->tables, table_index0);

      t1 = pool_elt_at_index (vcm->tables, table_index1);
            
      vnet_buffer(b0)->l2_classify.hash = 
        vnet_classify_hash_packet (t0, (u8 *) h0);

      vnet_classify_prefetch_bucket (t0, vnet_buffer(b0)->l2_classify.hash);

      vnet_buffer(b1)->l2_classify.hash = 
        vnet_classify_hash_packet (t1, (u8 *) h1);

      vnet_classify_prefetch_bucket (t1, vnet_buffer(b1)->l2_classify.hash);

      vnet_buffer(b0)->l2_classify.table_index = table_index0;

      vnet_buffer(b1)->l2_classify.table_index = table_index1;

      from += 2;
      n_left_from -= 2;
    }

  while (n_left_from > 0)
    {
      vlib_buffer_t * b0;
      u32 bi0;
      u8 * h0;
      u32 cd_index0;
      classify_dpo_t *cd0;
      u32 table_index0;
      vnet_classify_table_t * t0;

      bi0 = from[0];
      b0 = vlib_get_buffer (vm, bi0);
      h0 = (void *)vlib_buffer_get_current(b0) -
                ethernet_buffer_header_size(b0);
        
      cd_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
      cd0 = classify_dpo_get(cd_index0);
      table_index0 = cd0->cd_table_index;

      t0 = pool_elt_at_index (vcm->tables, table_index0);
      vnet_buffer(b0)->l2_classify.hash = 
        vnet_classify_hash_packet (t0, (u8 *) h0);

      vnet_buffer(b0)->l2_classify.table_index = table_index0;
      vnet_classify_prefetch_bucket (t0, vnet_buffer(b0)->l2_classify.hash);

      from++;
      n_left_from--;
    }
        
  next_index = node->cached_next_index;
  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index,
			   to_next, n_left_to_next);

      /* Not enough load/store slots to dual loop... */
      while (n_left_from > 0 && n_left_to_next > 0)
	{
          u32 bi0;
	  vlib_buffer_t * b0;
          u32 next0 = IP_LOOKUP_NEXT_DROP;
          u32 table_index0;
          vnet_classify_table_t * t0;
          vnet_classify_entry_t * e0;
          u64 hash0;
          u8 * h0;

          /* Stride 3 seems to work best */
          if (PREDICT_TRUE (n_left_from > 3))
            {
              vlib_buffer_t * p1 = vlib_get_buffer(vm, from[3]);
              vnet_classify_table_t * tp1;
              u32 table_index1;
              u64 phash1;

              table_index1 = vnet_buffer(p1)->l2_classify.table_index;
              
              if (PREDICT_TRUE (table_index1 != ~0))
                {
                  tp1 = pool_elt_at_index (vcm->tables, table_index1);
                  phash1 = vnet_buffer(p1)->l2_classify.hash;
                  vnet_classify_prefetch_entry (tp1, phash1); 
                }
            }

          /* speculatively enqueue b0 to the current next frame */
	  bi0 = from[0];
	  to_next[0] = bi0;
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  b0 = vlib_get_buffer (vm, bi0);
          h0 = b0->data;
          table_index0 = vnet_buffer(b0)->l2_classify.table_index;
          e0 = 0;
          t0 = 0;
          vnet_buffer(b0)->l2_classify.opaque_index = ~0;

          if (PREDICT_TRUE(table_index0 != ~0))
            {
              hash0 = vnet_buffer(b0)->l2_classify.hash;
              t0 = pool_elt_at_index (vcm->tables, table_index0);

              e0 = vnet_classify_find_entry (t0, (u8 *) h0, hash0,
                                             now);
              if (e0)
                {
                  vnet_buffer(b0)->l2_classify.opaque_index
                    = e0->opaque_index;
                  vlib_buffer_advance (b0, e0->advance);
                  next0 = (e0->next_index < node->n_next_nodes)?
                           e0->next_index:next0;
                  hits++;
                }
              else
                {
                  while (1)
                    {
                      if (t0->next_table_index != ~0)
                        t0 = pool_elt_at_index (vcm->tables,
                                                t0->next_table_index);
                      else
                        {
                          next0 = (t0->miss_next_index < n_next) ?
                                   t0->miss_next_index : next0;
                          misses++;
                          break;
                        }

                      hash0 = vnet_classify_hash_packet (t0, (u8 *) h0);
                      e0 = vnet_classify_find_entry
                        (t0, (u8 *) h0, hash0, now);
                      if (e0)
                        {
                          vnet_buffer(b0)->l2_classify.opaque_index
                            = e0->opaque_index;
                          vlib_buffer_advance (b0, e0->advance);
                          next0 = (e0->next_index < node->n_next_nodes)?
                                   e0->next_index:next0;
                          hits++;
                          chain_hits++;
                          break;
                        }
                    }
                }
            }

          if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) 
                            && (b0->flags & VLIB_BUFFER_IS_TRACED))) 
            {
              ip_classify_trace_t *t = 
                vlib_add_trace (vm, node, b0, sizeof (*t));
              t->next_index = next0;
              t->table_index = t0 ? t0 - vcm->tables : ~0;
              t->entry_index = e0 ? e0 - t0->entries : ~0;
            }

          /* verify speculative enqueue, maybe switch current next frame */
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  vlib_node_increment_counter (vm, node->node_index, 
                               IP_CLASSIFY_ERROR_MISS, 
                               misses);
  vlib_node_increment_counter (vm, node->node_index, 
                               IP_CLASSIFY_ERROR_HIT, 
                               hits);
  vlib_node_increment_counter (vm, node->node_index, 
                               IP_CLASSIFY_ERROR_CHAIN_HIT, 
                               chain_hits);
  return frame->n_vectors;
}

static uword
ip4_classify (vlib_main_t * vm,
              vlib_node_runtime_t * node,
              vlib_frame_t * frame)
{
  return ip_classify_inline (vm, node, frame, 1 /* is_ip4 */);
}


VLIB_REGISTER_NODE (ip4_classify_node) = {
  .function = ip4_classify,
  .name = "ip4-classify",
  .vector_size = sizeof (u32),
  .sibling_of = "ip4-lookup",
  .format_trace = format_ip_classify_trace,
  .n_errors = ARRAY_LEN(ip_classify_error_strings),
  .error_strings = ip_classify_error_strings,

  .n_next_nodes = 0,
};

VLIB_NODE_FUNCTION_MULTIARCH (ip4_classify_node, ip4_classify)

static uword
ip6_classify (vlib_main_t * vm,
              vlib_node_runtime_t * node,
              vlib_frame_t * frame)
{
  return ip_classify_inline (vm, node, frame, 0 /* is_ip4 */);
}


VLIB_REGISTER_NODE (ip6_classify_node) = {
  .function = ip6_classify,
  .name = "ip6-classify",
  .vector_size = sizeof (u32),
  .sibling_of = "ip6-lookup",
  .format_trace = format_ip_classify_trace,
  .n_errors = ARRAY_LEN(ip_classify_error_strings),
  .error_strings = ip_classify_error_strings,

  .n_next_nodes = 0,
};

VLIB_NODE_FUNCTION_MULTIARCH (ip6_classify_node, ip6_classify)

static clib_error_t *
ip_classify_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (ip_classify_init);
