/*
 * 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/udp/udp_encap.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_entry_track.h>
#include <vnet/fib/fib_table.h>
#include <vnet/dpo/drop_dpo.h>

/**
 * Registered DPO types for the IP header encapsulated, v4 or v6.
 */
dpo_type_t udp_encap_dpo_types[FIB_PROTOCOL_MAX];

/**
 * Pool of encaps
 */
udp_encap_t *udp_encap_pool;

/**
 * Stats for each UDP encap object
 */
vlib_combined_counter_main_t udp_encap_counters = {
  /**
   * The counter collection's name.
   */
  .name = "udp-encap",
  /**
   * Name in stat segment directory
   */
  .stat_segment_name = "/net/udp-encap",
};

static void
udp_encap_restack (udp_encap_t * ue)
{
  dpo_stack (udp_encap_dpo_types[ue->ue_ip_proto],
	     fib_proto_to_dpo (ue->ue_ip_proto), &ue->ue_dpo,
	     fib_entry_contribute_ip_forwarding (ue->ue_fib_entry_index));
}

index_t
udp_encap_add_and_lock (fib_protocol_t proto,
			index_t fib_index,
			const ip46_address_t * src_ip,
			const ip46_address_t * dst_ip,
			u16 src_port,
			u16 dst_port, udp_encap_fixup_flags_t flags)
{
  udp_encap_t *ue;
  u8 pfx_len = 0;
  index_t uei;

  pool_get_aligned_zero (udp_encap_pool, ue, CLIB_CACHE_LINE_BYTES);
  uei = ue - udp_encap_pool;

  vlib_validate_combined_counter (&(udp_encap_counters), uei);
  vlib_zero_combined_counter (&(udp_encap_counters), uei);

  fib_node_init (&ue->ue_fib_node, FIB_NODE_TYPE_UDP_ENCAP);
  fib_node_lock (&ue->ue_fib_node);
  ue->ue_fib_index = fib_index;
  ue->ue_flags = flags;
  ue->ue_ip_proto = proto;

  switch (proto)
    {
    case FIB_PROTOCOL_IP4:
      pfx_len = 32;
      ue->ue_hdrs.ip4.ue_ip4.ip_version_and_header_length = 0x45;
      ue->ue_hdrs.ip4.ue_ip4.ttl = 254;
      ue->ue_hdrs.ip4.ue_ip4.protocol = IP_PROTOCOL_UDP;
      ue->ue_hdrs.ip4.ue_ip4.src_address.as_u32 = src_ip->ip4.as_u32;
      ue->ue_hdrs.ip4.ue_ip4.dst_address.as_u32 = dst_ip->ip4.as_u32;
      ue->ue_hdrs.ip4.ue_ip4.checksum =
	ip4_header_checksum (&ue->ue_hdrs.ip4.ue_ip4);
      ue->ue_hdrs.ip4.ue_udp.src_port = clib_host_to_net_u16 (src_port);
      ue->ue_hdrs.ip4.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);

      break;
    case FIB_PROTOCOL_IP6:
      pfx_len = 128;
      ue->ue_hdrs.ip6.ue_ip6.ip_version_traffic_class_and_flow_label =
	clib_host_to_net_u32 (6 << 28);
      ue->ue_hdrs.ip6.ue_ip6.hop_limit = 255;
      ue->ue_hdrs.ip6.ue_ip6.protocol = IP_PROTOCOL_UDP;
      ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[0] = src_ip->ip6.as_u64[0];
      ue->ue_hdrs.ip6.ue_ip6.src_address.as_u64[1] = src_ip->ip6.as_u64[1];
      ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[0] = dst_ip->ip6.as_u64[0];
      ue->ue_hdrs.ip6.ue_ip6.dst_address.as_u64[1] = dst_ip->ip6.as_u64[1];
      ue->ue_hdrs.ip6.ue_udp.src_port = clib_host_to_net_u16 (src_port);
      ue->ue_hdrs.ip6.ue_udp.dst_port = clib_host_to_net_u16 (dst_port);

      break;
    default:
      ASSERT (0);
    }

  /*
   * track the destination address
   */
  fib_prefix_t dst_pfx = {
    .fp_proto = proto,
    .fp_len = pfx_len,
    .fp_addr = *dst_ip,
  };

  ue->ue_fib_entry_index = fib_entry_track (fib_index,
					    &dst_pfx,
					    FIB_NODE_TYPE_UDP_ENCAP,
					    uei, &ue->ue_fib_sibling);
  udp_encap_restack (ue);

  return (uei);
}

void
udp_encap_contribute_forwarding (index_t uei, dpo_proto_t proto,
				 dpo_id_t * dpo)
{
  if (INDEX_INVALID == uei)
    {
      dpo_copy (dpo, drop_dpo_get (proto));
    }
  else
    {
      udp_encap_t *ue;

      ue = udp_encap_get (uei);

      dpo_set (dpo, udp_encap_dpo_types[ue->ue_ip_proto], proto, uei);
    }
}

void
udp_encap_lock (index_t uei)
{
  udp_encap_t *ue;

  ue = udp_encap_get (uei);

  if (NULL != ue)
    {
      fib_node_lock (&ue->ue_fib_node);
    }
}

void
udp_encap_unlock (index_t uei)
{
  udp_encap_t *ue;

  if (INDEX_INVALID == uei)
    {
      return;
    }

  ue = udp_encap_get (uei);

  if (NULL != ue)
    {
      fib_node_unlock (&ue->ue_fib_node);
    }
}

static void
udp_encap_dpo_lock (dpo_id_t * dpo)
{
  udp_encap_t *ue;

  ue = udp_encap_get (dpo->dpoi_index);

  fib_node_lock (&ue->ue_fib_node);
}

static void
udp_encap_dpo_unlock (dpo_id_t * dpo)
{
  udp_encap_t *ue;

  ue = udp_encap_get (dpo->dpoi_index);

  fib_node_unlock (&ue->ue_fib_node);
}

static u8 *
format_udp_encap_i (u8 * s, va_list * args)
{
  index_t uei = va_arg (*args, index_t);
  u32 indent = va_arg (*args, u32);
  u32 details = va_arg (*args, u32);
  vlib_counter_t to;
  udp_encap_t *ue;

  ue = udp_encap_get (uei);

  // FIXME
  s = format (s, "udp-encap:[%d]: ip-fib-index:%d ", uei, ue->ue_fib_index);
  if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
    {
      s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d, dst:%d]",
		  format_ip4_address,
		  &ue->ue_hdrs.ip4.ue_ip4.src_address,
		  format_ip4_address,
		  &ue->ue_hdrs.ip4.ue_ip4.dst_address,
		  clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.src_port),
		  clib_net_to_host_u16 (ue->ue_hdrs.ip4.ue_udp.dst_port));
    }
  else
    {
      s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d dst:%d]",
		  format_ip6_address,
		  &ue->ue_hdrs.ip6.ue_ip6.src_address,
		  format_ip6_address,
		  &ue->ue_hdrs.ip6.ue_ip6.dst_address,
		  clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.src_port),
		  clib_net_to_host_u16 (ue->ue_hdrs.ip6.ue_udp.dst_port));
    }
  vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
  s = format (s, " to:[%Ld:%Ld]]", to.packets, to.bytes);

  if (details)
    {
      s = format (s, " locks:%d", ue->ue_fib_node.fn_locks);
      s = format (s, "\n%UStacked on:", format_white_space, indent + 1);
      s = format (s, "\n%U%U",
		  format_white_space, indent + 2,
		  format_dpo_id, &ue->ue_dpo, indent + 3);
    }
  return (s);
}

void
udp_encap_get_stats (index_t uei, u64 * packets, u64 * bytes)
{
  vlib_counter_t to;

  vlib_get_combined_counter (&(udp_encap_counters), uei, &to);

  *packets = to.packets;
  *bytes = to.bytes;
}

static u8 *
format_udp_encap_dpo (u8 * s, va_list * args)
{
  index_t uei = va_arg (*args, index_t);
  u32 indent = va_arg (*args, u32);

  return (format (s, "%U", format_udp_encap_i, uei, indent, 1));
}

u8 *
format_udp_encap (u8 * s, va_list * args)
{
  index_t uei = va_arg (*args, u32);
  u32 details = va_arg (*args, u32);

  return (format (s, "%U", format_udp_encap_i, uei, 0, details));
}

static udp_encap_t *
udp_encap_from_fib_node (fib_node_t * node)
{
  ASSERT (FIB_NODE_TYPE_UDP_ENCAP == node->fn_type);
  return ((udp_encap_t *) (((char *) node) -
			   STRUCT_OFFSET_OF (udp_encap_t, ue_fib_node)));
}

/**
 * Function definition to backwalk a FIB node
 */
static fib_node_back_walk_rc_t
udp_encap_fib_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
{
  udp_encap_restack (udp_encap_from_fib_node (node));

  return (FIB_NODE_BACK_WALK_CONTINUE);
}

/**
 * Function definition to get a FIB node from its index
 */
static fib_node_t *
udp_encap_fib_node_get (fib_node_index_t index)
{
  udp_encap_t *ue;

  ue = pool_elt_at_index (udp_encap_pool, index);

  return (&ue->ue_fib_node);
}

/**
 * Function definition to inform the FIB node that its last lock has gone.
 */
static void
udp_encap_fib_last_lock_gone (fib_node_t * node)
{
  udp_encap_t *ue;

  ue = udp_encap_from_fib_node (node);

    /**
     * reset the stacked DPO to unlock it
     */
  dpo_reset (&ue->ue_dpo);

  fib_entry_untrack (ue->ue_fib_entry_index, ue->ue_fib_sibling);

  pool_put (udp_encap_pool, ue);
}

const static char *const udp4_encap_ip4_nodes[] = {
  "udp4o4-encap",
  NULL,
};

const static char *const udp4_encap_ip6_nodes[] = {
  "udp6o4-encap",
  NULL,
};

const static char *const udp4_encap_mpls_nodes[] = {
  "udp4-encap",
  NULL,
};

const static char *const udp4_encap_bier_nodes[] = {
  "udp4-encap",
  NULL,
};

const static char *const udp6_encap_ip4_nodes[] = {
  "udp4o6-encap",
  NULL,
};

const static char *const udp6_encap_ip6_nodes[] = {
  "udp6o6-encap",
  NULL,
};

const static char *const udp6_encap_mpls_nodes[] = {
  "udp6-encap",
  NULL,
};

const static char *const udp6_encap_bier_nodes[] = {
  "udp6-encap",
  NULL,
};

const static char *const *const udp4_encap_nodes[DPO_PROTO_NUM] = {
  [DPO_PROTO_IP4] = udp4_encap_ip4_nodes,
  [DPO_PROTO_IP6] = udp4_encap_ip6_nodes,
  [DPO_PROTO_MPLS] = udp4_encap_mpls_nodes,
  [DPO_PROTO_BIER] = udp4_encap_bier_nodes,
};

const static char *const *const udp6_encap_nodes[DPO_PROTO_NUM] = {
  [DPO_PROTO_IP4] = udp6_encap_ip4_nodes,
  [DPO_PROTO_IP6] = udp6_encap_ip6_nodes,
  [DPO_PROTO_MPLS] = udp6_encap_mpls_nodes,
  [DPO_PROTO_BIER] = udp6_encap_bier_nodes,
};

/*
 * Virtual function table registered by UDP encaps
 * for participation in the FIB object graph.
 */
const static fib_node_vft_t udp_encap_fib_vft = {
  .fnv_get = udp_encap_fib_node_get,
  .fnv_last_lock = udp_encap_fib_last_lock_gone,
  .fnv_back_walk = udp_encap_fib_back_walk,
};

const static dpo_vft_t udp_encap_dpo_vft = {
  .dv_lock = udp_encap_dpo_lock,
  .dv_unlock = udp_encap_dpo_unlock,
  .dv_format = format_udp_encap_dpo,
};

clib_error_t *
udp_encap_init (vlib_main_t * vm)
{
  fib_node_register_type (FIB_NODE_TYPE_UDP_ENCAP, &udp_encap_fib_vft);

  udp_encap_dpo_types[FIB_PROTOCOL_IP4] =
    dpo_register_new_type (&udp_encap_dpo_vft, udp4_encap_nodes);
  udp_encap_dpo_types[FIB_PROTOCOL_IP6] =
    dpo_register_new_type (&udp_encap_dpo_vft, udp6_encap_nodes);

  return (NULL);
}

VLIB_INIT_FUNCTION (udp_encap_init);

clib_error_t *
udp_encap_cli (vlib_main_t * vm,
	       unformat_input_t * main_input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  clib_error_t *error = NULL;
  ip46_address_t src_ip, dst_ip;
  u32 table_id, src_port, dst_port;
  udp_encap_fixup_flags_t flags;
  fib_protocol_t fproto;
  index_t uei;
  u8 is_del;

  is_del = 0;
  table_id = 0;
  flags = UDP_ENCAP_FIXUP_NONE;
  fproto = FIB_PROTOCOL_MAX;
  dst_port = 0;
  uei = ~0;

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

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "index %d", &uei))
	;
      else if (unformat (line_input, "add"))
	is_del = 0;
      else if (unformat (line_input, "del"))
	is_del = 1;
      else if (unformat (line_input, "%U %U",
			 unformat_ip4_address,
			 &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
	fproto = FIB_PROTOCOL_IP4;
      else if (unformat (line_input, "%U %U",
			 unformat_ip6_address,
			 &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
	fproto = FIB_PROTOCOL_IP6;
      else if (unformat (line_input, "%d %d", &src_port, &dst_port))
	;
      else if (unformat (line_input, "%d", &dst_port))
	;
      else if (unformat (line_input, "table-id %d", &table_id))
	;
      else if (unformat (line_input, "src-port-is-entropy"))
	flags |= UDP_ENCAP_FIXUP_UDP_SRC_PORT_ENTROPY;
      else
	{
	  error = unformat_parse_error (line_input);
	  goto done;
	}
    }

  if (!is_del && fproto != FIB_PROTOCOL_MAX)
    {
      u32 fib_index;
      index_t uei;

      fib_index = fib_table_find (fproto, table_id);

      if (~0 == fib_index)
	{
	  error = clib_error_return (0, "Nonexistent table id %d", table_id);
	  goto done;
	}

      uei = udp_encap_add_and_lock (fproto, fib_index,
				    &src_ip, &dst_ip,
				    src_port, dst_port, flags);

      vlib_cli_output (vm, "udp-encap: %d\n", uei);
    }
  else if (is_del)
    {
      if (INDEX_INVALID == uei)
	{
	  error = clib_error_return (0, "specify udp-encap object index");
	  goto done;
	}
      udp_encap_unlock (uei);
    }
  else
    {
      error = clib_error_return (0, "specify some IP addresses");
    }

done:
  unformat_free (line_input);
  return error;
}

void
udp_encap_walk (udp_encap_walk_cb_t cb, void *ctx)
{
  index_t uei;

  /* *INDENT-OFF* */
  pool_foreach_index (uei, udp_encap_pool)
   {
    if (WALK_STOP == cb(uei, ctx))
      break;
  }
  /* *INDENT-ON* */
}

clib_error_t *
udp_encap_show (vlib_main_t * vm,
		unformat_input_t * input, vlib_cli_command_t * cmd)
{
  index_t uei;

  uei = INDEX_INVALID;

  /* Get a line of input. */
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%d", &uei))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (INDEX_INVALID == uei)
    {
      /* *INDENT-OFF* */
      pool_foreach_index (uei, udp_encap_pool)
       {
        vlib_cli_output(vm, "%U", format_udp_encap, uei, 0);
      }
      /* *INDENT-ON* */
    }
  else
    {
      vlib_cli_output (vm, "%U", format_udp_encap, uei, 1);
    }

  return NULL;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (udp_encap_add_command, static) = {
  .path = "udp encap",
  .short_help = "udp encap [add|del] <id ID> <src-ip> <dst-ip> [<src-port>] <dst-port>  [src-port-is-entropy] [table-id <table>]",
  .function = udp_encap_cli,
  .is_mp_safe = 1,
};
VLIB_CLI_COMMAND (udp_encap_show_command, static) = {
  .path = "show udp encap",
  .short_help = "show udp encap [ID]",
  .function = udp_encap_show,
  .is_mp_safe = 1,
};
/* *INDENT-ON* */

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