/*
 * ipsec_if.c : IPSec interface 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/vnet.h>
#include <vnet/api_errno.h>
#include <vnet/ip/ip.h>
#include <vnet/fib/fib.h>
#include <vnet/udp/udp.h>
#include <vnet/adj/adj_midchain.h>

#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/esp.h>

void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);

static u8 *
format_ipsec_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  ipsec_main_t *im = &ipsec_main;
  ipsec_tunnel_if_t *t = im->tunnel_interfaces + dev_instance;

  return format (s, "ipsec%d", t->show_instance);
}

/* Statistics (not really errors) */
#define foreach_ipsec_if_tx_error    \
_(TX, "good packets transmitted")

static void
ipsec_if_tunnel_stack (adj_index_t ai)
{
  ipsec_main_t *ipm = &ipsec_main;
  ipsec_tunnel_if_t *it;
  ip_adjacency_t *adj;
  u32 sw_if_index;

  adj = adj_get (ai);
  sw_if_index = adj->rewrite_header.sw_if_index;

  if ((vec_len (ipm->ipsec_if_by_sw_if_index) <= sw_if_index) ||
      (~0 == ipm->ipsec_if_by_sw_if_index[sw_if_index]))
    return;

  it = pool_elt_at_index (ipm->tunnel_interfaces,
			  ipm->ipsec_if_by_sw_if_index[sw_if_index]);

  if (!vnet_hw_interface_is_link_up (vnet_get_main (), it->hw_if_index))
    {
      adj_midchain_delegate_unstack (ai);
    }
  else
    {
      ipsec_sa_t *sa;

      sa = ipsec_sa_get (it->output_sa_index);

      /* *INDENT-OFF* */
      fib_prefix_t pfx = {
	.fp_addr = sa->tunnel_dst_addr,
	.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),
      };
      /* *INDENT-ON* */

      adj_midchain_delegate_stack (ai, sa->tx_fib_index, &pfx);
    }
}

/**
 * @brief Call back when restacking all adjacencies on a IPSec interface
 */
static adj_walk_rc_t
ipsec_if_adj_walk_cb (adj_index_t ai, void *ctx)
{
  ipsec_if_tunnel_stack (ai);

  return (ADJ_WALK_RC_CONTINUE);
}

static void
ipsec_if_tunnel_restack (ipsec_tunnel_if_t * it)
{
  fib_protocol_t proto;

  /*
   * walk all the adjacencies on the IPSec interface and restack them
   */
  FOR_EACH_FIB_IP_PROTOCOL (proto)
  {
    adj_nbr_walk (it->sw_if_index, proto, ipsec_if_adj_walk_cb, NULL);
  }
}

static clib_error_t *
ipsec_admin_up_down_function (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  ipsec_main_t *im = &ipsec_main;
  clib_error_t *err = 0;
  ipsec_tunnel_if_t *t;
  vnet_hw_interface_t *hi;
  ipsec_sa_t *sa;

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  t = pool_elt_at_index (im->tunnel_interfaces, hi->hw_instance);
  t->flags = flags;

  if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
    {
      sa = pool_elt_at_index (im->sad, t->input_sa_index);

      err = ipsec_check_support_cb (im, sa);
      if (err)
	return err;

      err = ipsec_add_del_sa_sess_cb (im, t->input_sa_index, 1);
      if (err)
	return err;

      sa = pool_elt_at_index (im->sad, t->output_sa_index);

      err = ipsec_check_support_cb (im, sa);
      if (err)
	return err;

      err = ipsec_add_del_sa_sess_cb (im, t->output_sa_index, 1);
      if (err)
	return err;

      vnet_hw_interface_set_flags (vnm, hw_if_index,
				   VNET_HW_INTERFACE_FLAG_LINK_UP);
    }
  else
    {
      vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ );
      sa = pool_elt_at_index (im->sad, t->input_sa_index);
      err = ipsec_add_del_sa_sess_cb (im, t->input_sa_index, 0);
      if (err)
	return err;
      sa = pool_elt_at_index (im->sad, t->output_sa_index);
      err = ipsec_add_del_sa_sess_cb (im, t->output_sa_index, 0);
      if (err)
	return err;
    }

  ipsec_if_tunnel_restack (t);

  return (NULL);
}

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

static void
ipsec_if_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_if_build_rewrite (vnm, sw_if_index, adj_get_link_type (ai), NULL));

  ipsec_if_tunnel_stack (ai);
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (ipsec_device_class) =
{
  .name = "IPSec",
  .format_device_name = format_ipsec_name,
  .admin_up_down_function = ipsec_admin_up_down_function,
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VNET_HW_INTERFACE_CLASS (ipsec_hw_class) =
{
  .name = "IPSec",
  .build_rewrite = default_build_rewrite,
  .update_adjacency = ipsec_if_update_adj,
  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};
/* *INDENT-ON* */

static int
ipsec_add_del_tunnel_if_rpc_callback (ipsec_add_del_tunnel_args_t * a)
{
  vnet_main_t *vnm = vnet_get_main ();
  ASSERT (vlib_get_thread_index () == 0);

  return ipsec_add_del_tunnel_if_internal (vnm, a, NULL);
}

int
ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args)
{
  vl_api_rpc_call_main_thread (ipsec_add_del_tunnel_if_rpc_callback,
			       (u8 *) args, sizeof (*args));
  return 0;
}

static u32
ipsec_tun_mk_input_sa_id (u32 ti)
{
  return (0x80000000 | ti);
}

static u32
ipsec_tun_mk_output_sa_id (u32 ti)
{
  return (0xc0000000 | ti);
}

static void
ipsec_tunnel_feature_set (ipsec_main_t * im, ipsec_tunnel_if_t * t, u8 enable)
{
  u8 arc;
  u32 esp4_feature_index, esp6_feature_index;
  ipsec_sa_t *sa;

  sa = ipsec_sa_get (t->output_sa_index);
  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_NONE &&
      sa->integ_alg == IPSEC_INTEG_ALG_NONE)
    {
      esp4_feature_index = im->esp4_no_crypto_tun_feature_index;
      esp6_feature_index = im->esp6_no_crypto_tun_feature_index;
    }
  else
    {
      esp4_feature_index = im->esp4_encrypt_tun_feature_index;
      esp6_feature_index = im->esp6_encrypt_tun_feature_index;
    }

  arc = vnet_get_feature_arc_index ("ip4-output");

  vnet_feature_enable_disable_with_index (arc, esp4_feature_index,
					  t->sw_if_index, enable,
					  &t->output_sa_index,
					  sizeof (t->output_sa_index));

  arc = vnet_get_feature_arc_index ("ip6-output");

  vnet_feature_enable_disable_with_index (arc, esp6_feature_index,
					  t->sw_if_index, enable,
					  &t->output_sa_index,
					  sizeof (t->output_sa_index));
}

int
ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
				  ipsec_add_del_tunnel_args_t * args,
				  u32 * sw_if_index)
{
  ipsec_tunnel_if_t *t;
  ipsec_main_t *im = &ipsec_main;
  vnet_hw_interface_t *hi = NULL;
  u32 hw_if_index = ~0;
  uword *p;
  u32 dev_instance;
  ipsec_key_t crypto_key, integ_key;
  ipsec_sa_flags_t flags;
  int rv;
  int is_ip6 = args->is_ip6;
  ipsec4_tunnel_key_t key4;
  ipsec6_tunnel_key_t key6;

  if (!is_ip6)
    {
      key4.remote_ip.as_u32 = args->remote_ip.ip4.as_u32;
      key4.spi = clib_host_to_net_u32 (args->remote_spi);
      p = hash_get (im->ipsec4_if_pool_index_by_key, key4.as_u64);
    }
  else
    {
      key6.remote_ip = args->remote_ip.ip6;
      key6.spi = clib_host_to_net_u32 (args->remote_spi);
      p = hash_get_mem (im->ipsec6_if_pool_index_by_key, &key6);
    }

  if (args->is_add)
    {
      /* check if same src/dst pair exists */
      if (p)
	return VNET_API_ERROR_INVALID_VALUE;

      pool_get_aligned_zero (im->tunnel_interfaces, t, CLIB_CACHE_LINE_BYTES);

      dev_instance = t - im->tunnel_interfaces;
      if (args->renumber)
	t->show_instance = args->show_instance;
      else
	t->show_instance = dev_instance;

      if (hash_get (im->ipsec_if_real_dev_by_show_dev, t->show_instance))
	{
	  pool_put (im->tunnel_interfaces, t);
	  return VNET_API_ERROR_INSTANCE_IN_USE;
	}

      hash_set (im->ipsec_if_real_dev_by_show_dev, t->show_instance,
		dev_instance);

      flags = IPSEC_SA_FLAG_IS_TUNNEL;
      if (args->is_ip6)
	flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
      if (args->udp_encap)
	flags |= IPSEC_SA_FLAG_UDP_ENCAP;
      if (args->esn)
	flags |= IPSEC_SA_FLAG_USE_ESN;
      if (args->anti_replay)
	flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;

      ipsec_mk_key (&crypto_key,
		    args->remote_crypto_key, args->remote_crypto_key_len);
      ipsec_mk_key (&integ_key,
		    args->remote_integ_key, args->remote_integ_key_len);

      rv = ipsec_sa_add_and_lock (ipsec_tun_mk_input_sa_id (dev_instance),
				  args->remote_spi,
				  IPSEC_PROTOCOL_ESP,
				  args->crypto_alg,
				  &crypto_key,
				  args->integ_alg,
				  &integ_key,
				  (flags | IPSEC_SA_FLAG_IS_INBOUND),
				  args->tx_table_id,
				  args->salt,
				  &args->remote_ip,
				  &args->local_ip, &t->input_sa_index);

      if (rv)
	return rv;

      ipsec_mk_key (&crypto_key,
		    args->local_crypto_key, args->local_crypto_key_len);
      ipsec_mk_key (&integ_key,
		    args->local_integ_key, args->local_integ_key_len);

      rv = ipsec_sa_add_and_lock (ipsec_tun_mk_output_sa_id (dev_instance),
				  args->local_spi,
				  IPSEC_PROTOCOL_ESP,
				  args->crypto_alg,
				  &crypto_key,
				  args->integ_alg,
				  &integ_key,
				  flags,
				  args->tx_table_id,
				  args->salt,
				  &args->local_ip,
				  &args->remote_ip, &t->output_sa_index);

      if (rv)
	return rv;

      /* copy the key */
      if (is_ip6)
	hash_set_mem_alloc (&im->ipsec6_if_pool_index_by_key, &key6,
			    t - im->tunnel_interfaces);
      else
	hash_set (im->ipsec4_if_pool_index_by_key, key4.as_u64,
		  t - im->tunnel_interfaces);

      hw_if_index = vnet_register_interface (vnm, ipsec_device_class.index,
					     t - im->tunnel_interfaces,
					     ipsec_hw_class.index,
					     t - im->tunnel_interfaces);

      hi = vnet_get_hw_interface (vnm, hw_if_index);

      t->hw_if_index = hw_if_index;
      t->sw_if_index = hi->sw_if_index;

      /* Standard default jumbo MTU. */
      vnet_sw_interface_set_mtu (vnm, t->sw_if_index, 9000);

      /* Add the new tunnel to the DB of tunnels per sw_if_index ... */
      vec_validate_init_empty (im->ipsec_if_by_sw_if_index, t->sw_if_index,
			       ~0);
      im->ipsec_if_by_sw_if_index[t->sw_if_index] = dev_instance;

      ipsec_tunnel_feature_set (im, t, 1);

      /*1st interface, register protocol */
      if (pool_elts (im->tunnel_interfaces) == 1)
	{
	  ip4_register_protocol (IP_PROTOCOL_IPSEC_ESP,
				 ipsec4_if_input_node.index);
	  ip6_register_protocol (IP_PROTOCOL_IPSEC_ESP,
				 ipsec6_if_input_node.index);
	}

    }
  else
    {
      u32 ti;

      /* check if exists */
      if (!p)
	return VNET_API_ERROR_INVALID_VALUE;

      ti = p[0];
      t = pool_elt_at_index (im->tunnel_interfaces, ti);
      hi = vnet_get_hw_interface (vnm, t->hw_if_index);
      vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0);	/* admin down */

      ipsec_tunnel_feature_set (im, t, 0);
      vnet_delete_hw_interface (vnm, t->hw_if_index);

      if (is_ip6)
	hash_unset_mem_free (&im->ipsec6_if_pool_index_by_key, &key6);
      else
	hash_unset (im->ipsec4_if_pool_index_by_key, key4.as_u64);
      hash_unset (im->ipsec_if_real_dev_by_show_dev, t->show_instance);

      im->ipsec_if_by_sw_if_index[t->sw_if_index] = ~0;

      /* delete input and output SA */
      ipsec_sa_unlock (t->input_sa_index);
      ipsec_sa_unlock (t->output_sa_index);

      pool_put (im->tunnel_interfaces, t);
    }

  if (sw_if_index)
    *sw_if_index = hi->sw_if_index;

  return 0;
}

int
ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id,
			u8 is_outbound)
{
  ipsec_main_t *im = &ipsec_main;
  vnet_hw_interface_t *hi;
  ipsec_tunnel_if_t *t;
  ipsec_sa_t *sa, *old_sa;
  u32 sa_index, old_sa_index;
  uword *p;

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  t = pool_elt_at_index (im->tunnel_interfaces, hi->dev_instance);

  sa_index = ipsec_sa_find_and_lock (sa_id);

  if (INDEX_INVALID == sa_index)
    {
      clib_warning ("SA with ID %u not found", sa_id);
      return VNET_API_ERROR_NO_SUCH_ENTRY;
    }

  sa = pool_elt_at_index (im->sad, sa_index);

  if (!is_outbound)
    {
      old_sa_index = t->input_sa_index;
      old_sa = pool_elt_at_index (im->sad, old_sa_index);

      if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ^
	  ipsec_sa_is_set_IS_TUNNEL_V6 (old_sa))
	{
	  clib_warning ("IPsec interface SA endpoints type can't be changed");
	  return VNET_API_ERROR_INVALID_VALUE;
	}

      if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa))
	{
	  ipsec6_tunnel_key_t key;

	  /* unset old inbound hash entry. packets should stop arriving */
	  key.remote_ip = old_sa->tunnel_src_addr.ip6;
	  key.spi = clib_host_to_net_u32 (old_sa->spi);

	  p = hash_get_mem (im->ipsec6_if_pool_index_by_key, &key);
	  if (p)
	    hash_unset_mem_free (&im->ipsec6_if_pool_index_by_key, &key);

	  /* set new inbound SA, then set new hash entry */
	  t->input_sa_index = sa_index;
	  key.remote_ip = sa->tunnel_src_addr.ip6;
	  key.spi = clib_host_to_net_u32 (sa->spi);

	  hash_set_mem_alloc (&im->ipsec6_if_pool_index_by_key, &key,
			      hi->dev_instance);
	}
      else
	{
	  ipsec4_tunnel_key_t key;

	  /* unset old inbound hash entry. packets should stop arriving */
	  key.remote_ip.as_u32 = old_sa->tunnel_src_addr.ip4.as_u32;
	  key.spi = clib_host_to_net_u32 (old_sa->spi);

	  p = hash_get (im->ipsec4_if_pool_index_by_key, key.as_u64);
	  if (p)
	    hash_unset (im->ipsec4_if_pool_index_by_key, key.as_u64);

	  /* set new inbound SA, then set new hash entry */
	  t->input_sa_index = sa_index;
	  key.remote_ip.as_u32 = sa->tunnel_src_addr.ip4.as_u32;
	  key.spi = clib_host_to_net_u32 (sa->spi);

	  hash_set (im->ipsec4_if_pool_index_by_key, key.as_u64,
		    hi->dev_instance);
	}
    }
  else
    {
      old_sa_index = t->output_sa_index;
      old_sa = pool_elt_at_index (im->sad, old_sa_index);

      if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ^
	  ipsec_sa_is_set_IS_TUNNEL_V6 (old_sa))
	{
	  clib_warning ("IPsec interface SA endpoints type can't be changed");
	  return VNET_API_ERROR_INVALID_VALUE;
	}

      /*
       * re-enable the feature to get the new SA in
       * the workers are stopped so no packets are sent in the clear
       */
      ipsec_tunnel_feature_set (im, t, 0);
      t->output_sa_index = sa_index;
      ipsec_tunnel_feature_set (im, t, 1);
    }

  /* remove sa_id to sa_index mapping on old SA */
  hash_unset (im->sa_index_by_sa_id, old_sa->id);

  if (ipsec_add_del_sa_sess_cb (im, old_sa_index, 0))
    {
      clib_warning ("IPsec backend add/del callback returned error");
      return VNET_API_ERROR_SYSCALL_ERROR_1;
    }

  ipsec_sa_unlock (old_sa_index);

  return 0;
}

clib_error_t *
ipsec_tunnel_if_init (vlib_main_t * vm)
{
  ipsec_main_t *im = &ipsec_main;

  /* initialize the ipsec-if ip4 hash */
  im->ipsec4_if_pool_index_by_key =
    hash_create (0, sizeof (ipsec4_tunnel_key_t));
  /* initialize the ipsec-if ip6 hash */
  im->ipsec6_if_pool_index_by_key = hash_create_mem (0,
						     sizeof
						     (ipsec6_tunnel_key_t),
						     sizeof (uword));
  im->ipsec_if_real_dev_by_show_dev = hash_create (0, sizeof (uword));

  /* set up feature nodes to drop outbound packets with no crypto alg set */
  ipsec_add_feature ("ip4-output", "esp4-no-crypto",
		     &im->esp4_no_crypto_tun_feature_index);
  ipsec_add_feature ("ip6-output", "esp6-no-crypto",
		     &im->esp6_no_crypto_tun_feature_index);

  udp_register_dst_port (vlib_get_main (),
			 UDP_DST_PORT_ipsec, ipsec4_if_input_node.index, 1);
  return 0;
}

VLIB_INIT_FUNCTION (ipsec_tunnel_if_init);


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