/*
 * ipsec_itf.c: IPSec dedicated interface type
 *
 * Copyright (c) 2020 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/ip/ip.h>
#include <vnet/ipsec/ipsec_itf.h>
#include <vnet/ipsec/ipsec_tun.h>
#include <vnet/ipsec/ipsec.h>
#include <vnet/adj/adj_midchain.h>

/* bitmap of Allocated IPSEC_ITF instances */
static uword *ipsec_itf_instances;

/* pool of interfaces */
static ipsec_itf_t *ipsec_itf_pool;

static u32 *ipsec_itf_index_by_sw_if_index;

static ipsec_itf_t *
ipsec_itf_find_by_sw_if_index (u32 sw_if_index)
{
  if (vec_len (ipsec_itf_index_by_sw_if_index) <= sw_if_index)
    return NULL;
  u32 ti = ipsec_itf_index_by_sw_if_index[sw_if_index];
  if (ti == ~0)
    return NULL;
  return pool_elt_at_index (ipsec_itf_pool, ti);
}

static u8 *
format_ipsec_itf_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "ipsec%d", dev_instance);
}

void
ipsec_itf_adj_unstack (adj_index_t ai)
{
  adj_midchain_delegate_unstack (ai);
}

void
ipsec_itf_adj_stack (adj_index_t ai, u32 sai)
{
  const vnet_hw_interface_t *hw;

  hw = vnet_get_sup_hw_interface (vnet_get_main (), adj_get_sw_if_index (ai));

  if (hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)
    {
      const ipsec_sa_t *sa;

      sa = ipsec_sa_get (sai);

      /* *INDENT-OFF* */
      const fib_prefix_t dst = {
        .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ? 128 : 32),
        .fp_proto = (ipsec_sa_is_set_IS_TUNNEL_V6(sa)?
                     FIB_PROTOCOL_IP6 :
                     FIB_PROTOCOL_IP4),
        .fp_addr = sa->tunnel_dst_addr,
      };
      /* *INDENT-ON* */

      adj_midchain_delegate_stack (ai, 0, &dst);
    }
  else
    adj_midchain_delegate_unstack (ai);
}

static adj_walk_rc_t
ipsec_itf_adj_stack_cb (adj_index_t ai, void *arg)
{
  ipsec_tun_protect_t *itp = arg;

  ipsec_itf_adj_stack (ai, itp->itp_out_sa);

  return (ADJ_WALK_RC_CONTINUE);
}

static void
ipsec_itf_restack (index_t itpi, const ipsec_itf_t * itf)
{
  ipsec_tun_protect_t *itp;
  fib_protocol_t proto;

  itp = ipsec_tun_protect_get (itpi);

  /*
   * walk all the adjacencies on the interface and restack them
   */
  FOR_EACH_FIB_IP_PROTOCOL (proto)
  {
    adj_nbr_walk (itf->ii_sw_if_index, proto, ipsec_itf_adj_stack_cb, itp);
  }
}

static walk_rc_t
ipsec_tun_protect_walk_state_change (index_t itpi, void *arg)
{
  const ipsec_itf_t *itf = arg;

  ipsec_itf_restack (itpi, itf);

  return (WALK_CONTINUE);
}

static clib_error_t *
ipsec_itf_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  vnet_hw_interface_t *hi;
  ipsec_itf_t *itf;
  u32 hw_flags;

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP ?
	      VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);

  itf = ipsec_itf_find_by_sw_if_index (hi->sw_if_index);

  if (itf)
    ipsec_tun_protect_walk_itf (itf->ii_sw_if_index,
				ipsec_tun_protect_walk_state_change, itf);

  return (NULL);
}

static int
ipsec_itf_tunnel_desc (u32 sw_if_index,
		       ip46_address_t * src, ip46_address_t * dst, u8 * is_l2)
{
  ip46_address_reset (src);
  ip46_address_reset (dst);
  *is_l2 = 0;

  return (0);
}

static u8 *
ipsec_itf_build_rewrite (void)
{
  /*
   * passing the adj code a NULL rewrite means 'i don't have one cos
   * t'other end is unresolved'. That's not the case here. For the ipsec
   * tunnel there are just no bytes of encap to apply in the adj.
   * So return a zero length rewrite. Encap will be added by a tunnel mode SA.
   */
  u8 *rewrite = NULL;

  vec_validate (rewrite, 0);
  vec_reset_length (rewrite);

  return (rewrite);
}

static u8 *
ipsec_itf_build_rewrite_i (vnet_main_t * vnm,
			   u32 sw_if_index,
			   vnet_link_t link_type, const void *dst_address)
{
  return (ipsec_itf_build_rewrite ());
}

void
ipsec_itf_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
{
  adj_nbr_midchain_update_rewrite
    (ai, NULL, NULL, ADJ_FLAG_MIDCHAIN_IP_STACK, ipsec_itf_build_rewrite ());
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (ipsec_itf_device_class) = {
  .name = "IPSEC Tunnel",
  .format_device_name = format_ipsec_itf_name,
  .admin_up_down_function = ipsec_itf_admin_up_down,
  .ip_tun_desc = ipsec_itf_tunnel_desc,
};

VNET_HW_INTERFACE_CLASS(ipsec_hw_interface_class) = {
  .name = "IPSec",
  .build_rewrite = ipsec_itf_build_rewrite_i,
  .update_adjacency = ipsec_itf_update_adj,
  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};
/* *INDENT-ON* */

/*
 * Maintain a bitmap of allocated ipsec_itf instance numbers.
 */
#define IPSEC_ITF_MAX_INSTANCE		(16 * 1024)

static u32
ipsec_itf_instance_alloc (u32 want)
{
  /*
   * Check for dynamically allocated instance number.
   */
  if (~0 == want)
    {
      u32 bit;

      bit = clib_bitmap_first_clear (ipsec_itf_instances);
      if (bit >= IPSEC_ITF_MAX_INSTANCE)
	{
	  return ~0;
	}
      ipsec_itf_instances = clib_bitmap_set (ipsec_itf_instances, bit, 1);
      return bit;
    }

  /*
   * In range?
   */
  if (want >= IPSEC_ITF_MAX_INSTANCE)
    {
      return ~0;
    }

  /*
   * Already in use?
   */
  if (clib_bitmap_get (ipsec_itf_instances, want))
    {
      return ~0;
    }

  /*
   * Grant allocation request.
   */
  ipsec_itf_instances = clib_bitmap_set (ipsec_itf_instances, want, 1);

  return want;
}

static int
ipsec_itf_instance_free (u32 instance)
{
  if (instance >= IPSEC_ITF_MAX_INSTANCE)
    {
      return -1;
    }

  if (clib_bitmap_get (ipsec_itf_instances, instance) == 0)
    {
      return -1;
    }

  ipsec_itf_instances = clib_bitmap_set (ipsec_itf_instances, instance, 0);
  return 0;
}

int
ipsec_itf_create (u32 user_instance, tunnel_mode_t mode, u32 * sw_if_indexp)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 instance, hw_if_index;
  vnet_hw_interface_t *hi;
  ipsec_itf_t *ipsec_itf;

  ASSERT (sw_if_indexp);

  *sw_if_indexp = (u32) ~ 0;

  if (mode != TUNNEL_MODE_P2P)
    return VNET_API_ERROR_UNSUPPORTED;

  /*
   * Allocate a ipsec_itf instance.  Either select on dynamically
   * or try to use the desired user_instance number.
   */
  instance = ipsec_itf_instance_alloc (user_instance);
  if (instance == ~0)
    return VNET_API_ERROR_INVALID_REGISTRATION;

  pool_get (ipsec_itf_pool, ipsec_itf);

  /* tunnel index (or instance) */
  u32 t_idx = ipsec_itf - ipsec_itf_pool;

  ipsec_itf->ii_mode = mode;
  ipsec_itf->ii_user_instance = instance;
  if (~0 == ipsec_itf->ii_user_instance)
    ipsec_itf->ii_user_instance = t_idx;

  hw_if_index = vnet_register_interface (vnm,
					 ipsec_itf_device_class.index,
					 t_idx,
					 ipsec_hw_interface_class.index,
					 t_idx);

  hi = vnet_get_hw_interface (vnm, hw_if_index);

  vec_validate_init_empty (ipsec_itf_index_by_sw_if_index, hi->sw_if_index,
			   INDEX_INVALID);
  ipsec_itf_index_by_sw_if_index[hi->sw_if_index] = t_idx;

  ipsec_itf->ii_sw_if_index = *sw_if_indexp = hi->sw_if_index;

  return 0;
}

int
ipsec_itf_delete (u32 sw_if_index)
{
  vnet_main_t *vnm = vnet_get_main ();

  if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  if (hw == 0 || hw->dev_class_index != ipsec_itf_device_class.index)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  ipsec_itf_t *ipsec_itf;
  ipsec_itf = ipsec_itf_find_by_sw_if_index (sw_if_index);
  if (NULL == ipsec_itf)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  if (ipsec_itf_instance_free (hw->dev_instance) < 0)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  vnet_delete_hw_interface (vnm, hw->hw_if_index);
  pool_put (ipsec_itf_pool, ipsec_itf);

  return 0;
}

static clib_error_t *
ipsec_itf_create_cli (vlib_main_t * vm,
		      unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 instance, sw_if_index;
  clib_error_t *error;
  mac_address_t mac;
  int rv;

  error = NULL;
  instance = sw_if_index = ~0;
  mac_address_set_zero (&mac);

  if (unformat_user (input, unformat_line_input, line_input))
    {
      while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
	{
	  if (unformat (line_input, "instance %d", &instance))
	    ;
	  else
	    {
	      error = clib_error_return (0, "unknown input: %U",
					 format_unformat_error, line_input);
	      break;
	    }
	}

      unformat_free (line_input);

      if (error)
	return error;
    }

  rv = ipsec_itf_create (instance, TUNNEL_MODE_P2P, &sw_if_index);

  if (rv)
    return clib_error_return (0, "iPSec interface create failed");

  vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main (),
		   sw_if_index);
  return 0;
}

/*?
 * Create a IPSec interface.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{ipsec itf create [instance <instance>]}
 * Example of how to create a ipsec interface:
 * @cliexcmd{ipsec itf create}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (ipsec_itf_create_command, static) = {
  .path = "ipsec itf create",
  .short_help = "ipsec itf create [instance <instance>]",
  .function = ipsec_itf_create_cli,
};
/* *INDENT-ON* */

static clib_error_t *
ipsec_itf_delete_cli (vlib_main_t * vm,
		      unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm;
  u32 sw_if_index;
  int rv;

  vnm = vnet_get_main ();
  sw_if_index = ~0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
	;
      else
	break;
    }

  if (~0 != sw_if_index)
    {
      rv = ipsec_itf_delete (sw_if_index);

      if (rv)
	return clib_error_return (0, "ipsec interface delete failed");
    }
  else
    return clib_error_return (0, "no such interface: %U",
			      format_unformat_error, input);

  return 0;
}

/*?
 * Delete a IPSEC_ITF interface.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{ipsec itf delete <interface>}
 * Example of how to create a ipsec_itf interface:
 * @cliexcmd{ipsec itf delete ipsec0}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (ipsec_itf_delete_command, static) = {
  .path = "ipsec itf delete",
  .short_help = "ipsec itf delete <interface>",
  .function = ipsec_itf_delete_cli,
};
/* *INDENT-ON* */


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