/*
 * Copyright (c) 2019 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/ip6_link.h>
#include <vnet/ip/ip6_ll_table.h>

#include <vnet/ethernet/ethernet.h>
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/adj/adj_mcast.h>

typedef struct ip6_link_delegate_t_
{
  u32 ild_sw_if_index;
  ip6_link_delegate_id_t ild_type;
  index_t ild_index;
} ip6_link_delegate_t;

const static ip6_link_delegate_t ip6_link_delegate_uninit = {
  .ild_sw_if_index = ~0,
};

typedef struct ip6_link_t_
{
  /** interface ip6 is enabled on */
  u32 il_sw_if_index;

  /** link-local address - if unset that IP6 is disabled*/
  ip6_address_t il_ll_addr;

  /** list of delegates */
  ip6_link_delegate_t *il_delegates;

  /** multicast adjacency for this link */
  adj_index_t il_mcast_adj;

  /** number of references to IP6 enabled on this link */
  u32 il_locks;
} ip6_link_t;

#define FOREACH_IP6_LINK_DELEGATE(_ild, _il, body)      \
{                                                       \
 if (NULL != _il) {                                     \
   vec_foreach (_ild, _il->il_delegates) {              \
     if (ip6_link_delegate_is_init(_ild))               \
       body;                                            \
   }                                                    \
 }                                                      \
}

#define FOREACH_IP6_LINK_DELEGATE_ID(_id) \
  for (_id = 0; _id < il_delegate_id; _id++)

/** last used delegate ID */
static ip6_link_delegate_id_t il_delegate_id;

/** VFT registered per-delegate type */
static ip6_link_delegate_vft_t *il_delegate_vfts;

/** Per interface configs */
static ip6_link_t *ip6_links;

/** Randomizer */
static u64 il_randomizer;

/** Logging */
static vlib_log_class_t ip6_link_logger;

#define IP6_LINK_DBG(...)                       \
    vlib_log_debug (ip6_link_logger, __VA_ARGS__);

#define IP6_LINK_INFO(...)                              \
    vlib_log_notice (ip6_link_logger, __VA_ARGS__);

static bool
ip6_link_delegate_is_init (const ip6_link_delegate_t * ild)
{
  return (~0 != ild->ild_sw_if_index);
}

static bool
ip6_link_is_enabled_i (const ip6_link_t * il)
{
  return (!ip6_address_is_zero (&il->il_ll_addr));
}

static void
ip6_link_local_address_from_mac (ip6_address_t * ip, const u8 * mac)
{
  ip->as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
  /* Invert the "u" bit */
  ip->as_u8[8] = mac[0] ^ (1 << 1);
  ip->as_u8[9] = mac[1];
  ip->as_u8[10] = mac[2];
  ip->as_u8[11] = 0xFF;
  ip->as_u8[12] = 0xFE;
  ip->as_u8[13] = mac[3];
  ip->as_u8[14] = mac[4];
  ip->as_u8[15] = mac[5];
}

static void
ip6_mac_address_from_link_local (u8 * mac, const ip6_address_t * ip)
{
  /* Invert the previously inverted "u" bit */
  mac[0] = ip->as_u8[8] ^ (1 << 1);
  mac[1] = ip->as_u8[9];
  mac[2] = ip->as_u8[10];
  mac[3] = ip->as_u8[13];
  mac[4] = ip->as_u8[14];
  mac[5] = ip->as_u8[15];
}

static ip6_link_t *
ip6_link_get (u32 sw_if_index)
{
  ip6_link_t *il;

  if (sw_if_index >= vec_len (ip6_links))
    return (NULL);

  il = &ip6_links[sw_if_index];

  if (!ip6_link_is_enabled_i (il))
    return (NULL);

  return (il);
}

bool
ip6_link_is_enabled (u32 sw_if_index)
{
  return (NULL != ip6_link_get (sw_if_index));
}


int
ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
{
  ip6_link_t *il;
  int rv;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    {
      const vnet_sw_interface_t *sw_sup;
      const ethernet_interface_t *eth;
      vnet_main_t *vnm;

      eth = NULL;
      vnm = vnet_get_main ();

      IP6_LINK_INFO ("enable: %U",
		     format_vnet_sw_if_index_name, vnm, sw_if_index);

      sw_sup = vnet_get_sup_sw_interface (vnm, sw_if_index);
      vec_validate (ip6_links, sw_if_index);

      il = &ip6_links[sw_if_index];
      il->il_locks = 0;
      il->il_sw_if_index = sw_if_index;
      il->il_mcast_adj = ADJ_INDEX_INVALID;

      if (sw_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
	eth = ethernet_get_interface (&ethernet_main, sw_sup->hw_if_index);

      /* use a user provided LL address if given */
      if (NULL != link_local_addr)
	ip6_address_copy (&il->il_ll_addr, link_local_addr);

      /* generate from ethernet MAC */
      if (ip6_address_is_zero (&il->il_ll_addr) && NULL != eth)
	ip6_link_local_address_from_mac (&il->il_ll_addr,
					 eth->address.mac.bytes);

      /* choose a random address */
      if (ip6_address_is_zero (&il->il_ll_addr))
	{
	  il->il_ll_addr.as_u64[0] =
	    clib_host_to_net_u64 (0xFE80000000000000ULL);

	  /* make up an interface id */
	  il->il_ll_addr.as_u64[1] = random_u64 (&il_randomizer);

	  /* clear u bit */
	  il->il_ll_addr.as_u8[8] &= 0xfd;
	}

      {
	ip6_ll_prefix_t ilp = {
	  .ilp_addr = il->il_ll_addr,
	  .ilp_sw_if_index = sw_if_index,
	};

	ip6_ll_table_entry_update (&ilp, FIB_ROUTE_PATH_LOCAL);
      }

      /* essentially "enables" ipv6 on this interface */
      ip6_mfib_interface_enable_disable (sw_if_index, 1);
      ip6_sw_interface_enable_disable (sw_if_index, 1);

      /* only ehternet interfaces support MLD and RA, which use the mcast adj
       */
      if (NULL != eth)
	il->il_mcast_adj =
	  adj_mcast_add_or_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, sw_if_index);

      /* inform all register clients */
      ip6_link_delegate_id_t id;
      FOREACH_IP6_LINK_DELEGATE_ID (id)
      {
	if (NULL != il_delegate_vfts[id].ildv_enable)
	  il_delegate_vfts[id].ildv_enable (il->il_sw_if_index);
      }

      rv = 0;
    }
  else
    {
      rv = VNET_API_ERROR_VALUE_EXIST;
    }

  il->il_locks++;

  return (rv);
}

static void
ip6_link_delegate_flush (ip6_link_t * il)
{
  ip6_link_delegate_t *ild;

  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
    il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
  }));

  vec_free (il->il_delegates);
  il->il_delegates = NULL;
}

static void
ip6_link_last_lock_gone (ip6_link_t * il)
{
  ip6_ll_prefix_t ilp = {
    .ilp_addr = il->il_ll_addr,
    .ilp_sw_if_index = il->il_sw_if_index,
  };

  IP6_LINK_INFO ("last-lock: %U",
		 format_vnet_sw_if_index_name,
		 vnet_get_main (), il->il_sw_if_index);

  ip6_link_delegate_flush (il);
  ip6_ll_table_entry_delete (&ilp);

  ip6_mfib_interface_enable_disable (il->il_sw_if_index, 0);
  ip6_sw_interface_enable_disable (il->il_sw_if_index, 0);

  ip6_address_set_zero (&il->il_ll_addr);
  adj_unlock (il->il_mcast_adj);
  il->il_mcast_adj = ADJ_INDEX_INVALID;
}

static void
ip6_link_unlock (ip6_link_t * il)
{
  if (NULL == il)
    return;

  il->il_locks--;

  if (0 == il->il_locks)
    ip6_link_last_lock_gone (il);
}

int
ip6_link_disable (u32 sw_if_index)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (VNET_API_ERROR_IP6_NOT_ENABLED);

  IP6_LINK_INFO ("disable: %U",
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index);

  ip6_link_unlock (il);

  return (0);
}

const ip6_address_t *
ip6_get_link_local_address (u32 sw_if_index)
{
  const ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (NULL);

  return (&il->il_ll_addr);
}

adj_index_t
ip6_link_get_mcast_adj (u32 sw_if_index)
{
  const ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (INDEX_INVALID);

  return (il->il_mcast_adj);
}

int
ip6_link_set_local_address (u32 sw_if_index, const ip6_address_t * address)
{
  ip6_link_delegate_t *ild;
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return ip6_link_enable (sw_if_index, address);

  ip6_ll_prefix_t ilp = {
    .ilp_addr = il->il_ll_addr,
    .ilp_sw_if_index = sw_if_index,
  };

  IP6_LINK_INFO ("set-ll: %U -> %U",
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
		 format_ip6_address, address);

  ip6_ll_table_entry_delete (&ilp);
  ip6_address_copy (&il->il_ll_addr, address);
  ip6_address_copy (&ilp.ilp_addr, address);
  ip6_ll_table_entry_update (&ilp, FIB_ROUTE_PATH_LOCAL);

  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
    if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
      il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
                                                     &il->il_ll_addr);
  }));

  return (0);
}

ip6_link_delegate_id_t
ip6_link_delegate_register (const ip6_link_delegate_vft_t * vft)
{
  ip6_link_delegate_id_t rc = il_delegate_id++;

  ASSERT (vft->ildv_disable);

  vec_validate (il_delegate_vfts, rc);

  il_delegate_vfts[rc] = *vft;

  return (rc);
}

index_t
ip6_link_delegate_get (u32 sw_if_index, ip6_link_delegate_id_t id)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (INDEX_INVALID);

  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);

  if (!ip6_link_delegate_is_init (&il->il_delegates[id]))
    return (INDEX_INVALID);

  return (il->il_delegates[id].ild_index);
}

bool
ip6_link_delegate_update (u32 sw_if_index,
			  ip6_link_delegate_id_t id, index_t ii)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (false);

  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);

  il->il_delegates[id].ild_sw_if_index = sw_if_index;
  il->il_delegates[id].ild_type = id;
  il->il_delegates[id].ild_index = ii;

  return (true);
}

void
ip6_link_delegate_remove (u32 sw_if_index,
			  ip6_link_delegate_id_t id, index_t ii)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL != il)
    {
      if (vec_len (il->il_delegates) > id)
	{
	  clib_memcpy (&il->il_delegates[id],
		       &ip6_link_delegate_uninit,
		       sizeof (il->il_delegates[0]));
	}
    }
}

static void
ip6_link_add_del_address (ip6_main_t * im,
			  uword opaque,
			  u32 sw_if_index,
			  ip6_address_t * address,
			  u32 address_length,
			  u32 if_address_index, u32 is_delete)
{
  const ip6_link_delegate_t *ild;
  ip6_link_t *il;

  if (ip6_address_is_link_local_unicast (address))
    // only interested in global addresses here
    return;

  IP6_LINK_INFO ("addr-%s: %U -> %U",
		 (is_delete ? "del" : "add"),
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
		 format_ip6_address, address);

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return;

  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
      if (is_delete)
        {
          if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_del)
            il_delegate_vfts[ild->ild_type].ildv_addr_del(ild->ild_index,
                                                          address, address_length);
        }
      else
        {
          if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_add)
            il_delegate_vfts[ild->ild_type].ildv_addr_add(ild->ild_index,
                                                          address, address_length);
        }
  }));
}

static clib_error_t *
ip6_link_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
{
  if (!is_add)
    {
      ip6_link_t *il;

      il = ip6_link_get (sw_if_index);

      IP6_LINK_DBG ("link-del: %U",
		    format_vnet_sw_if_index_name, vnet_get_main (),
		    sw_if_index);

      if (NULL != il)
	/* force cleanup */
	ip6_link_last_lock_gone (il);
    }

  return (NULL);
}

VNET_SW_INTERFACE_ADD_DEL_FUNCTION (ip6_link_interface_add_del);

static clib_error_t *
ip6_link_init (vlib_main_t * vm)
{
  il_randomizer = clib_cpu_time_now ();
  ip6_link_logger = vlib_log_register_class ("ip6", "link");

  {
    ip6_add_del_interface_address_callback_t cb = {
      .function = ip6_link_add_del_address,
    };
    vec_add1 (ip6_main.add_del_interface_address_callbacks, cb);
  }
  return (NULL);
}

VLIB_INIT_FUNCTION (ip6_link_init);


static clib_error_t *
test_ip6_link_command_fn (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u8 mac[6];
  ip6_address_t _a, *a = &_a;

  if (unformat (input, "%U", unformat_ethernet_address, mac))
    {
      ip6_link_local_address_from_mac (a, mac);
      vlib_cli_output (vm, "Link local address: %U", format_ip6_address, a);
      ip6_mac_address_from_link_local (mac, a);
      vlib_cli_output (vm, "Original MAC address: %U",
		       format_ethernet_address, mac);
    }

  return 0;
}

/*?
 * This command converts the given MAC Address into an IPv6 link-local
 * address.
 *
 * @cliexpar
 * Example of how to create an IPv6 link-local address:
 * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
 * Link local address: fe80::14d9:e0ff:fe91:7986
 * Original MAC address: 16:d9:e0:91:79:86
 * @cliexend
?*/
VLIB_CLI_COMMAND (test_link_command, static) =
{
  .path = "test ip6 link",
  .function = test_ip6_link_command_fn,
  .short_help = "test ip6 link <mac-address>",
};

static u8 *
ip6_print_addrs (u8 * s, u32 * addrs)
{
  ip_lookup_main_t *lm = &ip6_main.lookup_main;
  u32 i;

  for (i = 0; i < vec_len (addrs); i++)
    {
      ip_interface_address_t *a =
	pool_elt_at_index (lm->if_address_pool, addrs[i]);
      ip6_address_t *address = ip_interface_address_get_address (lm, a);

      s = format (s, "%U%U/%d\n",
		  format_white_space, 4,
		  format_ip6_address, address, a->address_length);
    }

  return (s);
}

static u8 *
format_ip6_link (u8 * s, va_list * arg)
{
  const ip6_link_t *il = va_arg (*arg, ip6_link_t *);
  ip_lookup_main_t *lm = &ip6_main.lookup_main;
  vnet_main_t *vnm = vnet_get_main ();

  if (!ip6_link_is_enabled_i (il))
    return (s);

  s = format (
    s, "%U is admin %s\n", format_vnet_sw_if_index_name, vnm,
    il->il_sw_if_index,
    (vnet_sw_interface_is_admin_up (vnm, il->il_sw_if_index) ? "up" : "down"));

  u32 ai;
  u32 *link_scope = 0, *global_scope = 0;
  u32 *local_scope = 0, *unknown_scope = 0;
  ip_interface_address_t *a;
  const ip6_link_delegate_t *ild;

  vec_validate_init_empty (lm->if_address_pool_index_by_sw_if_index,
			   il->il_sw_if_index, ~0);
  ai = lm->if_address_pool_index_by_sw_if_index[il->il_sw_if_index];

  while (ai != (u32) ~ 0)
    {
      a = pool_elt_at_index (lm->if_address_pool, ai);
      ip6_address_t *address = ip_interface_address_get_address (lm, a);

      if (ip6_address_is_link_local_unicast (address))
	vec_add1 (link_scope, ai);
      else if (ip6_address_is_global_unicast (address))
	vec_add1 (global_scope, ai);
      else if (ip6_address_is_local_unicast (address))
	vec_add1 (local_scope, ai);
      else
	vec_add1 (unknown_scope, ai);

      ai = a->next_this_sw_interface;
    }

  if (vec_len (link_scope))
    {
      s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, link_scope);
      vec_free (link_scope);
    }

  if (vec_len (local_scope))
    {
      s = format (s, "%ULocal unicast address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, local_scope);
      vec_free (local_scope);
    }

  if (vec_len (global_scope))
    {
      s = format (s, "%UGlobal unicast address(es):\n",
		  format_white_space, 2);
      s = ip6_print_addrs (s, global_scope);
      vec_free (global_scope);
    }

  if (vec_len (unknown_scope))
    {
      s = format (s, "%UOther-scope address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, unknown_scope);
      vec_free (unknown_scope);
    }

  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
  s = format (s, "%U%U\n",
	      format_white_space, 4, format_ip6_address, &il->il_ll_addr);

  FOREACH_IP6_LINK_DELEGATE(ild, il,
  ({
    s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
                     ild->ild_index, 2);
  }));

  return (s);
}

static clib_error_t *
ip6_link_show (vlib_main_t * vm,
	       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  const ip6_link_t *il;
  vnet_main_t *vnm;
  u32 sw_if_index;

  vnm = vnet_get_main ();
  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      il = ip6_link_get (sw_if_index);

      if (NULL == il)
	{
	  vlib_cli_output (vm, "IP6 disabled");
	  return (NULL);
	}
      else
	vlib_cli_output (vm, "%U", format_ip6_link, il);
    }
  else
    {
      vec_foreach (il, ip6_links)
	vlib_cli_output (vm, "%U", format_ip6_link, il);
    }

  return (NULL);
}

/*?
 * This command is used to display various IPv6 attributes on a given
 * interface.
 *
 * @cliexpar
 * Example of how to display IPv6 settings:
 * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
 * GigabitEthernet2/0/0 is admin up
 *         Link-local address(es):
 *                 fe80::ab8/64
 *         Joined group address(es):
 *                 ff02::1
 *                 ff02::2
 *                 ff02::16
 *                 ff02::1:ff00:ab8
 *         Advertised Prefixes:
 *                 prefix fe80::fe:28ff:fe9c:75b3,  length 64
 *         MTU is 1500
 *         ICMP error messages are unlimited
 *         ICMP redirects are disabled
 *         ICMP unreachables are not sent
 *         ND DAD is disabled
 *         ND advertised reachable time is 0
 *         ND advertised retransmit interval is 0 (msec)
 *         ND router advertisements are sent every 200 seconds (min interval is 150)
 *         ND router advertisements live for 600 seconds
 *         Hosts use stateless autoconfig for addresses
 *         ND router advertisements sent 19336
 *         ND router solicitations received 0
 *         ND router solicitations dropped 0
 * @cliexend
 * Example of output if IPv6 is not enabled on the interface:
 * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
 * show ip6 interface: IPv6 not enabled on interface
 * @cliexend
?*/
VLIB_CLI_COMMAND (ip6_link_show_command, static) =
{
  .path = "show ip6 interface",
  .function = ip6_link_show,
  .short_help = "show ip6 interface <interface>",
};

static clib_error_t *
enable_ip6_interface_cmd (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = NULL;
  u32 sw_if_index;

  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      if (ip6_link_enable (sw_if_index, NULL))
	error = clib_error_return (0, "Failed\n");
    }
  else
    {
      error = clib_error_return (0, "unknown interface\n'",
				 format_unformat_error, input);

    }
  return error;
}

/*?
 * This command is used to enable IPv6 on a given interface.
 *
 * @cliexpar
 * Example of how enable IPv6 on a given interface:
 * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
?*/
VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
{
  .path = "enable ip6 interface",
  .function = enable_ip6_interface_cmd,
  .short_help = "enable ip6 interface <interface>",
};

static clib_error_t *
disable_ip6_interface_cmd (vlib_main_t * vm,
			   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = NULL;
  u32 sw_if_index;

  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      if (ip6_link_disable (sw_if_index))
	error = clib_error_return (0, "Failed\n");
    }
  else
    {
      error = clib_error_return (0, "unknown interface\n'",
				 format_unformat_error, input);

    }
  return error;
}

/*?
 * This command is used to disable IPv6 on a given interface.
 *
 * @cliexpar
 * Example of how disable IPv6 on a given interface:
 * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
?*/
VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
{
  .path = "disable ip6 interface",
  .function = disable_ip6_interface_cmd,
  .short_help = "disable ip6 interface <interface>",
};

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