/*
 * Copyright (c) 2017-2019 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/session/session_table.h>
#include <vnet/session/session.h>

/**
 * Pool of session tables
 */
static session_table_t *lookup_tables;

session_table_t *
_get_session_tables (void)
{
  return lookup_tables;
}

session_table_t *
session_table_alloc (void)
{
  session_table_t *slt;
  pool_get_aligned (lookup_tables, slt, CLIB_CACHE_LINE_BYTES);
  clib_memset (slt, 0, sizeof (*slt));
  return slt;
}

u32
session_table_index (session_table_t * slt)
{
  return (slt - lookup_tables);
}

session_table_t *
session_table_get (u32 table_index)
{
  if (pool_is_free_index (lookup_tables, table_index))
    return 0;
  return pool_elt_at_index (lookup_tables, table_index);
}

#define foreach_hash_table_parameter            \
  _(v4,session,buckets,20000)                   \
  _(v4,session,memory,(64<<20))                 \
  _(v6,session,buckets,20000)                   \
  _(v6,session,memory,(64<<20))                 \
  _(v4,halfopen,buckets,20000)                  \
  _(v4,halfopen,memory,(64<<20))                \
  _(v6,halfopen,buckets,20000)                  \
  _(v6,halfopen,memory,(64<<20))

/**
 * Initialize session table hash tables
 *
 * If vpp configured with set of table parameters it uses them,
 * otherwise it uses defaults above.
 */
void
session_table_init (session_table_t * slt, u8 fib_proto)
{
  u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
  int i;

#define _(af,table,parm,value) 						\
  u32 configured_##af##_##table##_table_##parm = value;
  foreach_hash_table_parameter;
#undef _

#define _(af,table,parm,value)                                          \
  if (session_manager_main.configured_##af##_##table##_table_##parm)    \
    configured_##af##_##table##_table_##parm =                          \
      session_manager_main.configured_##af##_##table##_table_##parm;
  foreach_hash_table_parameter;
#undef _

  if (fib_proto == FIB_PROTOCOL_IP4 || all)
    {
      clib_bihash_init_16_8 (&slt->v4_session_hash, "v4 session table",
			     configured_v4_session_table_buckets,
			     configured_v4_session_table_memory);
      clib_bihash_init_16_8 (&slt->v4_half_open_hash, "v4 half-open table",
			     configured_v4_halfopen_table_buckets,
			     configured_v4_halfopen_table_memory);
    }
  if (fib_proto == FIB_PROTOCOL_IP6 || all)
    {
      clib_bihash_init_48_8 (&slt->v6_session_hash, "v6 session table",
			     configured_v6_session_table_buckets,
			     configured_v6_session_table_memory);
      clib_bihash_init_48_8 (&slt->v6_half_open_hash, "v6 half-open table",
			     configured_v6_halfopen_table_buckets,
			     configured_v6_halfopen_table_memory);
    }

  for (i = 0; i < TRANSPORT_N_PROTO; i++)
    session_rules_table_init (&slt->session_rules[i]);
}

typedef struct _ip4_session_table_walk_ctx_t
{
  ip4_session_table_walk_fn_t fn;
  void *ctx;
} ip4_session_table_walk_ctx_t;

void
ip4_session_table_walk_cb (clib_bihash_kv_16_8_t * kvp, void *arg)
{
  ip4_session_table_walk_ctx_t *ctx = arg;
  ctx->fn (kvp, ctx->ctx);
}

void
ip4_session_table_walk (clib_bihash_16_8_t * hash,
			ip4_session_table_walk_fn_t fn, void *arg)
{
  ip4_session_table_walk_ctx_t ctx = {
    .fn = fn,
    .ctx = arg,
  };
  clib_bihash_foreach_key_value_pair_16_8 (hash, ip4_session_table_walk_cb,
					   &ctx);
}

/* *INDENT-ON* */
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
