/*
 * sixrd.c - 6RD specific functions (RFC5969)
 *
 * 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.
 */

/**
 * This code supports the following sixrd modes:
 *
 * 32 EA bits (Complete IPv4 address is embedded):
 *   ea_bits_len = 32
 * IPv4 suffix is embedded:
 *   ea_bits_len = < 32
 * No embedded address bits (1:1 mode):
 *   ea_bits_len = 0
 */

#include "ipip.h"
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vnet/adj/adj.h>
#include <vnet/adj/adj_delegate.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/dpo/lookup_dpo.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_entry_track.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/plugin/plugin.h>

extern vlib_node_registration_t ip4_sixrd_node;

/**
 * Adj delegate data
 */
typedef struct sixrd_adj_delegate_t_
{
  u32 adj_index;
  fib_node_t sixrd_node;
  fib_node_index_t sixrd_fib_entry_index;
  u32 sixrd_sibling;
} sixrd_adj_delegate_t;

/**
 * Pool of delegate structs
 */
static sixrd_adj_delegate_t *sixrd_adj_delegate_pool;

/**
 * Adj delegate registered type
 */
static adj_delegate_type_t sixrd_adj_delegate_type;

/**
 * FIB node registered type
 */
static fib_node_type_t sixrd_fib_node_type;

static inline sixrd_adj_delegate_t *
sixrd_adj_from_base (adj_delegate_t * ad)
{
  if (ad == NULL)
    return (NULL);
  return (pool_elt_at_index (sixrd_adj_delegate_pool, ad->ad_index));
}

static inline const sixrd_adj_delegate_t *
sixrd_adj_from_const_base (const adj_delegate_t * ad)
{
  if (ad == NULL)
    {
      return (NULL);
    }
  return (pool_elt_at_index (sixrd_adj_delegate_pool, ad->ad_index));
}

static void
sixrd_fixup (vlib_main_t * vm,
	     const ip_adjacency_t * adj, vlib_buffer_t * b0, const void *data)
{
  ip4_header_t *ip4 = vlib_buffer_get_current (b0);
  ip6_header_t *ip6 = vlib_buffer_get_current (b0) + sizeof (ip4_header_t);
  const ipip_tunnel_t *t = data;

  ip4->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
  ip4->dst_address.as_u32 =
    sixrd_get_addr_net (t, ip6->dst_address.as_u64[0]);
  ip4->checksum = ip4_header_checksum (ip4);
}

static void
ip6ip_fixup (vlib_main_t * vm,
	     const ip_adjacency_t * adj, vlib_buffer_t * b0, const void *data)
{
  const ipip_tunnel_t *t = data;
  ip4_header_t *ip4 = vlib_buffer_get_current (b0);
  ip4->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
  ip4->dst_address.as_u32 =
    sixrd_get_addr_net (t, adj->sub_type.nbr.next_hop.as_u64[0]);
  ip4->checksum = ip4_header_checksum (ip4);
}

static u8 *
sixrd_build_rewrite (vnet_main_t * vnm, u32 sw_if_index,
		     vnet_link_t link_type, const void *dst_address)
{
  u8 *rewrite = NULL;
  ipip_tunnel_t *t;

  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return 0;

  vec_validate (rewrite, sizeof (ip4_header_t) - 1);
  ip4_header_t *ip4 = (ip4_header_t *) rewrite;
  ip4->ip_version_and_header_length = 0x45;
  ip4->ttl = 64;
  ip4->protocol = IP_PROTOCOL_IPV6;
  /* fixup ip4 header length and checksum after-the-fact */
  ip4->src_address.as_u32 = t->tunnel_src.ip4.as_u32;
  ip4->dst_address.as_u32 = 0;
  ip4->checksum = ip4_header_checksum (ip4);

  return rewrite;
}

static void
ip6ip_tunnel_stack (adj_index_t ai, u32 fib_entry_index)
{
  ip_adjacency_t *adj = adj_get (ai);
  ipip_tunnel_t *t;
  u32 sw_if_index = adj->rewrite_header.sw_if_index;

  t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return;

  /*
   * find the adjacency that is contributed by the FIB entry
   * that this tunnel resolves via, and use it as the next adj
   * in the midchain
   */
  if (vnet_hw_interface_get_flags (vnet_get_main (), t->hw_if_index) &
      VNET_HW_INTERFACE_FLAG_LINK_UP)
    {
      adj_nbr_midchain_stack_on_fib_entry (ai,
					   fib_entry_index,
					   FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
    }
  else
    {
      adj_nbr_midchain_unstack (ai);
    }
}

static void
sixrd_tunnel_stack (adj_index_t ai, u32 fib_index)
{
  dpo_id_t dpo = DPO_INVALID;
  ip_adjacency_t *adj = adj_get (ai);
  u32 sw_if_index = adj->rewrite_header.sw_if_index;

  ipip_tunnel_t *t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  if (!t)
    return;

  lookup_dpo_add_or_lock_w_fib_index (fib_index, DPO_PROTO_IP4,
				      LOOKUP_UNICAST, LOOKUP_INPUT_DST_ADDR,
				      LOOKUP_TABLE_FROM_CONFIG, &dpo);
  adj_nbr_midchain_stack (ai, &dpo);
  dpo_reset (&dpo);
}

static void
sixrd_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
{
  ip_adjacency_t *adj = adj_get (ai);
  ipip_tunnel_t *t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);

  /* Not our tunnel */
  if (!t)
    return;
  if (IP_LOOKUP_NEXT_BCAST == adj->lookup_next_index)
    {
      adj_nbr_midchain_update_rewrite (ai, sixrd_fixup, t, ADJ_FLAG_NONE,
				       sixrd_build_rewrite (vnm, sw_if_index,
							    adj_get_link_type
							    (ai), NULL));
      sixrd_tunnel_stack (ai, t->fib_index);
    }
  else
    {
      sixrd_adj_delegate_t *sixrd_ad;
      ip4_address_t da4;

      da4.as_u32 =
	sixrd_get_addr_net (t, adj->sub_type.nbr.next_hop.as_u64[0]);

      fib_prefix_t pfx = {
	.fp_proto = FIB_PROTOCOL_IP4,
	.fp_len = 32,
	.fp_addr = {
		    .ip4 = da4,
		    }
	,
      };

      adj_nbr_midchain_update_rewrite (ai, ip6ip_fixup, t, ADJ_FLAG_NONE,
				       sixrd_build_rewrite (vnm, sw_if_index,
							    adj_get_link_type
							    (ai), NULL));

      sixrd_ad =
	sixrd_adj_from_base (adj_delegate_get (adj, sixrd_adj_delegate_type));
      if (sixrd_ad == NULL)
	{
	  pool_get (sixrd_adj_delegate_pool, sixrd_ad);
	  fib_node_init (&sixrd_ad->sixrd_node, sixrd_fib_node_type);
	  sixrd_ad->adj_index = ai;
	  sixrd_ad->sixrd_fib_entry_index =
	    fib_entry_track (t->fib_index, &pfx,
			     sixrd_fib_node_type,
			     sixrd_ad - sixrd_adj_delegate_pool,
			     &sixrd_ad->sixrd_sibling);

	  adj_delegate_add (adj, sixrd_adj_delegate_type,
			    sixrd_ad - sixrd_adj_delegate_pool);

	  ip6ip_tunnel_stack (ai, sixrd_ad->sixrd_fib_entry_index);
	}
    }
}

clib_error_t *
sixrd_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  /* Always up */
  vnet_hw_interface_set_flags (vnm, hw_if_index,
			       VNET_HW_INTERFACE_FLAG_LINK_UP);
  return /* no error */ 0;
}

VNET_HW_INTERFACE_CLASS(sixrd_hw_interface_class) = {
    .name = "ip6ip-6rd",
    .build_rewrite = sixrd_build_rewrite,
    .update_adjacency = sixrd_update_adj,
};

VNET_DEVICE_CLASS(sixrd_device_class) = {
    .name = "ip6ip-6rd",
    .admin_up_down_function = sixrd_interface_admin_up_down,
#ifdef SOON
    .clear counter = 0;
#endif
}
;

int
sixrd_add_tunnel (ip6_address_t * ip6_prefix, u8 ip6_prefix_len,
		  ip4_address_t * ip4_prefix, u8 ip4_prefix_len,
		  ip4_address_t * ip4_src, bool security_check,
		  u32 ip4_fib_index, u32 ip6_fib_index, u32 * sw_if_index)
{
  ipip_main_t *gm = &ipip_main;
  ipip_tunnel_t *t;

  if ((ip6_prefix_len + 32 - ip4_prefix_len) > 64)
    return VNET_API_ERROR_INVALID_VALUE;

  /* Tunnel already configured */
  ip46_address_t src = ip46_address_initializer, dst =
    ip46_address_initializer;
  ip_set (&src, ip4_src, true);
  ipip_tunnel_key_t key;

  ipip_mk_key_i (IPIP_TRANSPORT_IP4, IPIP_MODE_6RD, &src, &dst, ip4_fib_index,
		 &key);

  t = ipip_tunnel_db_find (&key);
  if (t)
    return VNET_API_ERROR_IF_ALREADY_EXISTS;

  /* Get tunnel index */
  pool_get_aligned (gm->tunnels, t, CLIB_CACHE_LINE_BYTES);
  clib_memset (t, 0, sizeof (*t));
  u32 t_idx = t - gm->tunnels;	/* tunnel index (or instance) */

  /* Init tunnel struct */
  t->mode = IPIP_MODE_6RD;
  t->sixrd.ip4_prefix.as_u32 = ip4_prefix->as_u32;
  t->sixrd.ip4_prefix_len = ip4_prefix_len;
  t->sixrd.ip6_prefix = *ip6_prefix;
  t->sixrd.ip6_prefix_len = ip6_prefix_len;
  t->sixrd.ip6_fib_index = ip6_fib_index;
  t->tunnel_src = src;
  t->sixrd.security_check = security_check;
  t->sixrd.shift =
    (ip4_prefix_len < 32) ? 64 - ip6_prefix_len - (32 - ip4_prefix_len) : 0;

  /* Create interface */
  u32 hw_if_index =
    vnet_register_interface (vnet_get_main (), sixrd_device_class.index,
			     t_idx,
			     sixrd_hw_interface_class.index, t_idx);

  /* Default the interface to up and enable IPv6 (payload) */
  vnet_hw_interface_t *hi =
    vnet_get_hw_interface (vnet_get_main (), hw_if_index);
  t->hw_if_index = hw_if_index;
  t->fib_index = ip4_fib_index;
  t->sw_if_index = hi->sw_if_index;
  t->dev_instance = t_idx;
  t->user_instance = t_idx;

  vnet_sw_interface_set_mtu (vnet_get_main (), t->sw_if_index, 1480);
  vnet_set_interface_l3_output_node (gm->vlib_main, hi->sw_if_index,
				     (u8 *) "tunnel-output");

  ipip_tunnel_db_add (t, &key);

  vec_validate_init_empty (gm->tunnel_index_by_sw_if_index, hi->sw_if_index,
			   ~0);
  gm->tunnel_index_by_sw_if_index[hi->sw_if_index] = t_idx;

  vnet_hw_interface_set_flags (vnet_get_main (), hw_if_index,
			       VNET_HW_INTERFACE_FLAG_LINK_UP);
  vnet_sw_interface_set_flags (vnet_get_main (), hi->sw_if_index,
			       VNET_SW_INTERFACE_FLAG_ADMIN_UP);
  ip6_sw_interface_enable_disable (t->sw_if_index, true);

  /* Create IPv6 route/adjacency */
  fib_prefix_t pfx6 = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = t->sixrd.ip6_prefix_len,
    .fp_addr = {
      .ip6 = t->sixrd.ip6_prefix,
    },
  };

  fib_table_lock (ip6_fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_6RD);
  fib_table_entry_update_one_path (ip6_fib_index, &pfx6, FIB_SOURCE_6RD,
				   FIB_ENTRY_FLAG_ATTACHED, DPO_PROTO_IP6,
				   &ADJ_BCAST_ADDR, t->sw_if_index, ~0, 1,
				   NULL, FIB_ROUTE_PATH_FLAG_NONE);

  *sw_if_index = t->sw_if_index;

  if (!gm->ip4_protocol_registered)
    {
      vlib_node_t *ipip4_input =
	vlib_get_node_by_name (gm->vlib_main, (u8 *) "ipip4-input");
      ASSERT (ipip4_input);
      ip4_register_protocol (IP_PROTOCOL_IPV6, ipip4_input->index);
    }
  return 0;
}

/*
 * sixrd_del_tunnel
 */
int
sixrd_del_tunnel (u32 sw_if_index)
{
  ipip_main_t *gm = &ipip_main;
  ipip_tunnel_t *t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index);
  ipip_tunnel_key_t key;

  if (!t)
    {
      clib_warning ("SIXRD tunnel delete: tunnel does not exist: %d",
		    sw_if_index);
      return -1;
    }

  fib_prefix_t pfx6 = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = t->sixrd.ip6_prefix_len,
    .fp_addr = {
      .ip6 = t->sixrd.ip6_prefix,
    },
  };

  fib_table_entry_path_remove (t->sixrd.ip6_fib_index, &pfx6,
			       FIB_SOURCE_6RD,
			       DPO_PROTO_IP6,
			       &ADJ_BCAST_ADDR, t->sw_if_index, ~0, 1,
			       FIB_ROUTE_PATH_FLAG_NONE);
  fib_table_unlock (t->sixrd.ip6_fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_6RD);

  vnet_sw_interface_set_flags (vnet_get_main (), t->sw_if_index,
			       0 /* down */ );
  vnet_reset_interface_l3_output_node (gm->vlib_main, t->sw_if_index);
  ip6_sw_interface_enable_disable (t->sw_if_index, false);
  gm->tunnel_index_by_sw_if_index[t->sw_if_index] = ~0;

  vnet_delete_hw_interface (vnet_get_main (), t->hw_if_index);
  ipip_mk_key (t, &key);
  ipip_tunnel_db_remove (t, &key);
  pool_put (gm->tunnels, t);

  return 0;
}

static void
sixrd_adj_delegate_adj_deleted (adj_delegate_t * aed)
{
  sixrd_adj_delegate_t *sixrd_ad;

  sixrd_ad = sixrd_adj_from_base (aed);
  fib_entry_untrack (sixrd_ad->sixrd_fib_entry_index,
		     sixrd_ad->sixrd_sibling);
  pool_put (sixrd_adj_delegate_pool, sixrd_ad);
}

static u8 *
sixrd_adj_delegate_format (const adj_delegate_t * aed, u8 * s)
{
  const sixrd_adj_delegate_t *sixrd_ad;

  sixrd_ad = sixrd_adj_from_const_base (aed);
  s = format (s, "SIXRD:[fib-entry:%d]", sixrd_ad->sixrd_fib_entry_index);

  return (s);
}

static void
sixrd_fib_node_last_lock_gone (fib_node_t * node)
{
  /* top of the dependency tree, locks not managed here. */
}

static sixrd_adj_delegate_t *
sixrd_adj_delegate_from_fib_node (fib_node_t * node)
{
  return ((sixrd_adj_delegate_t *) (((char *) node) -
				    STRUCT_OFFSET_OF (sixrd_adj_delegate_t,
						      sixrd_node)));
}

static fib_node_back_walk_rc_t
sixrd_fib_node_back_walk_notify (fib_node_t * node,
				 fib_node_back_walk_ctx_t * ctx)
{
  sixrd_adj_delegate_t *sixrd_ad;

  sixrd_ad = sixrd_adj_delegate_from_fib_node (node);
  ip6ip_tunnel_stack (sixrd_ad->adj_index, sixrd_ad->sixrd_fib_entry_index);

  return (FIB_NODE_BACK_WALK_CONTINUE);
}

/**
 * Function definition to get a FIB node from its index
 */
static fib_node_t *
sixrd_fib_node_get (fib_node_index_t index)
{
  sixrd_adj_delegate_t *sixrd_ad;

  sixrd_ad = pool_elt_at_index (sixrd_adj_delegate_pool, index);

  return (&sixrd_ad->sixrd_node);
}

/**
 * VFT registered with the adjacency delegate
 */
const static adj_delegate_vft_t sixrd_adj_delegate_vft = {
  .adv_adj_deleted = sixrd_adj_delegate_adj_deleted,
  .adv_format = sixrd_adj_delegate_format,
};

/**
 * VFT registered with the FIB node for the adj delegate
 */
const static fib_node_vft_t sixrd_fib_node_vft = {
  .fnv_get = sixrd_fib_node_get,
  .fnv_last_lock = sixrd_fib_node_last_lock_gone,
  .fnv_back_walk = sixrd_fib_node_back_walk_notify,
};

static clib_error_t *
sixrd_init (vlib_main_t * vm)
{
  clib_error_t *error = 0;

  /* Make sure the IPIP tunnel subsystem is initialised */
  error = vlib_call_init_function (vm, ipip_init);

  sixrd_adj_delegate_type =
    adj_delegate_register_new_type (&sixrd_adj_delegate_vft);
  sixrd_fib_node_type =
    fib_node_register_new_type ("sixrd", &sixrd_fib_node_vft);

  return error;
}

VLIB_INIT_FUNCTION (sixrd_init);

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