/*
 * map.c : MAP support
 *
 * 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/fib/fib_table.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/adj/adj.h>
#include <vnet/map/map_dpo.h>

#include "map.h"

#ifdef __SSE4_2__
static inline u32
crc_u32 (u32 data, u32 value)
{
  __asm__ volatile ("crc32l %[data], %[value];":[value] "+r" (value):[data]
		    "rm" (data));
  return value;
}
#else
#include <vppinfra/xxhash.h>

static inline u32
crc_u32 (u32 data, u32 value)
{
  u64 tmp = ((u64) data << 32) | (u64) value;
  return (u32) clib_xxhash (tmp);
}
#endif


/*
 * This code supports the following MAP modes:
 *
 * Algorithmic Shared IPv4 address (ea_bits_len > 0):
 *   ea_bits_len + ip4_prefix > 32
 *   psid_length > 0, ip6_prefix < 64, ip4_prefix <= 32
 * Algorithmic Full IPv4 address (ea_bits_len > 0):
 *   ea_bits_len + ip4_prefix = 32
 *   psid_length = 0, ip6_prefix < 64, ip4_prefix <= 32
 * Algorithmic IPv4 prefix (ea_bits_len > 0):
 *   ea_bits_len + ip4_prefix < 32
 *   psid_length = 0, ip6_prefix < 64, ip4_prefix <= 32
 *
 * Independent Shared IPv4 address (ea_bits_len = 0):
 *   ip4_prefix = 32
 *   psid_length > 0
 *   Rule IPv6 address = 128, Rule PSID Set
 * Independent Full IPv4 address (ea_bits_len = 0):
 *   ip4_prefix = 32
 *   psid_length = 0, ip6_prefix = 128
 * Independent IPv4 prefix (ea_bits_len = 0):
 *   ip4_prefix < 32
 *   psid_length = 0, ip6_prefix = 128
 *
 */

/*
 * This code supports MAP-T:
 *
 * With DMR prefix length equal to 96.
 *
 */


i32
ip4_get_port (ip4_header_t * ip, map_dir_e dir, u16 buffer_len)
{
  //TODO: use buffer length
  if (ip->ip_version_and_header_length != 0x45 ||
      ip4_get_fragment_offset (ip))
    return -1;

  if (PREDICT_TRUE ((ip->protocol == IP_PROTOCOL_TCP) ||
		    (ip->protocol == IP_PROTOCOL_UDP)))
    {
      udp_header_t *udp = (void *) (ip + 1);
      return (dir == MAP_SENDER) ? udp->src_port : udp->dst_port;
    }
  else if (ip->protocol == IP_PROTOCOL_ICMP)
    {
      icmp46_header_t *icmp = (void *) (ip + 1);
      if (icmp->type == ICMP4_echo_request || icmp->type == ICMP4_echo_reply)
	{
	  return *((u16 *) (icmp + 1));
	}
      else if (clib_net_to_host_u16 (ip->length) >= 64)
	{
	  ip = (ip4_header_t *) (icmp + 2);
	  if (PREDICT_TRUE ((ip->protocol == IP_PROTOCOL_TCP) ||
			    (ip->protocol == IP_PROTOCOL_UDP)))
	    {
	      udp_header_t *udp = (void *) (ip + 1);
	      return (dir == MAP_SENDER) ? udp->dst_port : udp->src_port;
	    }
	  else if (ip->protocol == IP_PROTOCOL_ICMP)
	    {
	      icmp46_header_t *icmp = (void *) (ip + 1);
	      if (icmp->type == ICMP4_echo_request ||
		  icmp->type == ICMP4_echo_reply)
		{
		  return *((u16 *) (icmp + 1));
		}
	    }
	}
    }
  return -1;
}

i32
ip6_get_port (ip6_header_t * ip6, map_dir_e dir, u16 buffer_len)
{
  u8 l4_protocol;
  u16 l4_offset;
  u16 frag_offset;
  u8 *l4;

  if (ip6_parse (ip6, buffer_len, &l4_protocol, &l4_offset, &frag_offset))
    return -1;

  //TODO: Use buffer length

  if (frag_offset &&
      ip6_frag_hdr_offset (((ip6_frag_hdr_t *)
			    u8_ptr_add (ip6, frag_offset))))
    return -1;			//Can't deal with non-first fragment for now

  l4 = u8_ptr_add (ip6, l4_offset);
  if (l4_protocol == IP_PROTOCOL_TCP || l4_protocol == IP_PROTOCOL_UDP)
    {
      return (dir ==
	      MAP_SENDER) ? ((udp_header_t *) (l4))->src_port : ((udp_header_t
								  *)
								 (l4))->dst_port;
    }
  else if (l4_protocol == IP_PROTOCOL_ICMP6)
    {
      icmp46_header_t *icmp = (icmp46_header_t *) (l4);
      if (icmp->type == ICMP6_echo_request)
	{
	  return (dir == MAP_SENDER) ? ((u16 *) (icmp))[2] : -1;
	}
      else if (icmp->type == ICMP6_echo_reply)
	{
	  return (dir == MAP_SENDER) ? -1 : ((u16 *) (icmp))[2];
	}
    }
  return -1;
}


int
map_create_domain (ip4_address_t * ip4_prefix,
		   u8 ip4_prefix_len,
		   ip6_address_t * ip6_prefix,
		   u8 ip6_prefix_len,
		   ip6_address_t * ip6_src,
		   u8 ip6_src_len,
		   u8 ea_bits_len,
		   u8 psid_offset,
		   u8 psid_length, u32 * map_domain_index, u16 mtu, u8 flags)
{
  u8 suffix_len, suffix_shift;
  map_main_t *mm = &map_main;
  dpo_id_t dpo_v4 = DPO_INVALID;
  dpo_id_t dpo_v6 = DPO_INVALID;
  map_domain_t *d;

  /* Sanity check on the src prefix length */
  if (flags & MAP_DOMAIN_TRANSLATION)
    {
      if (ip6_src_len != 96)
	{
	  clib_warning ("MAP-T only supports ip6_src_len = 96 for now.");
	  return -1;
	}
    }
  else
    {
      if (ip6_src_len != 128)
	{
	  clib_warning
	    ("MAP-E requires a BR address, not a prefix (ip6_src_len should "
	     "be 128).");
	  return -1;
	}
    }

  /* How many, and which bits to grab from the IPv4 DA */
  if (ip4_prefix_len + ea_bits_len < 32)
    {
      flags |= MAP_DOMAIN_PREFIX;
      suffix_shift = 32 - ip4_prefix_len - ea_bits_len;
      suffix_len = ea_bits_len;
    }
  else
    {
      suffix_shift = 0;
      suffix_len = 32 - ip4_prefix_len;
    }

  /* EA bits must be within the first 64 bits */
  if (ea_bits_len > 0 && ((ip6_prefix_len + ea_bits_len) > 64 ||
			  ip6_prefix_len + suffix_len + psid_length > 64))
    {
      clib_warning
	("Embedded Address bits must be within the first 64 bits of "
	 "the IPv6 prefix");
      return -1;
    }

  /* Get domain index */
  pool_get_aligned (mm->domains, d, CLIB_CACHE_LINE_BYTES);
  memset (d, 0, sizeof (*d));
  *map_domain_index = d - mm->domains;

  /* Init domain struct */
  d->ip4_prefix.as_u32 = ip4_prefix->as_u32;
  d->ip4_prefix_len = ip4_prefix_len;
  d->ip6_prefix = *ip6_prefix;
  d->ip6_prefix_len = ip6_prefix_len;
  d->ip6_src = *ip6_src;
  d->ip6_src_len = ip6_src_len;
  d->ea_bits_len = ea_bits_len;
  d->psid_offset = psid_offset;
  d->psid_length = psid_length;
  d->mtu = mtu;
  d->flags = flags;
  d->suffix_shift = suffix_shift;
  d->suffix_mask = (1 << suffix_len) - 1;

  d->psid_shift = 16 - psid_length - psid_offset;
  d->psid_mask = (1 << d->psid_length) - 1;
  d->ea_shift = 64 - ip6_prefix_len - suffix_len - d->psid_length;

  /* MAP data-plane object */
  if (d->flags & MAP_DOMAIN_TRANSLATION)
    map_t_dpo_create (DPO_PROTO_IP4, *map_domain_index, &dpo_v4);
  else
    map_dpo_create (DPO_PROTO_IP4, *map_domain_index, &dpo_v4);

  /* Create ip4 route */
  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP4,
    .fp_len = d->ip4_prefix_len,
    .fp_addr = {
		.ip4 = d->ip4_prefix,
		}
    ,
  };
  fib_table_entry_special_dpo_add (0, &pfx,
				   FIB_SOURCE_MAP,
				   FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
  dpo_reset (&dpo_v4);

  /*
   * construct a DPO to use the v6 domain
   */
  if (d->flags & MAP_DOMAIN_TRANSLATION)
    map_t_dpo_create (DPO_PROTO_IP6, *map_domain_index, &dpo_v6);
  else
    map_dpo_create (DPO_PROTO_IP6, *map_domain_index, &dpo_v6);

  /*
   * Multiple MAP domains may share same source IPv6 TEP. Which is just dandy.
   * We are not tracking the sharing. So a v4 lookup to find the correct
   * domain post decap/trnaslate is always done
   *
   * Create ip6 route. This is a reference counted add. If the prefix
   * already exists and is MAP sourced, it is now MAP source n+1 times
   * and will need to be removed n+1 times.
   */
  fib_prefix_t pfx6 = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = d->ip6_src_len,
    .fp_addr.ip6 = d->ip6_src,
  };

  fib_table_entry_special_dpo_add (0, &pfx6,
				   FIB_SOURCE_MAP,
				   FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v6);
  dpo_reset (&dpo_v6);

  /* Validate packet/byte counters */
  map_domain_counter_lock (mm);
  int i;
  for (i = 0; i < vec_len (mm->simple_domain_counters); i++)
    {
      vlib_validate_simple_counter (&mm->simple_domain_counters[i],
				    *map_domain_index);
      vlib_zero_simple_counter (&mm->simple_domain_counters[i],
				*map_domain_index);
    }
  for (i = 0; i < vec_len (mm->domain_counters); i++)
    {
      vlib_validate_combined_counter (&mm->domain_counters[i],
				      *map_domain_index);
      vlib_zero_combined_counter (&mm->domain_counters[i], *map_domain_index);
    }
  map_domain_counter_unlock (mm);

  return 0;
}

/*
 * map_delete_domain
 */
int
map_delete_domain (u32 map_domain_index)
{
  map_main_t *mm = &map_main;
  map_domain_t *d;

  if (pool_is_free_index (mm->domains, map_domain_index))
    {
      clib_warning ("MAP domain delete: domain does not exist: %d",
		    map_domain_index);
      return -1;
    }

  d = pool_elt_at_index (mm->domains, map_domain_index);

  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP4,
    .fp_len = d->ip4_prefix_len,
    .fp_addr = {
		.ip4 = d->ip4_prefix,
		}
    ,
  };
  fib_table_entry_special_remove (0, &pfx, FIB_SOURCE_MAP);

  fib_prefix_t pfx6 = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = d->ip6_src_len,
    .fp_addr = {
		.ip6 = d->ip6_src,
		}
    ,
  };
  fib_table_entry_special_remove (0, &pfx6, FIB_SOURCE_MAP);

  /* Deleting rules */
  if (d->rules)
    clib_mem_free (d->rules);

  pool_put (mm->domains, d);

  return 0;
}

int
map_add_del_psid (u32 map_domain_index, u16 psid, ip6_address_t * tep,
		  u8 is_add)
{
  map_domain_t *d;
  map_main_t *mm = &map_main;

  if (pool_is_free_index (mm->domains, map_domain_index))
    {
      clib_warning ("MAP rule: domain does not exist: %d", map_domain_index);
      return -1;
    }
  d = pool_elt_at_index (mm->domains, map_domain_index);

  /* Rules are only used in 1:1 independent case */
  if (d->ea_bits_len > 0)
    return (-1);

  if (!d->rules)
    {
      u32 l = (0x1 << d->psid_length) * sizeof (ip6_address_t);
      d->rules = clib_mem_alloc_aligned (l, CLIB_CACHE_LINE_BYTES);
      if (!d->rules)
	return -1;
      memset (d->rules, 0, l);
    }

  if (psid >= (0x1 << d->psid_length))
    {
      clib_warning ("MAP rule: PSID outside bounds: %d [%d]", psid,
		    0x1 << d->psid_length);
      return -1;
    }

  if (is_add)
    {
      d->rules[psid] = *tep;
    }
  else
    {
      memset (&d->rules[psid], 0, sizeof (ip6_address_t));
    }
  return 0;
}

#ifdef MAP_SKIP_IP6_LOOKUP
/**
 * Pre-resolvd per-protocol global next-hops
 */
map_main_pre_resolved_t pre_resolved[FIB_PROTOCOL_MAX];

static void
map_pre_resolve_init (map_main_pre_resolved_t * pr)
{
  pr->fei = FIB_NODE_INDEX_INVALID;
  fib_node_init (&pr->node, FIB_NODE_TYPE_MAP_E);
}

static u8 *
format_map_pre_resolve (u8 * s, va_list ap)
{
  map_main_pre_resolved_t *pr = va_arg (ap, map_main_pre_resolved_t *);

  if (FIB_NODE_INDEX_INVALID != pr->fei)
    {
      fib_prefix_t pfx;

      fib_entry_get_prefix (pr->fei, &pfx);

      return (format (s, "%U (%u)",
		      format_ip46_address, &pfx.fp_addr, IP46_TYPE_ANY,
		      pr->dpo.dpoi_index));
    }
  else
    {
      return (format (s, "un-set"));
    }
}


/**
 * Function definition to inform the FIB node that its last lock has gone.
 */
static void
map_last_lock_gone (fib_node_t * node)
{
  /*
   * The MAP is a root of the graph. As such
   * it never has children and thus is never locked.
   */
  ASSERT (0);
}

static map_main_pre_resolved_t *
map_from_fib_node (fib_node_t * node)
{
#if (CLIB_DEBUG > 0)
  ASSERT (FIB_NODE_TYPE_MAP_E == node->fn_type);
#endif
  return ((map_main_pre_resolved_t *)
	  (((char *) node) -
	   STRUCT_OFFSET_OF (map_main_pre_resolved_t, node)));
}

static void
map_stack (map_main_pre_resolved_t * pr)
{
  const dpo_id_t *dpo;

  dpo = fib_entry_contribute_ip_forwarding (pr->fei);

  dpo_copy (&pr->dpo, dpo);
}

/**
 * Function definition to backwalk a FIB node
 */
static fib_node_back_walk_rc_t
map_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
{
  map_stack (map_from_fib_node (node));

  return (FIB_NODE_BACK_WALK_CONTINUE);
}

/**
 * Function definition to get a FIB node from its index
 */
static fib_node_t *
map_fib_node_get (fib_node_index_t index)
{
  return (&pre_resolved[index].node);
}

/*
 * Virtual function table registered by MPLS GRE tunnels
 * for participation in the FIB object graph.
 */
const static fib_node_vft_t map_vft = {
  .fnv_get = map_fib_node_get,
  .fnv_last_lock = map_last_lock_gone,
  .fnv_back_walk = map_back_walk,
};

static void
map_fib_resolve (map_main_pre_resolved_t * pr,
		 fib_protocol_t proto, u8 len, const ip46_address_t * addr)
{
  fib_prefix_t pfx = {
    .fp_proto = proto,
    .fp_len = len,
    .fp_addr = *addr,
  };

  pr->fei = fib_table_entry_special_add (0,	// default fib
					 &pfx,
					 FIB_SOURCE_RR,
					 FIB_ENTRY_FLAG_NONE,
					 ADJ_INDEX_INVALID);
  pr->sibling = fib_entry_child_add (pr->fei, FIB_NODE_TYPE_MAP_E, proto);
  map_stack (pr);
}

static void
map_fib_unresolve (map_main_pre_resolved_t * pr,
		   fib_protocol_t proto, u8 len, const ip46_address_t * addr)
{
  fib_prefix_t pfx = {
    .fp_proto = proto,
    .fp_len = len,
    .fp_addr = *addr,
  };

  fib_entry_child_remove (pr->fei, pr->sibling);

  fib_table_entry_special_remove (0,	// default fib
				  &pfx, FIB_SOURCE_RR);
  dpo_reset (&pr->dpo);

  pr->fei = FIB_NODE_INDEX_INVALID;
  pr->sibling = FIB_NODE_INDEX_INVALID;
}

static void
map_pre_resolve (ip4_address_t * ip4, ip6_address_t * ip6, int is_del)
{
  if (ip6 && (ip6->as_u64[0] != 0 || ip6->as_u64[1] != 0))
    {
      ip46_address_t addr = {
	.ip6 = *ip6,
      };
      if (is_del)
	map_fib_unresolve (&pre_resolved[FIB_PROTOCOL_IP6],
			   FIB_PROTOCOL_IP6, 128, &addr);
      else
	map_fib_resolve (&pre_resolved[FIB_PROTOCOL_IP6],
			 FIB_PROTOCOL_IP6, 128, &addr);
    }
  if (ip4 && (ip4->as_u32 != 0))
    {
      ip46_address_t addr = {
	.ip4 = *ip4,
      };
      if (is_del)
	map_fib_unresolve (&pre_resolved[FIB_PROTOCOL_IP4],
			   FIB_PROTOCOL_IP4, 32, &addr);
      else
	map_fib_resolve (&pre_resolved[FIB_PROTOCOL_IP4],
			 FIB_PROTOCOL_IP4, 32, &addr);
    }
}
#endif

static clib_error_t *
map_security_check_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "off"))
	mm->sec_check = false;
      else if (unformat (line_input, "on"))
	mm->sec_check = true;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_security_check_frag_command_fn (vlib_main_t * vm,
				    unformat_input_t * input,
				    vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "off"))
	mm->sec_check_frag = false;
      else if (unformat (line_input, "on"))
	mm->sec_check_frag = true;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_add_domain_command_fn (vlib_main_t * vm,
			   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip4_address_t ip4_prefix;
  ip6_address_t ip6_prefix;
  ip6_address_t ip6_src;
  u32 ip6_prefix_len = 0, ip4_prefix_len = 0, map_domain_index, ip6_src_len;
  u32 num_m_args = 0;
  /* Optional arguments */
  u32 ea_bits_len = 0, psid_offset = 0, psid_length = 0;
  u32 mtu = 0;
  u8 flags = 0;
  ip6_src_len = 128;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (line_input, "ip4-pfx %U/%d", unformat_ip4_address, &ip4_prefix,
	   &ip4_prefix_len))
	num_m_args++;
      else
	if (unformat
	    (line_input, "ip6-pfx %U/%d", unformat_ip6_address, &ip6_prefix,
	     &ip6_prefix_len))
	num_m_args++;
      else
	if (unformat
	    (line_input, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
	     &ip6_src_len))
	num_m_args++;
      else
	if (unformat
	    (line_input, "ip6-src %U", unformat_ip6_address, &ip6_src))
	num_m_args++;
      else if (unformat (line_input, "ea-bits-len %d", &ea_bits_len))
	num_m_args++;
      else if (unformat (line_input, "psid-offset %d", &psid_offset))
	num_m_args++;
      else if (unformat (line_input, "psid-len %d", &psid_length))
	num_m_args++;
      else if (unformat (line_input, "mtu %d", &mtu))
	num_m_args++;
      else if (unformat (line_input, "map-t"))
	flags |= MAP_DOMAIN_TRANSLATION;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (num_m_args < 3)
    {
      error = clib_error_return (0, "mandatory argument(s) missing");
      goto done;
    }

  map_create_domain (&ip4_prefix, ip4_prefix_len,
		     &ip6_prefix, ip6_prefix_len, &ip6_src, ip6_src_len,
		     ea_bits_len, psid_offset, psid_length, &map_domain_index,
		     mtu, flags);

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_del_domain_command_fn (vlib_main_t * vm,
			   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 num_m_args = 0;
  u32 map_domain_index;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "index %d", &map_domain_index))
	num_m_args++;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (num_m_args != 1)
    {
      error = clib_error_return (0, "mandatory argument(s) missing");
      goto done;
    }

  map_delete_domain (map_domain_index);

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_add_rule_command_fn (vlib_main_t * vm,
			 unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip6_address_t tep;
  u32 num_m_args = 0;
  u32 psid = 0, map_domain_index;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "index %d", &map_domain_index))
	num_m_args++;
      else if (unformat (line_input, "psid %d", &psid))
	num_m_args++;
      else
	if (unformat (line_input, "ip6-dst %U", unformat_ip6_address, &tep))
	num_m_args++;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (num_m_args != 3)
    {
      error = clib_error_return (0, "mandatory argument(s) missing");
      goto done;
    }

  if (map_add_del_psid (map_domain_index, psid, &tep, 1) != 0)
    {
      error = clib_error_return (0, "Failing to add Mapping Rule");
      goto done;
    }

done:
  unformat_free (line_input);

  return error;
}

#if MAP_SKIP_IP6_LOOKUP
static clib_error_t *
map_pre_resolve_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip4_address_t ip4nh, *p_v4 = NULL;
  ip6_address_t ip6nh, *p_v6 = NULL;
  clib_error_t *error = NULL;
  int is_del = 0;

  memset (&ip4nh, 0, sizeof (ip4nh));
  memset (&ip6nh, 0, sizeof (ip6nh));

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "ip4-nh %U", unformat_ip4_address, &ip4nh))
	p_v4 = &ip4nh;
      else
	if (unformat (line_input, "ip6-nh %U", unformat_ip6_address, &ip6nh))
	p_v6 = &ip6nh;
      else if (unformat (line_input, "del"))
	is_del = 1;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  map_pre_resolve (p_v4, p_v6, is_del);

done:
  unformat_free (line_input);

  return error;
}
#endif

static clib_error_t *
map_icmp_relay_source_address_command_fn (vlib_main_t * vm,
					  unformat_input_t * input,
					  vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip4_address_t icmp_src_address;
  map_main_t *mm = &map_main;
  clib_error_t *error = NULL;

  mm->icmp4_src_address.as_u32 = 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (line_input, "%U", unformat_ip4_address, &icmp_src_address))
	mm->icmp4_src_address = icmp_src_address;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_icmp_unreachables_command_fn (vlib_main_t * vm,
				  unformat_input_t * input,
				  vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  int num_m_args = 0;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      num_m_args++;
      if (unformat (line_input, "on"))
	mm->icmp6_enabled = true;
      else if (unformat (line_input, "off"))
	mm->icmp6_enabled = false;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }


  if (num_m_args != 1)
    error = clib_error_return (0, "mandatory argument(s) missing");

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_fragment_command_fn (vlib_main_t * vm,
			 unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "inner"))
	mm->frag_inner = true;
      else if (unformat (line_input, "outer"))
	mm->frag_inner = false;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_fragment_df_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "on"))
	mm->frag_ignore_df = true;
      else if (unformat (line_input, "off"))
	mm->frag_ignore_df = false;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
map_traffic_class_command_fn (vlib_main_t * vm,
			      unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  u32 tc = 0;
  clib_error_t *error = NULL;

  mm->tc_copy = false;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "copy"))
	mm->tc_copy = true;
      else if (unformat (line_input, "%x", &tc))
	mm->tc = tc & 0xff;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);

  return error;
}

static u8 *
format_map_domain (u8 * s, va_list * args)
{
  map_domain_t *d = va_arg (*args, map_domain_t *);
  bool counters = va_arg (*args, int);
  map_main_t *mm = &map_main;
  ip6_address_t ip6_prefix;

  if (d->rules)
    memset (&ip6_prefix, 0, sizeof (ip6_prefix));
  else
    ip6_prefix = d->ip6_prefix;

  s = format (s,
	      "[%d] ip4-pfx %U/%d ip6-pfx %U/%d ip6-src %U/%d ea_bits_len %d psid-offset %d psid-len %d mtu %d %s",
	      d - mm->domains,
	      format_ip4_address, &d->ip4_prefix, d->ip4_prefix_len,
	      format_ip6_address, &ip6_prefix, d->ip6_prefix_len,
	      format_ip6_address, &d->ip6_src, d->ip6_src_len,
	      d->ea_bits_len, d->psid_offset, d->psid_length, d->mtu,
	      (d->flags & MAP_DOMAIN_TRANSLATION) ? "map-t" : "");

  if (counters)
    {
      map_domain_counter_lock (mm);
      vlib_counter_t v;
      vlib_get_combined_counter (&mm->domain_counters[MAP_DOMAIN_COUNTER_TX],
				 d - mm->domains, &v);
      s = format (s, "  TX: %lld/%lld", v.packets, v.bytes);
      vlib_get_combined_counter (&mm->domain_counters[MAP_DOMAIN_COUNTER_RX],
				 d - mm->domains, &v);
      s = format (s, "  RX: %lld/%lld", v.packets, v.bytes);
      map_domain_counter_unlock (mm);
    }
  s = format (s, "\n");

  if (d->rules)
    {
      int i;
      ip6_address_t dst;
      for (i = 0; i < (0x1 << d->psid_length); i++)
	{
	  dst = d->rules[i];
	  if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
	    continue;
	  s = format (s,
		      " rule psid: %d ip6-dst %U\n", i, format_ip6_address,
		      &dst);
	}
    }
  return s;
}

static u8 *
format_map_ip4_reass (u8 * s, va_list * args)
{
  map_main_t *mm = &map_main;
  map_ip4_reass_t *r = va_arg (*args, map_ip4_reass_t *);
  map_ip4_reass_key_t *k = &r->key;
  f64 now = vlib_time_now (mm->vlib_main);
  f64 lifetime = (((f64) mm->ip4_reass_conf_lifetime_ms) / 1000);
  f64 dt = (r->ts + lifetime > now) ? (r->ts + lifetime - now) : -1;
  s = format (s,
	      "ip4-reass src=%U  dst=%U  protocol=%d  identifier=%d  port=%d  lifetime=%.3lf\n",
	      format_ip4_address, &k->src.as_u8, format_ip4_address,
	      &k->dst.as_u8, k->protocol,
	      clib_net_to_host_u16 (k->fragment_id),
	      (r->port >= 0) ? clib_net_to_host_u16 (r->port) : -1, dt);
  return s;
}

static u8 *
format_map_ip6_reass (u8 * s, va_list * args)
{
  map_main_t *mm = &map_main;
  map_ip6_reass_t *r = va_arg (*args, map_ip6_reass_t *);
  map_ip6_reass_key_t *k = &r->key;
  f64 now = vlib_time_now (mm->vlib_main);
  f64 lifetime = (((f64) mm->ip6_reass_conf_lifetime_ms) / 1000);
  f64 dt = (r->ts + lifetime > now) ? (r->ts + lifetime - now) : -1;
  s = format (s,
	      "ip6-reass src=%U  dst=%U  protocol=%d  identifier=%d  lifetime=%.3lf\n",
	      format_ip6_address, &k->src.as_u8, format_ip6_address,
	      &k->dst.as_u8, k->protocol,
	      clib_net_to_host_u32 (k->fragment_id), dt);
  return s;
}

static clib_error_t *
show_map_domain_command_fn (vlib_main_t * vm, unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  map_main_t *mm = &map_main;
  map_domain_t *d;
  bool counters = false;
  u32 map_domain_index = ~0;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "counters"))
	counters = true;
      else if (unformat (line_input, "index %d", &map_domain_index))
	;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (pool_elts (mm->domains) == 0)
    vlib_cli_output (vm, "No MAP domains are configured...");

  if (map_domain_index == ~0)
    {
    /* *INDENT-OFF* */
    pool_foreach(d, mm->domains, ({vlib_cli_output(vm, "%U", format_map_domain, d, counters);}));
    /* *INDENT-ON* */
    }
  else
    {
      if (pool_is_free_index (mm->domains, map_domain_index))
	{
	  error = clib_error_return (0, "MAP domain does not exists %d",
				     map_domain_index);
	  goto done;
	}

      d = pool_elt_at_index (mm->domains, map_domain_index);
      vlib_cli_output (vm, "%U", format_map_domain, d, counters);
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
show_map_fragments_command_fn (vlib_main_t * vm, unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  map_main_t *mm = &map_main;
  map_ip4_reass_t *f4;
  map_ip6_reass_t *f6;

  /* *INDENT-OFF* */
  pool_foreach(f4, mm->ip4_reass_pool, ({vlib_cli_output (vm, "%U", format_map_ip4_reass, f4);}));
  /* *INDENT-ON* */
  /* *INDENT-OFF* */
  pool_foreach(f6, mm->ip6_reass_pool, ({vlib_cli_output (vm, "%U", format_map_ip6_reass, f6);}));
  /* *INDENT-ON* */
  return (0);
}

u64
map_error_counter_get (u32 node_index, map_error_t map_error)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_node_runtime_t *error_node = vlib_node_get_runtime (vm, node_index);
  vlib_error_main_t *em = &vm->error_main;
  vlib_error_t e = error_node->errors[map_error];
  vlib_node_t *n = vlib_get_node (vm, node_index);
  u32 ci;

  ci = vlib_error_get_code (e);
  ASSERT (ci < n->n_errors);
  ci += n->error_heap_index;

  return (em->counters[ci]);
}

static clib_error_t *
show_map_stats_command_fn (vlib_main_t * vm, unformat_input_t * input,
			   vlib_cli_command_t * cmd)
{
  map_main_t *mm = &map_main;
  map_domain_t *d;
  int domains = 0, rules = 0, domaincount = 0, rulecount = 0;
  if (pool_elts (mm->domains) == 0)
    vlib_cli_output (vm, "No MAP domains are configured...");

  /* *INDENT-OFF* */
  pool_foreach(d, mm->domains, ({
    if (d->rules) {
      rulecount+= 0x1 << d->psid_length;
      rules += sizeof(ip6_address_t) * 0x1 << d->psid_length;
    }
    domains += sizeof(*d);
    domaincount++;
  }));
  /* *INDENT-ON* */

  vlib_cli_output (vm, "MAP domains structure: %d\n", sizeof (map_domain_t));
  vlib_cli_output (vm, "MAP domains: %d (%d bytes)\n", domaincount, domains);
  vlib_cli_output (vm, "MAP rules: %d (%d bytes)\n", rulecount, rules);
  vlib_cli_output (vm, "Total: %d bytes)\n", rules + domains);

#if MAP_SKIP_IP6_LOOKUP
  vlib_cli_output (vm,
		   "MAP pre-resolve: IP6 next-hop: %U, IP4 next-hop: %U\n",
		   format_map_pre_resolve, &pre_resolved[FIB_PROTOCOL_IP6],
		   format_map_pre_resolve, &pre_resolved[FIB_PROTOCOL_IP4]);

#endif

  if (mm->tc_copy)
    vlib_cli_output (vm, "MAP traffic-class: copy");
  else
    vlib_cli_output (vm, "MAP traffic-class: %x", mm->tc);

  vlib_cli_output (vm,
		   "MAP IPv6 inbound security check: %s, fragmented packet security check: %s",
		   mm->sec_check ? "enabled" : "disabled",
		   mm->sec_check_frag ? "enabled" : "disabled");

  vlib_cli_output (vm, "ICMP-relay IPv4 source address: %U\n",
		   format_ip4_address, &mm->icmp4_src_address);
  vlib_cli_output (vm, "ICMP6 unreachables sent for unmatched packets: %s\n",
		   mm->icmp6_enabled ? "enabled" : "disabled");
  vlib_cli_output (vm, "Inner fragmentation: %s\n",
		   mm->frag_inner ? "enabled" : "disabled");
  vlib_cli_output (vm, "Fragment packets regardless of DF flag: %s\n",
		   mm->frag_ignore_df ? "enabled" : "disabled");

  /*
   * Counters
   */
  vlib_combined_counter_main_t *cm = mm->domain_counters;
  u64 total_pkts[MAP_N_DOMAIN_COUNTER];
  u64 total_bytes[MAP_N_DOMAIN_COUNTER];
  int which, i;
  vlib_counter_t v;

  memset (total_pkts, 0, sizeof (total_pkts));
  memset (total_bytes, 0, sizeof (total_bytes));

  map_domain_counter_lock (mm);
  vec_foreach (cm, mm->domain_counters)
  {
    which = cm - mm->domain_counters;

    for (i = 0; i < vlib_combined_counter_n_counters (cm); i++)
      {
	vlib_get_combined_counter (cm, i, &v);
	total_pkts[which] += v.packets;
	total_bytes[which] += v.bytes;
      }
  }
  map_domain_counter_unlock (mm);

  vlib_cli_output (vm, "Encapsulated packets: %lld bytes: %lld\n",
		   total_pkts[MAP_DOMAIN_COUNTER_TX],
		   total_bytes[MAP_DOMAIN_COUNTER_TX]);
  vlib_cli_output (vm, "Decapsulated packets: %lld bytes: %lld\n",
		   total_pkts[MAP_DOMAIN_COUNTER_RX],
		   total_bytes[MAP_DOMAIN_COUNTER_RX]);

  vlib_cli_output (vm, "ICMP relayed packets: %d\n",
		   vlib_get_simple_counter (&mm->icmp_relayed, 0));

  return 0;
}

static clib_error_t *
map_params_reass_command_fn (vlib_main_t * vm, unformat_input_t * input,
			     vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 lifetime = ~0;
  f64 ht_ratio = (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1);
  u32 pool_size = ~0;
  u64 buffers = ~(0ull);
  u8 ip4 = 0, ip6 = 0;

  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "lifetime %u", &lifetime))
	;
      else if (unformat (line_input, "ht-ratio %lf", &ht_ratio))
	;
      else if (unformat (line_input, "pool-size %u", &pool_size))
	;
      else if (unformat (line_input, "buffers %llu", &buffers))
	;
      else if (unformat (line_input, "ip4"))
	ip4 = 1;
      else if (unformat (line_input, "ip6"))
	ip6 = 1;
      else
	{
	  unformat_free (line_input);
	  return clib_error_return (0, "invalid input");
	}
    }
  unformat_free (line_input);

  if (!ip4 && !ip6)
    return clib_error_return (0, "must specify ip4 and/or ip6");

  if (ip4)
    {
      if (pool_size != ~0 && pool_size > MAP_IP4_REASS_CONF_POOL_SIZE_MAX)
	return clib_error_return (0, "invalid ip4-reass pool-size ( > %d)",
				  MAP_IP4_REASS_CONF_POOL_SIZE_MAX);
      if (ht_ratio != (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1)
	  && ht_ratio > MAP_IP4_REASS_CONF_HT_RATIO_MAX)
	return clib_error_return (0, "invalid ip4-reass ht-ratio ( > %d)",
				  MAP_IP4_REASS_CONF_HT_RATIO_MAX);
      if (lifetime != ~0 && lifetime > MAP_IP4_REASS_CONF_LIFETIME_MAX)
	return clib_error_return (0, "invalid ip4-reass lifetime ( > %d)",
				  MAP_IP4_REASS_CONF_LIFETIME_MAX);
      if (buffers != ~(0ull) && buffers > MAP_IP4_REASS_CONF_BUFFERS_MAX)
	return clib_error_return (0, "invalid ip4-reass buffers ( > %ld)",
				  MAP_IP4_REASS_CONF_BUFFERS_MAX);
    }

  if (ip6)
    {
      if (pool_size != ~0 && pool_size > MAP_IP6_REASS_CONF_POOL_SIZE_MAX)
	return clib_error_return (0, "invalid ip6-reass pool-size ( > %d)",
				  MAP_IP6_REASS_CONF_POOL_SIZE_MAX);
      if (ht_ratio != (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1)
	  && ht_ratio > MAP_IP6_REASS_CONF_HT_RATIO_MAX)
	return clib_error_return (0, "invalid ip6-reass ht-log2len ( > %d)",
				  MAP_IP6_REASS_CONF_HT_RATIO_MAX);
      if (lifetime != ~0 && lifetime > MAP_IP6_REASS_CONF_LIFETIME_MAX)
	return clib_error_return (0, "invalid ip6-reass lifetime ( > %d)",
				  MAP_IP6_REASS_CONF_LIFETIME_MAX);
      if (buffers != ~(0ull) && buffers > MAP_IP6_REASS_CONF_BUFFERS_MAX)
	return clib_error_return (0, "invalid ip6-reass buffers ( > %ld)",
				  MAP_IP6_REASS_CONF_BUFFERS_MAX);
    }

  if (ip4)
    {
      u32 reass = 0, packets = 0;
      if (pool_size != ~0)
	{
	  if (map_ip4_reass_conf_pool_size (pool_size, &reass, &packets))
	    {
	      vlib_cli_output (vm, "Could not set ip4-reass pool-size");
	    }
	  else
	    {
	      vlib_cli_output (vm,
			       "Setting ip4-reass pool-size (destroyed-reassembly=%u , dropped-fragments=%u)",
			       reass, packets);
	    }
	}
      if (ht_ratio != (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1))
	{
	  if (map_ip4_reass_conf_ht_ratio (ht_ratio, &reass, &packets))
	    {
	      vlib_cli_output (vm, "Could not set ip4-reass ht-log2len");
	    }
	  else
	    {
	      vlib_cli_output (vm,
			       "Setting ip4-reass ht-log2len (destroyed-reassembly=%u , dropped-fragments=%u)",
			       reass, packets);
	    }
	}
      if (lifetime != ~0)
	{
	  if (map_ip4_reass_conf_lifetime (lifetime))
	    vlib_cli_output (vm, "Could not set ip4-reass lifetime");
	  else
	    vlib_cli_output (vm, "Setting ip4-reass lifetime");
	}
      if (buffers != ~(0ull))
	{
	  if (map_ip4_reass_conf_buffers (buffers))
	    vlib_cli_output (vm, "Could not set ip4-reass buffers");
	  else
	    vlib_cli_output (vm, "Setting ip4-reass buffers");
	}

      if (map_main.ip4_reass_conf_buffers >
	  map_main.ip4_reass_conf_pool_size *
	  MAP_IP4_REASS_MAX_FRAGMENTS_PER_REASSEMBLY)
	{
	  vlib_cli_output (vm,
			   "Note: 'ip4-reass buffers' > pool-size * max-fragments-per-reassembly.");
	}
    }

  if (ip6)
    {
      u32 reass = 0, packets = 0;
      if (pool_size != ~0)
	{
	  if (map_ip6_reass_conf_pool_size (pool_size, &reass, &packets))
	    {
	      vlib_cli_output (vm, "Could not set ip6-reass pool-size");
	    }
	  else
	    {
	      vlib_cli_output (vm,
			       "Setting ip6-reass pool-size (destroyed-reassembly=%u , dropped-fragments=%u)",
			       reass, packets);
	    }
	}
      if (ht_ratio != (MAP_IP4_REASS_CONF_HT_RATIO_MAX + 1))
	{
	  if (map_ip6_reass_conf_ht_ratio (ht_ratio, &reass, &packets))
	    {
	      vlib_cli_output (vm, "Could not set ip6-reass ht-log2len");
	    }
	  else
	    {
	      vlib_cli_output (vm,
			       "Setting ip6-reass ht-log2len (destroyed-reassembly=%u , dropped-fragments=%u)",
			       reass, packets);
	    }
	}
      if (lifetime != ~0)
	{
	  if (map_ip6_reass_conf_lifetime (lifetime))
	    vlib_cli_output (vm, "Could not set ip6-reass lifetime");
	  else
	    vlib_cli_output (vm, "Setting ip6-reass lifetime");
	}
      if (buffers != ~(0ull))
	{
	  if (map_ip6_reass_conf_buffers (buffers))
	    vlib_cli_output (vm, "Could not set ip6-reass buffers");
	  else
	    vlib_cli_output (vm, "Setting ip6-reass buffers");
	}

      if (map_main.ip6_reass_conf_buffers >
	  map_main.ip6_reass_conf_pool_size *
	  MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY)
	{
	  vlib_cli_output (vm,
			   "Note: 'ip6-reass buffers' > pool-size * max-fragments-per-reassembly.");
	}
    }

  return 0;
}


/*
 * packet trace format function
 */
u8 *
format_map_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 *);
  map_trace_t *t = va_arg (*args, map_trace_t *);
  u32 map_domain_index = t->map_domain_index;
  u16 port = t->port;

  s =
    format (s, "MAP domain index: %d L4 port: %u", map_domain_index,
	    clib_net_to_host_u16 (port));

  return s;
}

static_always_inline map_ip4_reass_t *
map_ip4_reass_lookup (map_ip4_reass_key_t * k, u32 bucket, f64 now)
{
  map_main_t *mm = &map_main;
  u32 ri = mm->ip4_reass_hash_table[bucket];
  while (ri != MAP_REASS_INDEX_NONE)
    {
      map_ip4_reass_t *r = pool_elt_at_index (mm->ip4_reass_pool, ri);
      if (r->key.as_u64[0] == k->as_u64[0] &&
	  r->key.as_u64[1] == k->as_u64[1] &&
	  now < r->ts + (((f64) mm->ip4_reass_conf_lifetime_ms) / 1000))
	{
	  return r;
	}
      ri = r->bucket_next;
    }
  return NULL;
}

#define map_ip4_reass_pool_index(r) (r - map_main.ip4_reass_pool)

void
map_ip4_reass_free (map_ip4_reass_t * r, u32 ** pi_to_drop)
{
  map_main_t *mm = &map_main;
  map_ip4_reass_get_fragments (r, pi_to_drop);

  // Unlink in hash bucket
  map_ip4_reass_t *r2 = NULL;
  u32 r2i = mm->ip4_reass_hash_table[r->bucket];
  while (r2i != map_ip4_reass_pool_index (r))
    {
      ASSERT (r2i != MAP_REASS_INDEX_NONE);
      r2 = pool_elt_at_index (mm->ip4_reass_pool, r2i);
      r2i = r2->bucket_next;
    }
  if (r2)
    {
      r2->bucket_next = r->bucket_next;
    }
  else
    {
      mm->ip4_reass_hash_table[r->bucket] = r->bucket_next;
    }

  // Unlink in list
  if (r->fifo_next == map_ip4_reass_pool_index (r))
    {
      mm->ip4_reass_fifo_last = MAP_REASS_INDEX_NONE;
    }
  else
    {
      if (mm->ip4_reass_fifo_last == map_ip4_reass_pool_index (r))
	mm->ip4_reass_fifo_last = r->fifo_prev;
      pool_elt_at_index (mm->ip4_reass_pool, r->fifo_prev)->fifo_next =
	r->fifo_next;
      pool_elt_at_index (mm->ip4_reass_pool, r->fifo_next)->fifo_prev =
	r->fifo_prev;
    }

  pool_put (mm->ip4_reass_pool, r);
  mm->ip4_reass_allocated--;
}

map_ip4_reass_t *
map_ip4_reass_get (u32 src, u32 dst, u16 fragment_id,
		   u8 protocol, u32 ** pi_to_drop)
{
  map_ip4_reass_t *r;
  map_main_t *mm = &map_main;
  map_ip4_reass_key_t k = {.src.data_u32 = src,
    .dst.data_u32 = dst,
    .fragment_id = fragment_id,
    .protocol = protocol
  };

  u32 h = 0;
  h = crc_u32 (k.as_u32[0], h);
  h = crc_u32 (k.as_u32[1], h);
  h = crc_u32 (k.as_u32[2], h);
  h = crc_u32 (k.as_u32[3], h);
  h = h >> (32 - mm->ip4_reass_ht_log2len);

  f64 now = vlib_time_now (mm->vlib_main);

  //Cache garbage collection
  while (mm->ip4_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      map_ip4_reass_t *last =
	pool_elt_at_index (mm->ip4_reass_pool, mm->ip4_reass_fifo_last);
      if (last->ts + (((f64) mm->ip4_reass_conf_lifetime_ms) / 1000) < now)
	map_ip4_reass_free (last, pi_to_drop);
      else
	break;
    }

  if ((r = map_ip4_reass_lookup (&k, h, now)))
    return r;

  if (mm->ip4_reass_allocated >= mm->ip4_reass_conf_pool_size)
    return NULL;

  pool_get (mm->ip4_reass_pool, r);
  mm->ip4_reass_allocated++;
  int i;
  for (i = 0; i < MAP_IP4_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
    r->fragments[i] = ~0;

  u32 ri = map_ip4_reass_pool_index (r);

  //Link in new bucket
  r->bucket = h;
  r->bucket_next = mm->ip4_reass_hash_table[h];
  mm->ip4_reass_hash_table[h] = ri;

  //Link in fifo
  if (mm->ip4_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      r->fifo_next =
	pool_elt_at_index (mm->ip4_reass_pool,
			   mm->ip4_reass_fifo_last)->fifo_next;
      r->fifo_prev = mm->ip4_reass_fifo_last;
      pool_elt_at_index (mm->ip4_reass_pool, r->fifo_prev)->fifo_next = ri;
      pool_elt_at_index (mm->ip4_reass_pool, r->fifo_next)->fifo_prev = ri;
    }
  else
    {
      r->fifo_next = r->fifo_prev = ri;
      mm->ip4_reass_fifo_last = ri;
    }

  //Set other fields
  r->ts = now;
  r->key = k;
  r->port = -1;
#ifdef MAP_IP4_REASS_COUNT_BYTES
  r->expected_total = 0xffff;
  r->forwarded = 0;
#endif

  return r;
}

int
map_ip4_reass_add_fragment (map_ip4_reass_t * r, u32 pi)
{
  if (map_main.ip4_reass_buffered_counter >= map_main.ip4_reass_conf_buffers)
    return -1;

  int i;
  for (i = 0; i < MAP_IP4_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
    if (r->fragments[i] == ~0)
      {
	r->fragments[i] = pi;
	map_main.ip4_reass_buffered_counter++;
	return 0;
      }
  return -1;
}

static_always_inline map_ip6_reass_t *
map_ip6_reass_lookup (map_ip6_reass_key_t * k, u32 bucket, f64 now)
{
  map_main_t *mm = &map_main;
  u32 ri = mm->ip6_reass_hash_table[bucket];
  while (ri != MAP_REASS_INDEX_NONE)
    {
      map_ip6_reass_t *r = pool_elt_at_index (mm->ip6_reass_pool, ri);
      if (now < r->ts + (((f64) mm->ip6_reass_conf_lifetime_ms) / 1000) &&
	  r->key.as_u64[0] == k->as_u64[0] &&
	  r->key.as_u64[1] == k->as_u64[1] &&
	  r->key.as_u64[2] == k->as_u64[2] &&
	  r->key.as_u64[3] == k->as_u64[3] &&
	  r->key.as_u64[4] == k->as_u64[4])
	return r;
      ri = r->bucket_next;
    }
  return NULL;
}

#define map_ip6_reass_pool_index(r) (r - map_main.ip6_reass_pool)

void
map_ip6_reass_free (map_ip6_reass_t * r, u32 ** pi_to_drop)
{
  map_main_t *mm = &map_main;
  int i;
  for (i = 0; i < MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
    if (r->fragments[i].pi != ~0)
      {
	vec_add1 (*pi_to_drop, r->fragments[i].pi);
	r->fragments[i].pi = ~0;
	map_main.ip6_reass_buffered_counter--;
      }

  // Unlink in hash bucket
  map_ip6_reass_t *r2 = NULL;
  u32 r2i = mm->ip6_reass_hash_table[r->bucket];
  while (r2i != map_ip6_reass_pool_index (r))
    {
      ASSERT (r2i != MAP_REASS_INDEX_NONE);
      r2 = pool_elt_at_index (mm->ip6_reass_pool, r2i);
      r2i = r2->bucket_next;
    }
  if (r2)
    {
      r2->bucket_next = r->bucket_next;
    }
  else
    {
      mm->ip6_reass_hash_table[r->bucket] = r->bucket_next;
    }

  // Unlink in list
  if (r->fifo_next == map_ip6_reass_pool_index (r))
    {
      //Single element in the list, list is now empty
      mm->ip6_reass_fifo_last = MAP_REASS_INDEX_NONE;
    }
  else
    {
      if (mm->ip6_reass_fifo_last == map_ip6_reass_pool_index (r))	//First element
	mm->ip6_reass_fifo_last = r->fifo_prev;
      pool_elt_at_index (mm->ip6_reass_pool, r->fifo_prev)->fifo_next =
	r->fifo_next;
      pool_elt_at_index (mm->ip6_reass_pool, r->fifo_next)->fifo_prev =
	r->fifo_prev;
    }

  // Free from pool if necessary
  pool_put (mm->ip6_reass_pool, r);
  mm->ip6_reass_allocated--;
}

map_ip6_reass_t *
map_ip6_reass_get (ip6_address_t * src, ip6_address_t * dst, u32 fragment_id,
		   u8 protocol, u32 ** pi_to_drop)
{
  map_ip6_reass_t *r;
  map_main_t *mm = &map_main;
  map_ip6_reass_key_t k = {
    .src = *src,
    .dst = *dst,
    .fragment_id = fragment_id,
    .protocol = protocol
  };

  u32 h = 0;
  int i;
  for (i = 0; i < 10; i++)
    h = crc_u32 (k.as_u32[i], h);
  h = h >> (32 - mm->ip6_reass_ht_log2len);

  f64 now = vlib_time_now (mm->vlib_main);

  //Cache garbage collection
  while (mm->ip6_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      map_ip6_reass_t *last =
	pool_elt_at_index (mm->ip6_reass_pool, mm->ip6_reass_fifo_last);
      if (last->ts + (((f64) mm->ip6_reass_conf_lifetime_ms) / 1000) < now)
	map_ip6_reass_free (last, pi_to_drop);
      else
	break;
    }

  if ((r = map_ip6_reass_lookup (&k, h, now)))
    return r;

  if (mm->ip6_reass_allocated >= mm->ip6_reass_conf_pool_size)
    return NULL;

  pool_get (mm->ip6_reass_pool, r);
  mm->ip6_reass_allocated++;
  for (i = 0; i < MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
    {
      r->fragments[i].pi = ~0;
      r->fragments[i].next_data_len = 0;
      r->fragments[i].next_data_offset = 0;
    }

  u32 ri = map_ip6_reass_pool_index (r);

  //Link in new bucket
  r->bucket = h;
  r->bucket_next = mm->ip6_reass_hash_table[h];
  mm->ip6_reass_hash_table[h] = ri;

  //Link in fifo
  if (mm->ip6_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      r->fifo_next =
	pool_elt_at_index (mm->ip6_reass_pool,
			   mm->ip6_reass_fifo_last)->fifo_next;
      r->fifo_prev = mm->ip6_reass_fifo_last;
      pool_elt_at_index (mm->ip6_reass_pool, r->fifo_prev)->fifo_next = ri;
      pool_elt_at_index (mm->ip6_reass_pool, r->fifo_next)->fifo_prev = ri;
    }
  else
    {
      r->fifo_next = r->fifo_prev = ri;
      mm->ip6_reass_fifo_last = ri;
    }

  //Set other fields
  r->ts = now;
  r->key = k;
  r->ip4_header.ip_version_and_header_length = 0;
#ifdef MAP_IP6_REASS_COUNT_BYTES
  r->expected_total = 0xffff;
  r->forwarded = 0;
#endif
  return r;
}

int
map_ip6_reass_add_fragment (map_ip6_reass_t * r, u32 pi,
			    u16 data_offset, u16 next_data_offset,
			    u8 * data_start, u16 data_len)
{
  map_ip6_fragment_t *f = NULL, *prev_f = NULL;
  u16 copied_len = (data_len > 20) ? 20 : data_len;

  if (map_main.ip6_reass_buffered_counter >= map_main.ip6_reass_conf_buffers)
    return -1;

  //Lookup for fragments for the current buffer
  //and the one before that
  int i;
  for (i = 0; i < MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
    {
      if (data_offset && r->fragments[i].next_data_offset == data_offset)
	{
	  prev_f = &r->fragments[i];	// This is buffer for previous packet
	}
      else if (r->fragments[i].next_data_offset == next_data_offset)
	{
	  f = &r->fragments[i];	// This is a buffer for the current packet
	}
      else if (r->fragments[i].next_data_offset == 0)
	{			//Available
	  if (f == NULL)
	    f = &r->fragments[i];
	  else if (prev_f == NULL)
	    prev_f = &r->fragments[i];
	}
    }

  if (!f || f->pi != ~0)
    return -1;

  if (data_offset)
    {
      if (!prev_f)
	return -1;

      clib_memcpy (prev_f->next_data, data_start, copied_len);
      prev_f->next_data_len = copied_len;
      prev_f->next_data_offset = data_offset;
    }
  else
    {
      if (((ip4_header_t *) data_start)->ip_version_and_header_length != 0x45)
	return -1;

      if (r->ip4_header.ip_version_and_header_length == 0)
	clib_memcpy (&r->ip4_header, data_start, sizeof (ip4_header_t));
    }

  if (data_len > 20)
    {
      f->next_data_offset = next_data_offset;
      f->pi = pi;
      map_main.ip6_reass_buffered_counter++;
    }
  return 0;
}

void
map_ip4_reass_reinit (u32 * trashed_reass, u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  int i;

  if (dropped_packets)
    *dropped_packets = mm->ip4_reass_buffered_counter;
  if (trashed_reass)
    *trashed_reass = mm->ip4_reass_allocated;
  if (mm->ip4_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      u16 ri = mm->ip4_reass_fifo_last;
      do
	{
	  map_ip4_reass_t *r = pool_elt_at_index (mm->ip4_reass_pool, ri);
	  for (i = 0; i < MAP_IP4_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
	    if (r->fragments[i] != ~0)
	      map_ip4_drop_pi (r->fragments[i]);

	  ri = r->fifo_next;
	  pool_put (mm->ip4_reass_pool, r);
	}
      while (ri != mm->ip4_reass_fifo_last);
    }

  vec_free (mm->ip4_reass_hash_table);
  vec_resize (mm->ip4_reass_hash_table, 1 << mm->ip4_reass_ht_log2len);
  for (i = 0; i < (1 << mm->ip4_reass_ht_log2len); i++)
    mm->ip4_reass_hash_table[i] = MAP_REASS_INDEX_NONE;
  pool_free (mm->ip4_reass_pool);
  pool_alloc (mm->ip4_reass_pool, mm->ip4_reass_conf_pool_size);

  mm->ip4_reass_allocated = 0;
  mm->ip4_reass_fifo_last = MAP_REASS_INDEX_NONE;
  mm->ip4_reass_buffered_counter = 0;
}

u8
map_get_ht_log2len (f32 ht_ratio, u16 pool_size)
{
  u32 desired_size = (u32) (pool_size * ht_ratio);
  u8 i;
  for (i = 1; i < 31; i++)
    if ((1 << i) >= desired_size)
      return i;
  return 4;
}

int
map_ip4_reass_conf_ht_ratio (f32 ht_ratio, u32 * trashed_reass,
			     u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  if (ht_ratio > MAP_IP4_REASS_CONF_HT_RATIO_MAX)
    return -1;

  map_ip4_reass_lock ();
  mm->ip4_reass_conf_ht_ratio = ht_ratio;
  mm->ip4_reass_ht_log2len =
    map_get_ht_log2len (ht_ratio, mm->ip4_reass_conf_pool_size);
  map_ip4_reass_reinit (trashed_reass, dropped_packets);
  map_ip4_reass_unlock ();
  return 0;
}

int
map_ip4_reass_conf_pool_size (u16 pool_size, u32 * trashed_reass,
			      u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  if (pool_size > MAP_IP4_REASS_CONF_POOL_SIZE_MAX)
    return -1;

  map_ip4_reass_lock ();
  mm->ip4_reass_conf_pool_size = pool_size;
  map_ip4_reass_reinit (trashed_reass, dropped_packets);
  map_ip4_reass_unlock ();
  return 0;
}

int
map_ip4_reass_conf_lifetime (u16 lifetime_ms)
{
  map_main.ip4_reass_conf_lifetime_ms = lifetime_ms;
  return 0;
}

int
map_ip4_reass_conf_buffers (u32 buffers)
{
  map_main.ip4_reass_conf_buffers = buffers;
  return 0;
}

void
map_ip6_reass_reinit (u32 * trashed_reass, u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  if (dropped_packets)
    *dropped_packets = mm->ip6_reass_buffered_counter;
  if (trashed_reass)
    *trashed_reass = mm->ip6_reass_allocated;
  int i;
  if (mm->ip6_reass_fifo_last != MAP_REASS_INDEX_NONE)
    {
      u16 ri = mm->ip6_reass_fifo_last;
      do
	{
	  map_ip6_reass_t *r = pool_elt_at_index (mm->ip6_reass_pool, ri);
	  for (i = 0; i < MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY; i++)
	    if (r->fragments[i].pi != ~0)
	      map_ip6_drop_pi (r->fragments[i].pi);

	  ri = r->fifo_next;
	  pool_put (mm->ip6_reass_pool, r);
	}
      while (ri != mm->ip6_reass_fifo_last);
      mm->ip6_reass_fifo_last = MAP_REASS_INDEX_NONE;
    }

  vec_free (mm->ip6_reass_hash_table);
  vec_resize (mm->ip6_reass_hash_table, 1 << mm->ip6_reass_ht_log2len);
  for (i = 0; i < (1 << mm->ip6_reass_ht_log2len); i++)
    mm->ip6_reass_hash_table[i] = MAP_REASS_INDEX_NONE;
  pool_free (mm->ip6_reass_pool);
  pool_alloc (mm->ip6_reass_pool, mm->ip4_reass_conf_pool_size);

  mm->ip6_reass_allocated = 0;
  mm->ip6_reass_buffered_counter = 0;
}

int
map_ip6_reass_conf_ht_ratio (f32 ht_ratio, u32 * trashed_reass,
			     u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  if (ht_ratio > MAP_IP6_REASS_CONF_HT_RATIO_MAX)
    return -1;

  map_ip6_reass_lock ();
  mm->ip6_reass_conf_ht_ratio = ht_ratio;
  mm->ip6_reass_ht_log2len =
    map_get_ht_log2len (ht_ratio, mm->ip6_reass_conf_pool_size);
  map_ip6_reass_reinit (trashed_reass, dropped_packets);
  map_ip6_reass_unlock ();
  return 0;
}

int
map_ip6_reass_conf_pool_size (u16 pool_size, u32 * trashed_reass,
			      u32 * dropped_packets)
{
  map_main_t *mm = &map_main;
  if (pool_size > MAP_IP6_REASS_CONF_POOL_SIZE_MAX)
    return -1;

  map_ip6_reass_lock ();
  mm->ip6_reass_conf_pool_size = pool_size;
  map_ip6_reass_reinit (trashed_reass, dropped_packets);
  map_ip6_reass_unlock ();
  return 0;
}

int
map_ip6_reass_conf_lifetime (u16 lifetime_ms)
{
  map_main.ip6_reass_conf_lifetime_ms = lifetime_ms;
  return 0;
}

int
map_ip6_reass_conf_buffers (u32 buffers)
{
  map_main.ip6_reass_conf_buffers = buffers;
  return 0;
}

/* *INDENT-OFF* */

/*?
 * Configure MAP reassembly behaviour
 *
 * @cliexpar
 * @cliexstart{map params reassembly}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_ip4_reass_lifetime_command, static) = {
  .path = "map params reassembly",
  .short_help = "map params reassembly [ip4 | ip6] [lifetime <lifetime-ms>] "
                "[pool-size <pool-size>] [buffers <buffers>] "
                "[ht-ratio <ht-ratio>]",
  .function = map_params_reass_command_fn,
};

/*?
 * Set or copy the IP TOS/Traffic Class field
 *
 * @cliexpar
 * @cliexstart{map params traffic-class}
 *
 * This command is used to set the traffic-class field in translated
 * or encapsulated packets. If copy is specifed (the default) then the
 * traffic-class/TOS field is copied from the original packet to the
 * translated / encapsulating header.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_traffic_class_command, static) = {
  .path = "map params traffic-class",
  .short_help = "map params traffic-class {0x0-0xff | copy}",
  .function = map_traffic_class_command_fn,
};

/*?
 * Bypass IP4/IP6 lookup
 *
 * @cliexpar
 * @cliexstart{map params pre-resolve}
 *
 * Bypass a second FIB lookup of the translated or encapsulated
 * packet, and forward the packet directly to the specified
 * next-hop. This optimization trades forwarding flexibility for
 * performance.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_pre_resolve_command, static) = {
  .path = "map params pre-resolve",
  .short_help = " map params pre-resolve {ip4-nh <address>} "
                "| {ip6-nh <address>}",
  .function = map_pre_resolve_command_fn,
};

/*?
 * Enable or disable the MAP-E inbound security check
 *
 * @cliexpar
 * @cliexstart{map params security-check}
 *
 * By default, a decapsulated packet's IPv4 source address will be
 * verified against the outer header's IPv6 source address. Disabling
 * this feature will allow IPv4 source address spoofing.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_security_check_command, static) = {
  .path = "map params security-check",
  .short_help = "map params security-check on|off",
  .function = map_security_check_command_fn,
};

/*?
 * Specifiy the IPv4 source address used for relayed ICMP error messages
 *
 * @cliexpar
 * @cliexstart{map params icmp source-address}
 *
 * This command specifies which IPv4 source address (must be local to
 * the system), that is used for relayed received IPv6 ICMP error
 * messages.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_icmp_relay_source_address_command, static) = {
  .path = "map params icmp source-address",
  .short_help = "map params icmp source-address <ip4-address>",
  .function = map_icmp_relay_source_address_command_fn,
};

/*?
 * Send IPv6 ICMP unreachables
 *
 * @cliexpar
 * @cliexstart{map params icmp6 unreachables}
 *
 * Send IPv6 ICMP unreachable messages back if security check fails or
 * no MAP domain exists.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_icmp_unreachables_command, static) = {
  .path = "map params icmp6 unreachables",
  .short_help = "map params icmp6 unreachables {on|off}",
  .function = map_icmp_unreachables_command_fn,
};

/*?
 * Configure MAP fragmentation behaviour
 *
 * @cliexpar
 * @cliexstart{map params fragment}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_fragment_command, static) = {
  .path = "map params fragment",
  .short_help = "map params fragment inner|outer",
  .function = map_fragment_command_fn,
};

/*?
 * Ignore the IPv4 Don't fragment bit
 *
 * @cliexpar
 * @cliexstart{map params fragment ignore-df}
 *
 * Allows fragmentation of the IPv4 packet even if the DF bit is
 * set. The choice between inner or outer fragmentation of tunnel
 * packets is complicated. The benefit of inner fragmentation is that
 * the ultimate endpoint must reassemble, instead of the tunnel
 * endpoint.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_fragment_df_command, static) = {
  .path = "map params fragment ignore-df",
  .short_help = "map params fragment ignore-df on|off",
  .function = map_fragment_df_command_fn,
};

/*?
 * Specifiy if the inbound security check should be done on fragments
 *
 * @cliexpar
 * @cliexstart{map params security-check fragments}
 *
 * Typically the inbound on-decapsulation security check is only done
 * on the first packet. The packet that contains the L4
 * information. While a security check on every fragment is possible,
 * it has a cost. State must be created on the first fragment.
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_security_check_frag_command, static) = {
  .path = "map params security-check fragments",
  .short_help = "map params security-check fragments on|off",
  .function = map_security_check_frag_command_fn,
};

/*?
 * Add MAP domain
 *
 * @cliexpar
 * @cliexstart{map add domain}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_add_domain_command, static) = {
  .path = "map add domain",
  .short_help = "map add domain ip4-pfx <ip4-pfx> ip6-pfx <ip6-pfx> "
      "ip6-src <ip6-pfx> ea-bits-len <n> psid-offset <n> psid-len <n> "
      "[map-t] [mtu <mtu>]",
  .function = map_add_domain_command_fn,
};

/*?
 * Add MAP rule to a domain
 *
 * @cliexpar
 * @cliexstart{map add rule}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_add_rule_command, static) = {
  .path = "map add rule",
  .short_help = "map add rule index <domain> psid <psid> ip6-dst <ip6-addr>",
  .function = map_add_rule_command_fn,
};

/*?
 * Delete MAP domain
 *
 * @cliexpar
 * @cliexstart{map del domain}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(map_del_command, static) = {
  .path = "map del domain",
  .short_help = "map del domain index <domain>",
  .function = map_del_domain_command_fn,
};

/*?
 * Show MAP domains
 *
 * @cliexpar
 * @cliexstart{show map domain}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(show_map_domain_command, static) = {
  .path = "show map domain",
  .short_help = "show map domain index <n> [counters]",
  .function = show_map_domain_command_fn,
};

/*?
 * Show MAP statistics
 *
 * @cliexpar
 * @cliexstart{show map stats}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(show_map_stats_command, static) = {
  .path = "show map stats",
  .short_help = "show map stats",
  .function = show_map_stats_command_fn,
};

/*?
 * Show MAP fragmentation information
 *
 * @cliexpar
 * @cliexstart{show map fragments}
 * @cliexend
 ?*/
VLIB_CLI_COMMAND(show_map_fragments_command, static) = {
  .path = "show map fragments",
  .short_help = "show map fragments",
  .function = show_map_fragments_command_fn,
};
/* *INDENT-ON* */

/*
 * map_init
 */
clib_error_t *
map_init (vlib_main_t * vm)
{
  map_main_t *mm = &map_main;
  mm->vnet_main = vnet_get_main ();
  mm->vlib_main = vm;

#ifdef MAP_SKIP_IP6_LOOKUP
  fib_protocol_t proto;

  FOR_EACH_FIB_PROTOCOL (proto)
  {
    map_pre_resolve_init (&pre_resolved[proto]);
  }
#endif

  /* traffic class */
  mm->tc = 0;
  mm->tc_copy = true;

  /* Inbound security check */
  mm->sec_check = true;
  mm->sec_check_frag = false;

  /* ICMP6 Type 1, Code 5 for security check failure */
  mm->icmp6_enabled = false;

  /* Inner or outer fragmentation */
  mm->frag_inner = false;
  mm->frag_ignore_df = false;

  vec_validate (mm->domain_counters, MAP_N_DOMAIN_COUNTER - 1);
  mm->domain_counters[MAP_DOMAIN_COUNTER_RX].name = "rx";
  mm->domain_counters[MAP_DOMAIN_COUNTER_TX].name = "tx";

  vlib_validate_simple_counter (&mm->icmp_relayed, 0);
  vlib_zero_simple_counter (&mm->icmp_relayed, 0);

  /* IP4 virtual reassembly */
  mm->ip4_reass_hash_table = 0;
  mm->ip4_reass_pool = 0;
  mm->ip4_reass_lock =
    clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
  mm->ip4_reass_conf_ht_ratio = MAP_IP4_REASS_HT_RATIO_DEFAULT;
  mm->ip4_reass_conf_lifetime_ms = MAP_IP4_REASS_LIFETIME_DEFAULT;
  mm->ip4_reass_conf_pool_size = MAP_IP4_REASS_POOL_SIZE_DEFAULT;
  mm->ip4_reass_conf_buffers = MAP_IP4_REASS_BUFFERS_DEFAULT;
  mm->ip4_reass_ht_log2len =
    map_get_ht_log2len (mm->ip4_reass_conf_ht_ratio,
			mm->ip4_reass_conf_pool_size);
  mm->ip4_reass_fifo_last = MAP_REASS_INDEX_NONE;
  map_ip4_reass_reinit (NULL, NULL);

  /* IP6 virtual reassembly */
  mm->ip6_reass_hash_table = 0;
  mm->ip6_reass_pool = 0;
  mm->ip6_reass_lock =
    clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
  mm->ip6_reass_conf_ht_ratio = MAP_IP6_REASS_HT_RATIO_DEFAULT;
  mm->ip6_reass_conf_lifetime_ms = MAP_IP6_REASS_LIFETIME_DEFAULT;
  mm->ip6_reass_conf_pool_size = MAP_IP6_REASS_POOL_SIZE_DEFAULT;
  mm->ip6_reass_conf_buffers = MAP_IP6_REASS_BUFFERS_DEFAULT;
  mm->ip6_reass_ht_log2len =
    map_get_ht_log2len (mm->ip6_reass_conf_ht_ratio,
			mm->ip6_reass_conf_pool_size);
  mm->ip6_reass_fifo_last = MAP_REASS_INDEX_NONE;
  map_ip6_reass_reinit (NULL, NULL);

#ifdef MAP_SKIP_IP6_LOOKUP
  fib_node_register_type (FIB_NODE_TYPE_MAP_E, &map_vft);
#endif
  map_dpo_module_init ();

  return 0;
}

VLIB_INIT_FUNCTION (map_init);

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