/*
 * 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.
 */
#ifndef __included_vnet_classify_h__
#define __included_vnet_classify_h__

#include <stdarg.h>

#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ethernet/packet.h>
#include <vnet/ip/ip_packet.h>
#include <vnet/ip/ip4_packet.h>
#include <vnet/ip/ip6_packet.h>
#include <vlib/cli.h>
#include <vnet/l2/l2_input.h>
#include <vnet/l2/feat_bitmap.h>
#include <vnet/api_errno.h>     /* for API error numbers */

#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vppinfra/cache.h>
#include <vppinfra/xxhash.h>

extern vlib_node_registration_t ip4_classify_node;
extern vlib_node_registration_t ip6_classify_node;

#define CLASSIFY_TRACE 0

#if !defined( __aarch64__) && !defined(__arm__)
#define CLASSIFY_USE_SSE //Allow usage of SSE operations
#endif

#define U32X4_ALIGNED(p) PREDICT_TRUE((((intptr_t)p) & 0xf) == 0)

/*
 * Classify table option to process packets
 *  CLASSIFY_FLAG_USE_CURR_DATA:
 *   - classify packets starting from VPP node’s current data pointer
 */
#define CLASSIFY_FLAG_USE_CURR_DATA              1

/*
 * Classify session action
 *  CLASSIFY_ACTION_SET_IP4_FIB_INDEX:
 *   - Classified IP packets will be looked up
 *     from the specified ipv4 fib table
 *  CLASSIFY_ACTION_SET_IP6_FIB_INDEX:
 *   - Classified IP packets will be looked up
 *     from the specified ipv6 fib table
 */
typedef enum vnet_classify_action_t_
{
  CLASSIFY_ACTION_SET_IP4_FIB_INDEX = 1,
  CLASSIFY_ACTION_SET_IP6_FIB_INDEX = 2,
} __attribute__ ((packed)) vnet_classify_action_t;

struct _vnet_classify_main;
typedef struct _vnet_classify_main vnet_classify_main_t;

#define foreach_size_in_u32x4                   \
_(1)                                            \
_(2)                                            \
_(3)                                            \
_(4)                                            \
_(5)

typedef CLIB_PACKED(struct _vnet_classify_entry {
  /* Graph node next index */
  u32 next_index;

  /* put into vnet_buffer(b)->l2_classfy.opaque_index */
  union {
    struct {
      u32 opaque_index;
      /* advance on hit, note it's a signed quantity... */
      i32 advance;
    };
    u64 opaque_count;
  };

  /* Really only need 1 bit */
  u8 flags;
#define VNET_CLASSIFY_ENTRY_FREE	(1<<0)

  vnet_classify_action_t action;
  u16 metadata;

  /* Hit counter, last heard time */
  union {
    u64 hits;
    struct _vnet_classify_entry * next_free;
  };
    
  f64 last_heard;

  /* Must be aligned to a 16-octet boundary */
  u32x4 key[0];
}) vnet_classify_entry_t;

static inline int vnet_classify_entry_is_free (vnet_classify_entry_t * e)
{
  return e->flags & VNET_CLASSIFY_ENTRY_FREE;
}

static inline int vnet_classify_entry_is_busy (vnet_classify_entry_t * e)
{
  return ((e->flags & VNET_CLASSIFY_ENTRY_FREE) == 0);
}

/* Need these to con the vector allocator */
#define _(size)                                 \
typedef CLIB_PACKED(struct {                    \
  u32 pad0[4];                                  \
  u64 pad1[2];                                  \
  u32x4 key[size];                              \
}) vnet_classify_entry_##size##_t;
foreach_size_in_u32x4;
#undef _

typedef struct {
  union {
    struct {
      u32 offset;
      u8 linear_search;
      u8 pad[2];
      u8 log2_pages;
    };
    u64 as_u64;
  };
} vnet_classify_bucket_t;

typedef struct {
  /* Mask to apply after skipping N vectors */
  u32x4 *mask;
  /* Buckets and entries */
  vnet_classify_bucket_t * buckets;
  vnet_classify_entry_t * entries;
  
  /* Config parameters */
  u32 match_n_vectors;
  u32 skip_n_vectors;
  u32 nbuckets;
  u32 log2_nbuckets;
  u32 linear_buckets;
  int entries_per_page;
  u32 active_elements;
  u32 current_data_flag;
  int current_data_offset;
  u32 data_offset;
  /* Index of next table to try */
  u32 next_table_index;
  
  /* Miss next index, return if next_table_index = 0 */
  u32 miss_next_index;
  
  /* Per-bucket working copies, one per thread */
  vnet_classify_entry_t ** working_copies;
  int *working_copy_lengths;
  vnet_classify_bucket_t saved_bucket;
  
  /* Free entry freelists */
  vnet_classify_entry_t **freelists;

  u8 * name;
  
  /* Private allocation arena, protected by the writer lock */
  void * mheap;
  
  /* Writer (only) lock for this table */
  volatile u32 * writer_lock;
  
} vnet_classify_table_t;

struct _vnet_classify_main {
  /* Table pool */
  vnet_classify_table_t * tables;
  
  /* Registered next-index, opaque unformat fcns */
  unformat_function_t ** unformat_l2_next_index_fns;
  unformat_function_t ** unformat_ip_next_index_fns;
  unformat_function_t ** unformat_acl_next_index_fns;
  unformat_function_t ** unformat_policer_next_index_fns;
  unformat_function_t ** unformat_opaque_index_fns;

  /* convenience variables */
  vlib_main_t * vlib_main;
  vnet_main_t * vnet_main;
};

extern vnet_classify_main_t vnet_classify_main;

u8 * format_classify_table (u8 * s, va_list * args);

u64 vnet_classify_hash_packet (vnet_classify_table_t * t, u8 * h);

static inline u64 
vnet_classify_hash_packet_inline (vnet_classify_table_t * t, 
                                  u8 * h)
{
  u32x4 *mask;

  union {
    u32x4 as_u32x4;
    u64 as_u64[2];
  } xor_sum __attribute__((aligned(sizeof(u32x4))));

  ASSERT(t);
  mask = t->mask;
#ifdef CLASSIFY_USE_SSE
  if (U32X4_ALIGNED(h)) {  //SSE can't handle unaligned data
    u32x4 *data = (u32x4 *)h;
    xor_sum.as_u32x4  = data[0 + t->skip_n_vectors] & mask[0];
    switch (t->match_n_vectors)
    {
      case 5:
        xor_sum.as_u32x4 ^= data[4 + t->skip_n_vectors] & mask[4];
        /* FALLTHROUGH */
      case 4:
        xor_sum.as_u32x4 ^= data[3 + t->skip_n_vectors] & mask[3];
        /* FALLTHROUGH */
      case 3:
        xor_sum.as_u32x4 ^= data[2 + t->skip_n_vectors] & mask[2];
        /* FALLTHROUGH */
      case 2:
        xor_sum.as_u32x4 ^= data[1 + t->skip_n_vectors] & mask[1];
        /* FALLTHROUGH */
      case 1:
        break;
      default:
        abort();
    }
  } else
#endif /* CLASSIFY_USE_SSE */
  {
    u32 skip_u64 = t->skip_n_vectors * 2;
    u64 *data64 = (u64 *)h;
    xor_sum.as_u64[0] = data64[0 + skip_u64] & ((u64 *)mask)[0];
    xor_sum.as_u64[1] = data64[1 + skip_u64] & ((u64 *)mask)[1];
    switch (t->match_n_vectors)
    {
      case 5:
        xor_sum.as_u64[0]  ^= data64[8 + skip_u64] & ((u64 *)mask)[8];
        xor_sum.as_u64[1]  ^= data64[9 + skip_u64] & ((u64 *)mask)[9];
        /* FALLTHROUGH */
      case 4:
        xor_sum.as_u64[0]  ^= data64[6 + skip_u64] & ((u64 *)mask)[6];
        xor_sum.as_u64[1]  ^= data64[7 + skip_u64] & ((u64 *)mask)[7];
        /* FALLTHROUGH */
      case 3:
        xor_sum.as_u64[0]  ^= data64[4 + skip_u64] & ((u64 *)mask)[4];
        xor_sum.as_u64[1]  ^= data64[5 + skip_u64] & ((u64 *)mask)[5];
        /* FALLTHROUGH */
      case 2:
        xor_sum.as_u64[0]  ^= data64[2 + skip_u64] & ((u64 *)mask)[2];
        xor_sum.as_u64[1]  ^= data64[3 + skip_u64] & ((u64 *)mask)[3];
        /* FALLTHROUGH */
      case 1:
        break;

      default:
        abort();
    }
  }
  
  return clib_xxhash (xor_sum.as_u64[0] ^ xor_sum.as_u64[1]);
}

static inline void 
vnet_classify_prefetch_bucket (vnet_classify_table_t * t, u64 hash)
{
  u32 bucket_index;
  
  ASSERT (is_pow2(t->nbuckets));
  
  bucket_index = hash & (t->nbuckets - 1);
  
  CLIB_PREFETCH(&t->buckets[bucket_index], CLIB_CACHE_LINE_BYTES, LOAD);
}

static inline vnet_classify_entry_t * 
vnet_classify_get_entry (vnet_classify_table_t * t, uword offset)
{
  u8 * hp = t->mheap;
  u8 * vp = hp + offset;
  
  return (void *) vp;
}

static inline uword vnet_classify_get_offset (vnet_classify_table_t * t, 
                                              vnet_classify_entry_t * v)
{
  u8 * hp, * vp;

  hp = (u8 *) t->mheap;
  vp = (u8 *) v;

  ASSERT((vp - hp) < 0x100000000ULL);
  return vp - hp;
}

static inline vnet_classify_entry_t *
vnet_classify_entry_at_index (vnet_classify_table_t * t, 
                              vnet_classify_entry_t * e,
                              u32 index)
{
  u8 * eu8;

  eu8 = (u8 *)e;

  eu8 += index * (sizeof (vnet_classify_entry_t) +
                  (t->match_n_vectors * sizeof (u32x4)));

  return (vnet_classify_entry_t *) eu8;
}

static inline void
vnet_classify_prefetch_entry (vnet_classify_table_t * t, 
                              u64 hash)
{
  u32 bucket_index;
  u32 value_index;
  vnet_classify_bucket_t * b;
  vnet_classify_entry_t * e;

  bucket_index = hash & (t->nbuckets - 1);

  b = &t->buckets[bucket_index];
  
  if (b->offset == 0)
    return;

  hash >>= t->log2_nbuckets;

  e = vnet_classify_get_entry (t, b->offset);
  value_index = hash & ((1<<b->log2_pages)-1);

  e = vnet_classify_entry_at_index (t, e, value_index);

  CLIB_PREFETCH(e, CLIB_CACHE_LINE_BYTES, LOAD);
}

vnet_classify_entry_t *
vnet_classify_find_entry (vnet_classify_table_t * t,
                          u8 * h, u64 hash, f64 now);

static inline vnet_classify_entry_t *
vnet_classify_find_entry_inline (vnet_classify_table_t * t,
                                 u8 * h, u64 hash, f64 now)
{
  vnet_classify_entry_t * v;
  u32x4 *mask, *key;
  union {
    u32x4 as_u32x4;
    u64 as_u64[2];
  } result __attribute__((aligned(sizeof(u32x4))));
  vnet_classify_bucket_t * b;
  u32 value_index;
  u32 bucket_index;
  u32 limit;
  int i;

  bucket_index = hash & (t->nbuckets-1);
  b = &t->buckets[bucket_index];
  mask = t->mask;

  if (b->offset == 0)
    return 0;

  hash >>= t->log2_nbuckets;

  v = vnet_classify_get_entry (t, b->offset);
  value_index = hash & ((1<<b->log2_pages)-1);
  limit = t->entries_per_page;
  if (PREDICT_FALSE (b->linear_search))
    {
      value_index = 0;
      limit *= (1<<b->log2_pages);
    }

  v = vnet_classify_entry_at_index (t, v, value_index);

#ifdef CLASSIFY_USE_SSE
  if (U32X4_ALIGNED(h)) {
    u32x4 *data = (u32x4 *) h;
    for (i = 0; i < limit; i++) {
      key = v->key;
      result.as_u32x4 = (data[0 + t->skip_n_vectors] & mask[0]) ^ key[0];
      switch (t->match_n_vectors)
        {
        case 5:
          result.as_u32x4 |= (data[4 + t->skip_n_vectors] & mask[4]) ^ key[4];
          /* FALLTHROUGH */
        case 4:
          result.as_u32x4 |= (data[3 + t->skip_n_vectors] & mask[3]) ^ key[3];
          /* FALLTHROUGH */
        case 3:
          result.as_u32x4 |= (data[2 + t->skip_n_vectors] & mask[2]) ^ key[2];
          /* FALLTHROUGH */
        case 2:
          result.as_u32x4 |= (data[1 + t->skip_n_vectors] & mask[1]) ^ key[1];
          /* FALLTHROUGH */
        case 1:
          break;
        default:
          abort();
        }

      if (u32x4_zero_byte_mask (result.as_u32x4) == 0xffff) {
        if (PREDICT_TRUE(now)) {
          v->hits++;
          v->last_heard = now;
        }
        return (v);
      }
      v = vnet_classify_entry_at_index (t, v, 1);
    }
  } else
#endif /* CLASSIFY_USE_SSE */
    {
      u32 skip_u64 = t->skip_n_vectors * 2;
      u64 *data64 = (u64 *)h;
      for (i = 0; i < limit; i++) {
        key = v->key;

        result.as_u64[0] = (data64[0 + skip_u64] & ((u64 *)mask)[0]) ^ ((u64 *)key)[0];
        result.as_u64[1] = (data64[1 + skip_u64] & ((u64 *)mask)[1]) ^ ((u64 *)key)[1];
        switch (t->match_n_vectors)
          {
          case 5:
            result.as_u64[0] |= (data64[8 + skip_u64] & ((u64 *)mask)[8]) ^ ((u64 *)key)[8];
            result.as_u64[1] |= (data64[9 + skip_u64] & ((u64 *)mask)[9]) ^ ((u64 *)key)[9];
            /* FALLTHROUGH */
          case 4:
            result.as_u64[0] |= (data64[6 + skip_u64] & ((u64 *)mask)[6]) ^ ((u64 *)key)[6];
            result.as_u64[1] |= (data64[7 + skip_u64] & ((u64 *)mask)[7]) ^ ((u64 *)key)[7];
            /* FALLTHROUGH */
          case 3:
            result.as_u64[0] |= (data64[4 + skip_u64] & ((u64 *)mask)[4]) ^ ((u64 *)key)[4];
            result.as_u64[1] |= (data64[5 + skip_u64] & ((u64 *)mask)[5]) ^ ((u64 *)key)[5];
            /* FALLTHROUGH */
          case 2:
            result.as_u64[0] |= (data64[2 + skip_u64] & ((u64 *)mask)[2]) ^ ((u64 *)key)[2];
            result.as_u64[1] |= (data64[3 + skip_u64] & ((u64 *)mask)[3]) ^ ((u64 *)key)[3];
            /* FALLTHROUGH */
          case 1:
            break;
          default:
            abort();
          }

        if (result.as_u64[0] == 0 && result.as_u64[1] == 0) {
          if (PREDICT_TRUE(now)) {
            v->hits++;
            v->last_heard = now;
          }
          return (v);
        }

        v = vnet_classify_entry_at_index (t, v, 1);
      }
    }
  return 0;
}

vnet_classify_table_t * 
vnet_classify_new_table (vnet_classify_main_t *cm,
                         u8 * mask, u32 nbuckets, u32 memory_size,
                         u32 skip_n_vectors,
                         u32 match_n_vectors);

int vnet_classify_add_del_session (vnet_classify_main_t * cm, 
                                   u32 table_index, 
                                   u8 * match, 
                                   u32 hit_next_index,
                                   u32 opaque_index, 
                                   i32 advance,
                                   u8 action,
                                   u32 metadata,
                                   int is_add);

int vnet_classify_add_del_table (vnet_classify_main_t * cm,
                                 u8 * mask, 
                                 u32 nbuckets,
                                 u32 memory_size,
                                 u32 skip,
                                 u32 match,
                                 u32 next_table_index,
                                 u32 miss_next_index,
                                 u32 * table_index,
                                 u8 current_data_flag,
                                 i16 current_data_offset,
                                 int is_add,
				 int del_chain);

unformat_function_t unformat_ip4_mask;
unformat_function_t unformat_ip6_mask;
unformat_function_t unformat_l3_mask;
unformat_function_t unformat_l2_mask;
unformat_function_t unformat_classify_mask;
unformat_function_t unformat_l2_next_index;
unformat_function_t unformat_ip_next_index;
unformat_function_t unformat_ip4_match;
unformat_function_t unformat_ip6_match;
unformat_function_t unformat_l3_match;
unformat_function_t unformat_l4_match;
unformat_function_t unformat_vlan_tag;
unformat_function_t unformat_l2_match;
unformat_function_t unformat_classify_match;

void vnet_classify_register_unformat_ip_next_index_fn 
(unformat_function_t * fn);

void vnet_classify_register_unformat_l2_next_index_fn 
(unformat_function_t * fn);

void vnet_classify_register_unformat_acl_next_index_fn 
(unformat_function_t * fn);

void  vnet_classify_register_unformat_policer_next_index_fn
(unformat_function_t * fn);

void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn);

#endif /* __included_vnet_classify_h__ */
