/*
 * Copyright (c) 2018 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 "ipip.h"
#include <vppinfra/error.h>
#include <vnet/vnet.h>
#include <vnet/fib/fib_table.h>

static clib_error_t *
create_ipip_tunnel_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip46_address_t src = ip46_address_initializer, dst =
    ip46_address_initializer;
  u32 instance = ~0;
  u32 fib_index = 0;
  u32 table_id = 0;
  int rv;
  u32 num_m_args = 0;
  u32 sw_if_index;
  clib_error_t *error = NULL;
  bool ip4_set = false, ip6_set = false;
  tunnel_mode_t mode = TUNNEL_MODE_P2P;
  tunnel_encap_decap_flags_t flags = TUNNEL_ENCAP_DECAP_FLAG_NONE;

  /* 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, "instance %d", &instance))
	;
      else
	if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
	{
	  num_m_args++;
	  ip4_set = true;
	}
      else
	if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
	{
	  num_m_args++;
	  ip4_set = true;
	}
      else
	if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
	{
	  num_m_args++;
	  ip6_set = true;
	}
      else
	if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
	{
	  num_m_args++;
	  ip6_set = true;
	}
      else if (unformat (line_input, "%U", unformat_tunnel_mode, &mode))
	{
	  num_m_args++;
	}
      else if (unformat (line_input, "outer-table-id %d", &table_id))
	;
      else
	if (unformat
	    (line_input, "flags %U", unformat_tunnel_encap_decap_flags,
	     &flags))
	;
      else
	{
	  error =
	    clib_error_return (0, "unknown input `%U'", format_unformat_error,
			       line_input);
	  goto done;
	}
    }

  if (num_m_args < 2)
    {
      error = clib_error_return (0, "mandatory argument(s) missing");
      goto done;
    }
  if (ip4_set && ip6_set)
    {
      error =
	clib_error_return (0,
			   "source and destination must be of same address family");
      goto done;
    }

  fib_index = fib_table_find (fib_ip_proto (ip6_set), table_id);

  if (~0 == fib_index)
    {
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else
    {
      rv = ipip_add_tunnel (ip6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4,
			    instance,
			    &src,
			    &dst,
			    fib_index,
			    flags, IP_DSCP_CS0, mode, &sw_if_index);
    }

  switch (rv)
    {
    case 0:
      vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
		       vnet_get_main (), sw_if_index);
      break;
    case VNET_API_ERROR_IF_ALREADY_EXISTS:
      error = clib_error_return (0, "IPIP tunnel already exists...");
      goto done;
    case VNET_API_ERROR_NO_SUCH_FIB:
      error =
	clib_error_return (0, "outer fib ID %d doesn't exist\n", fib_index);
      goto done;
    case VNET_API_ERROR_NO_SUCH_ENTRY:
      error = clib_error_return (0, "IPIP tunnel doesn't exist");
      goto done;
    case VNET_API_ERROR_INSTANCE_IN_USE:
      error = clib_error_return (0, "Instance is in use");
      goto done;
    case VNET_API_ERROR_INVALID_DST_ADDRESS:
      error =
	clib_error_return (0,
			   "destination IP address when mode is multi-point");
      goto done;
    default:
      error =
	clib_error_return (0, "vnet_ipip_add_del_tunnel returned %d", rv);
      goto done;
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
delete_ipip_tunnel_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  int rv;
  u32 num_m_args = 0;
  u32 sw_if_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, "sw_if_index %d", &sw_if_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;
    }

  rv = ipip_del_tunnel (sw_if_index);
  printf ("RV %d\n", rv);

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND(create_ipip_tunnel_command, static) = {
    .path = "create ipip tunnel",
    .short_help = "create ipip tunnel src <addr> dst <addr> [instance <n>] "
                  "[outer-table-id <ID>] [p2mp]",
    .function = create_ipip_tunnel_command_fn,
};
VLIB_CLI_COMMAND(delete_ipip_tunnel_command, static) = {
    .path = "delete ipip tunnel",
    .short_help = "delete ipip tunnel sw_if_index <sw_if_index>",
    .function = delete_ipip_tunnel_command_fn,
};
/* *INDENT-ON* */

static u8 *
format_ipip_tunnel (u8 * s, va_list * args)
{
  ipip_tunnel_t *t = va_arg (*args, ipip_tunnel_t *);

  ip46_type_t type =
    (t->transport == IPIP_TRANSPORT_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;
  u32 table_id;

  table_id = fib_table_get_table_id (t->fib_index,
				     fib_proto_from_ip46 (type));
  switch (t->mode)
    {
    case IPIP_MODE_6RD:
      s = format (s, "[%d] 6rd src %U ip6-pfx %U/%d ",
		  t->dev_instance,
		  format_ip46_address, &t->tunnel_src, type,
		  format_ip6_address, &t->sixrd.ip6_prefix,
		  t->sixrd.ip6_prefix_len);
      break;
    case IPIP_MODE_P2P:
      s = format (s, "[%d] instance %d src %U dst %U ",
		  t->dev_instance, t->user_instance,
		  format_ip46_address, &t->tunnel_src, type,
		  format_ip46_address, &t->tunnel_dst, type);
      break;
    case IPIP_MODE_P2MP:
      s = format (s, "[%d] instance %d p2mp src %U ",
		  t->dev_instance, t->user_instance,
		  format_ip46_address, &t->tunnel_src, type);
      break;
    }

  s = format (s, "table-ID %d sw-if-idx %d flags [%U] dscp %U",
	      table_id, t->sw_if_index,
	      format_tunnel_encap_decap_flags, t->flags,
	      format_ip_dscp, t->dscp);

  return s;
}

static clib_error_t *
show_ipip_tunnel_command_fn (vlib_main_t * vm,
			     unformat_input_t * input,
			     vlib_cli_command_t * cmd)
{
  ipip_main_t *gm = &ipip_main;
  ipip_tunnel_t *t;
  u32 ti = ~0;

  if (pool_elts (gm->tunnels) == 0)
    vlib_cli_output (vm, "No IPIP tunnels configured...");

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%d", &ti))
	;
      else
	break;
    }

  if (ti == ~0)
    {
    /* *INDENT-OFF* */
    pool_foreach(t, gm->tunnels,
                 ({vlib_cli_output(vm, "%U", format_ipip_tunnel, t); }));
    /* *INDENT-ON* */
    }
  else
    {
      if (pool_is_free_index (gm->tunnels, ti))
	return clib_error_return (0, "unknown index:%d", ti);
      t = pool_elt_at_index (gm->tunnels, ti);
      if (t)
	vlib_cli_output (vm, "%U", format_ipip_tunnel, t);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND(show_ipip_tunnel_command, static) = {
    .path = "show ipip tunnel",
    .function = show_ipip_tunnel_command_fn,
};
/* *INDENT-ON* */

static u8 *
format_ipip_tunnel_key (u8 * s, va_list * args)
{
  ipip_tunnel_key_t *t = va_arg (*args, ipip_tunnel_key_t *);

  s = format (s, "src:%U dst:%U fib:%d transport:%d mode:%d",
	      format_ip46_address, &t->src, IP46_TYPE_ANY,
	      format_ip46_address, &t->dst, IP46_TYPE_ANY,
	      t->fib_index, t->transport, t->mode);

  return (s);
}

static clib_error_t *
ipip_tunnel_hash_show (vlib_main_t * vm,
		       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ipip_main_t *im = &ipip_main;
  ipip_tunnel_key_t *key;
  u32 index;

  /* *INDENT-OFF* */
  hash_foreach(key, index, im->tunnel_by_key,
  ({
      vlib_cli_output (vm, " %U -> %d", format_ipip_tunnel_key, key, index);
  }));
  /* *INDENT-ON* */

  return NULL;
}

/**
 * show IPSEC tunnel protection hash tables
 */
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (ipip_tunnel_hash_show_node, static) =
{
  .path = "show ipip tunnel-hash",
  .function = ipip_tunnel_hash_show,
  .short_help =  "show ipip tunnel-hash",
};
/* *INDENT-ON* */

static clib_error_t *
create_sixrd_tunnel_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;
  ip4_address_t ip4_src;
  u32 ip6_prefix_len = 0, ip4_prefix_len = 0, sixrd_tunnel_index;
  u32 num_m_args = 0;
  /* Optional arguments */
  u32 ip4_table_id = 0, ip4_fib_index;
  u32 ip6_table_id = 0, ip6_fib_index;
  clib_error_t *error = 0;
  bool security_check = false;
  int rv;

  /* 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, "security-check"))
	security_check = true;
      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, "ip4-pfx %U/%d", unformat_ip4_address,
			 &ip4_prefix, &ip4_prefix_len))
	num_m_args++;
      else
	if (unformat
	    (line_input, "ip4-src %U", unformat_ip4_address, &ip4_src))
	num_m_args++;
      else if (unformat (line_input, "ip4-table-id %d", &ip4_table_id))
	;
      else if (unformat (line_input, "ip6-table-id %d", &ip6_table_id))
	;
      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;
    }
  ip4_fib_index = fib_table_find (FIB_PROTOCOL_IP4, ip4_table_id);
  ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, ip6_table_id);

  if (~0 == ip4_fib_index)
    {
      error = clib_error_return (0, "No such IP4 table %d", ip4_table_id);
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else if (~0 == ip6_fib_index)
    {
      error = clib_error_return (0, "No such IP6 table %d", ip6_table_id);
      rv = VNET_API_ERROR_NO_SUCH_FIB;
    }
  else
    {
      rv = sixrd_add_tunnel (&ip6_prefix, ip6_prefix_len, &ip4_prefix,
			     ip4_prefix_len, &ip4_src, security_check,
			     ip4_fib_index, ip6_fib_index,
			     &sixrd_tunnel_index);

      if (rv)
	error = clib_error_return (0, "adding tunnel failed %d", rv);
    }

done:
  unformat_free (line_input);

  return error;
}

static clib_error_t *
delete_sixrd_tunnel_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;
  /* Optional arguments */
  clib_error_t *error = 0;
  u32 sw_if_index = ~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, "sw_if_index %d", &sw_if_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;
    }
  int rv = sixrd_del_tunnel (sw_if_index);
  printf ("RV %d\n", rv);

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND(create_sixrd_tunnel_command, static) = {
    .path = "create 6rd tunnel",
    .short_help = "create 6rd tunnel ip6-pfx <ip6-pfx> ip4-pfx <ip4-pfx> "
                  "ip4-src <ip4-addr> ip4-table-id <ID> ip6-table-id <ID> "
                  "[security-check]",
    .function = create_sixrd_tunnel_command_fn,
};
VLIB_CLI_COMMAND(delete_sixrd_tunnel_command, static) = {
    .path = "delete 6rd tunnel",
    .short_help = "delete 6rd tunnel sw_if_index <sw_if_index>",
    .function = delete_sixrd_tunnel_command_fn,
};
/* *INDENT-ON* */

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