/*
 * Copyright (c) 2016 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.
 */
/**
 * @file
 * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
 *
 */

#include <vnet/lisp-gpe/lisp_gpe.h>
#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
#include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
#include <vnet/fib/fib_path_list.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_internal.h>

/** LISP-GPE global state */
lisp_gpe_main_t lisp_gpe_main;


/** CLI command to add/del forwarding entry. */
static clib_error_t *
lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
				       unformat_input_t * input,
				       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 is_add = 1;
  ip_address_t lloc, rloc;
  clib_error_t *error = 0;
  gid_address_t _reid, *reid = &_reid, _leid, *leid = &_leid;
  u8 reid_set = 0, leid_set = 0, is_negative = 0, dp_table_set = 0,
    vni_set = 0;
  u32 vni = 0, dp_table = 0, action = ~0, w;
  locator_pair_t pair, *pairs = 0;
  int rv;

  memset (leid, 0, sizeof (*leid));
  memset (reid, 0, sizeof (*reid));

  /* 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, "del"))
	is_add = 0;
      else if (unformat (line_input, "add"))
	is_add = 1;
      else if (unformat (line_input, "leid %U", unformat_gid_address, leid))
	{
	  leid_set = 1;
	}
      else if (unformat (line_input, "reid %U", unformat_gid_address, reid))
	{
	  reid_set = 1;
	}
      else if (unformat (line_input, "vni %u", &vni))
	{
	  gid_address_vni (leid) = vni;
	  gid_address_vni (reid) = vni;
	  vni_set = 1;
	}
      else if (unformat (line_input, "vrf %u", &dp_table))
	{
	  dp_table_set = 1;
	}
      else if (unformat (line_input, "bd %u", &dp_table))
	{
	  dp_table_set = 1;
	}
      else if (unformat (line_input, "negative action %U",
			 unformat_negative_mapping_action, &action))
	{
	  is_negative = 1;
	}
      else if (unformat (line_input, "loc-pair %U %U w %d",
			 unformat_ip_address, &lloc,
			 unformat_ip_address, &rloc, &w))
	{
	  pair.lcl_loc = lloc;
	  pair.rmt_loc = rloc;
	  pair.weight = w;
	  pair.priority = 0;
	  vec_add1 (pairs, pair);
	}
      else
	{
	  error = unformat_parse_error (line_input);
	  vlib_cli_output (vm, "parse error: '%U'",
			   format_unformat_error, line_input);
	  goto done;
	}
    }

  if (!reid_set)
    {
      vlib_cli_output (vm, "remote eid must be set!");
      goto done;
    }

  if (gid_address_type (reid) != GID_ADDR_NSH && (!vni_set || !dp_table_set))
    {
      vlib_cli_output (vm, "vni and vrf/bd must be set!");
      goto done;
    }

  if (is_negative)
    {
      if (~0 == action)
	{
	  vlib_cli_output (vm, "no action set for negative tunnel!");
	  goto done;
	}
    }
  else
    {
      if (vec_len (pairs) == 0)
	{
	  vlib_cli_output (vm, "expected ip4/ip6 locators");
	  goto done;
	}
    }

  if (!leid_set)
    {
      /* if leid not set, make sure it's the same AFI like reid */
      gid_address_type (leid) = gid_address_type (reid);
      if (GID_ADDR_IP_PREFIX == gid_address_type (reid))
	gid_address_ip_version (leid) = gid_address_ip_version (reid);
    }

  /* add fwd entry */
  vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
  memset (a, 0, sizeof (a[0]));

  a->is_add = is_add;
  a->is_negative = is_negative;
  a->vni = vni;
  a->table_id = dp_table;
  gid_address_copy (&a->lcl_eid, leid);
  gid_address_copy (&a->rmt_eid, reid);
  a->locator_pairs = pairs;
  a->action = action;

  rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
  if (0 != rv)
    {
      vlib_cli_output (vm, "failed to %s gpe tunnel!",
		       is_add ? "add" : "delete");
    }

done:
  unformat_free (line_input);
  vec_free (pairs);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = {
  .path = "gpe entry",
  .short_help = "gpe entry add/del vni <vni> vrf/bd <id> [leid <leid>]"
      "reid <reid> [loc-pair <lloc> <rloc> w <weight>] "
      "[negative action <action>]",
  .function = lisp_gpe_add_del_fwd_entry_command_fn,
};
/* *INDENT-ON* */

/** Check if LISP-GPE is enabled. */
u8
vnet_lisp_gpe_enable_disable_status (void)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  return lgm->is_en;
}

/** Enable/disable LISP-GPE. */
clib_error_t *
vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  if (a->is_en)
    {
      lgm->is_en = 1;
    }
  else
    {
      /* remove all entries */
      vnet_lisp_gpe_fwd_entry_flush ();

      /* disable all l3 ifaces */
      lisp_gpe_tenant_flush ();

      lgm->is_en = 0;
    }

  return 0;
}

/** Set GPE encapsulation mode. */
int
vnet_gpe_set_encap_mode (gpe_encap_mode_t mode)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  if (mode >= GPE_ENCAP_COUNT)
    return VNET_API_ERROR_INVALID_GPE_MODE;

  if (pool_elts (lgm->lisp_fwd_entry_pool) != 0)
    return VNET_API_ERROR_LISP_GPE_ENTRIES_PRESENT;

  lgm->encap_mode = mode;
  return 0;
}

/** CLI command to set GPE encap */
static clib_error_t *
gpe_set_encap_mode_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  gpe_encap_mode_t mode = GPE_ENCAP_COUNT;
  vnet_api_error_t 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, "lisp"))
	mode = GPE_ENCAP_LISP;
      else if (unformat (line_input, "vxlan"))
	mode = GPE_ENCAP_VXLAN;
      else
	{
	  return clib_error_return (0, "parse error: '%U'",
				    format_unformat_error, line_input);
	}
    }
  rv = vnet_gpe_set_encap_mode (mode);
  if (rv)
    {
      return clib_error_return (0,
				"Error: invalid mode or GPE entries are present!");
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gpe_set_encap_mode_command, static) = {
  .path = "gpe encap",
  .short_help = "gpe encap [lisp|vxlan]",
  .function = gpe_set_encap_mode_command_fn,
};
/* *INDENT-ON* */

/** Format GPE encap mode. */
u8 *
format_vnet_gpe_encap_mode (u8 * s, va_list * args)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;

  switch (lgm->encap_mode)
    {
    case GPE_ENCAP_LISP:
      return format (s, "lisp");
    case GPE_ENCAP_VXLAN:
      return format (s, "vxlan");
    default:
      return 0;
    }
  return 0;
}

/** CLI command to show GPE encap */
static clib_error_t *
gpe_show_encap_mode_command_fn (vlib_main_t * vm,
				unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  vlib_cli_output (vm, "encap mode: %U", format_vnet_gpe_encap_mode);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gpe_show_encap_mode_command, static) = {
  .path = "show gpe encap",
  .short_help = "show GPE encapulation mode",
  .function = gpe_show_encap_mode_command_fn,
};
/* *INDENT-ON* */

/** CLI command to enable/disable LISP-GPE. */
static clib_error_t *
lisp_gpe_enable_disable_command_fn (vlib_main_t * vm,
				    unformat_input_t * input,
				    vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 is_en = 1;
  vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
  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, "enable"))
	is_en = 1;
      else if (unformat (line_input, "disable"))
	is_en = 0;
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }
  a->is_en = is_en;
  error = vnet_lisp_gpe_enable_disable (a);

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = {
  .path = "gpe",
  .short_help = "gpe [enable|disable]",
  .function = lisp_gpe_enable_disable_command_fn,
};
/* *INDENT-ON* */

/** CLI command to show LISP-GPE interfaces. */
static clib_error_t *
lisp_show_iface_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  hash_pair_t *p;

  vlib_cli_output (vm, "%=10s%=12s", "vrf", "hw_if_index");

  /* *INDENT-OFF* */
  hash_foreach_pair (p, lgm->l3_ifaces.hw_if_index_by_dp_table, ({
    vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
  }));
  /* *INDENT-ON* */

  if (0 != lgm->l2_ifaces.hw_if_index_by_dp_table)
    {
      vlib_cli_output (vm, "%=10s%=12s", "bd_id", "hw_if_index");
      /* *INDENT-OFF* */
      hash_foreach_pair (p, lgm->l2_ifaces.hw_if_index_by_dp_table, ({
        vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
      }));
      /* *INDENT-ON* */
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (lisp_show_iface_command) = {
    .path = "show gpe interface",
    .short_help = "show gpe interface",
    .function = lisp_show_iface_command_fn,
};
/* *INDENT-ON* */

/** CLI command to show GPE fwd native route path. */
static clib_error_t *
gpe_show_native_fwd_rpath_command_fn (vlib_main_t * vm,
				      unformat_input_t * input,
				      vlib_cli_command_t * cmd)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  fib_route_path_t *rpath;

  if (vec_len (lgm->native_fwd_rpath[IP4]))
    {
      vec_foreach (rpath, lgm->native_fwd_rpath[IP4])
      {
	vlib_cli_output (vm, "nh: %U fib_index %u sw_if_index %u",
			 format_ip46_address, &rpath->frp_addr,
			 IP46_TYPE_IP4, rpath->frp_fib_index,
			 rpath->frp_sw_if_index);
      }
    }
  if (vec_len (lgm->native_fwd_rpath[IP6]))
    {
      vec_foreach (rpath, lgm->native_fwd_rpath[IP6])
      {
	vlib_cli_output (vm, "nh: %U fib_index %u sw_if_index %u",
			 format_ip46_address, &rpath->frp_addr, IP46_TYPE_IP6,
			 rpath->frp_fib_index, rpath->frp_sw_if_index);
      }
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gpe_show_native_fwd_rpath_command) = {
    .path = "show gpe native-forward",
    .short_help = "show gpe native-forward",
    .function = gpe_show_native_fwd_rpath_command_fn,
};
/* *INDENT-ON* */

void
gpe_update_native_fwd_path (u8 ip_version)
{
  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
  lisp_gpe_fwd_entry_t *lfe;
  fib_prefix_t fib_prefix;
  u32 *lfei;

  vec_foreach (lfei, lgm->native_fwd_lfes[ip_version])
  {
    lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, lfei[0]);
    ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &fib_prefix);
    fib_table_entry_update (lfe->eid_fib_index, &fib_prefix, FIB_SOURCE_LISP,
			    FIB_ENTRY_FLAG_NONE,
			    lgm->native_fwd_rpath[ip_version]);
  }
}

int
vnet_gpe_add_del_native_fwd_rpath (vnet_gpe_native_fwd_rpath_args_t * a)
{
  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
  fib_route_path_t *rpath;
  u8 ip_version;

  ip_version = a->rpath.frp_proto == FIB_PROTOCOL_IP4 ? IP4 : IP6;

  if (a->is_add)
    {
      vec_add1 (lgm->native_fwd_rpath[ip_version], a->rpath);
    }
  else
    {
      vec_foreach (rpath, lgm->native_fwd_rpath[ip_version])
      {
	if (!fib_route_path_cmp (rpath, &a->rpath))
	  {
	    vec_del1 (lgm->native_fwd_rpath[ip_version],
		      rpath - lgm->native_fwd_rpath[ip_version]);
	    break;
	  }
      }
    }
  gpe_update_native_fwd_path (ip_version);
  return 0;
}

/**
 * CLI command to add action for native forward.
 */
static clib_error_t *
gpe_native_forward_command_fn (vlib_main_t * vm, unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_api_error_t rv;
  fib_route_path_t rpath;
  u32 table_id = ~0;
  vnet_gpe_native_fwd_rpath_args_t _a, *a = &_a;
  u8 is_add = 1;
  clib_error_t *error = 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  memset (&rpath, 0, sizeof (rpath));

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "table %d", &table_id))
	;
      else if (unformat (line_input, "del"))
	is_add = 0;
      else if (unformat (line_input, "via %U %U",
			 unformat_ip4_address,
			 &rpath.frp_addr.ip4,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index))
	{
	  rpath.frp_weight = 1;
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	}
      else if (unformat (line_input, "via %U %U",
			 unformat_ip6_address,
			 &rpath.frp_addr.ip6,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index))
	{
	  rpath.frp_weight = 1;
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	}
      else if (unformat (line_input, "via %U",
			 unformat_ip4_address, &rpath.frp_addr.ip4))
	{
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	}
      else if (unformat (line_input, "via %U",
			 unformat_ip6_address, &rpath.frp_addr.ip6))
	{
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	}
      else
	{
	  return clib_error_return (0, "parse error: '%U'",
				    format_unformat_error, line_input);
	}
    }

  if ((u32) ~ 0 == table_id)
    {
      rpath.frp_fib_index = 0;
    }
  else
    {
      rpath.frp_fib_index = fib_table_find (rpath.frp_proto, table_id);
      if ((u32) ~ 0 == rpath.frp_fib_index)
	{
	  error = clib_error_return (0, "Nonexistent table id %d", table_id);
	  goto done;
	}
    }

  a->rpath = rpath;
  a->is_add = is_add;

  rv = vnet_gpe_add_del_native_fwd_rpath (a);
  if (rv)
    {
      return clib_error_return (0, "Error: couldn't add path!");
    }

done:
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gpe_native_forward_command) = {
    .path = "gpe native-forward",
    .short_help = "gpe native-forward [del] via <nh-ip-addr> [iface] "
	"[table <table>]",
    .function = gpe_native_forward_command_fn,
};
/* *INDENT-ON* */

/** Format LISP-GPE status. */
u8 *
format_vnet_lisp_gpe_status (u8 * s, va_list * args)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  return format (s, "%s", lgm->is_en ? "enabled" : "disabled");
}

/** LISP-GPE init function. */
clib_error_t *
lisp_gpe_init (vlib_main_t * vm)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  clib_error_t *error = 0;

  if ((error = vlib_call_init_function (vm, ip_main_init)))
    return error;

  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
    return error;

  lgm->vnet_main = vnet_get_main ();
  lgm->vlib_main = vm;
  lgm->im4 = &ip4_main;
  lgm->im6 = &ip6_main;
  lgm->lm4 = &ip4_main.lookup_main;
  lgm->lm6 = &ip6_main.lookup_main;
  lgm->encap_mode = GPE_ENCAP_LISP;

  lgm->lisp_gpe_fwd_entries =
    hash_create_mem (0, sizeof (lisp_gpe_fwd_entry_key_t), sizeof (uword));

  udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe,
			 lisp_gpe_ip4_input_node.index, 1 /* is_ip4 */ );
  udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe6,
			 lisp_gpe_ip6_input_node.index, 0 /* is_ip4 */ );

  lgm->lisp_stats_index_by_key =
    hash_create_mem (0, sizeof (lisp_stats_key_t), sizeof (uword));
  memset (&lgm->counters, 0, sizeof (lgm->counters));
  lgm->counters.name = "LISP counters";

  return 0;
}

gpe_encap_mode_t
vnet_gpe_get_encap_mode (void)
{
  lisp_gpe_main_t *lgm = &lisp_gpe_main;
  return lgm->encap_mode;
}

static clib_error_t *
lisp_gpe_test_send_nsh_packet (u8 * file_name)
{
  vlib_frame_t *f;
  vlib_buffer_t *b;
  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
  pcap_main_t pm;
  clib_error_t *error = 0;

  if (!file_name)
    return clib_error_create ("no pcap file specified!");

  memset (&pm, 0, sizeof (pm));
  pm.file_name = (char *) file_name;
  error = pcap_read (&pm);
  if (error)
    return error;

  u32 bi;
  if (vlib_buffer_alloc (lgm->vlib_main, &bi, 1) != 1)
    return clib_error_create ("cannot allocate memory!");

  b = vlib_get_buffer (lgm->vlib_main, bi);
  tunnel_lookup_t *nsh_ifaces = &lgm->nsh_ifaces;
  uword *hip;
  vnet_hw_interface_t *hi;

  hip = hash_get (nsh_ifaces->hw_if_index_by_dp_table, 0);
  if (hip == 0)
    return clib_error_create ("The NSH 0 interface doesn't exist");

  hi = vnet_get_hw_interface (lgm->vnet_main, hip[0]);

  vnet_buffer (b)->sw_if_index[VLIB_TX] = hi->sw_if_index;
  u8 *p = vlib_buffer_put_uninit (b, vec_len (pm.packets_read[0]));
  clib_memcpy (p, pm.packets_read[0], vec_len (pm.packets_read[0]));
  vlib_buffer_pull (b, sizeof (ethernet_header_t));

  vlib_node_t *n = vlib_get_node_by_name (lgm->vlib_main,
					  (u8 *) "interface-tx");
  f = vlib_get_frame_to_node (lgm->vlib_main, n->index);
  u32 *to_next = vlib_frame_vector_args (f);
  to_next[0] = bi;
  f->n_vectors = 1;
  vlib_put_frame_to_node (lgm->vlib_main, n->index, f);

  return error;
}

static clib_error_t *
lisp_test_nsh_command_fn (vlib_main_t * vm, unformat_input_t * input,
			  vlib_cli_command_t * cmd)
{
  clib_error_t *error = 0;
  u8 *file_name = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "pcap %v", &file_name))
	{
	  error = lisp_gpe_test_send_nsh_packet (file_name);
	  goto done;
	}
      else
	{
	  error = clib_error_create ("unknown input `%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

done:
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (lisp_test_nsh_command, static) = {
  .path = "test one nsh",
  .short_help = "test gpe nsh pcap <path-to-pcap-file>",
  .function = lisp_test_nsh_command_fn,
};
/* *INDENT-ON* */

VLIB_INIT_FUNCTION (lisp_gpe_init);

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