/*
 * 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;

  /* 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 {
      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,
                           TUNNEL_ENCAP_DECAP_FLAG_NONE,
                           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>]",
    .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 {
    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* */
