/*
 * 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.
 */
/*
 * srp_interface.c: srp interfaces
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vnet/srp/srp.h>

static u8*
srp_build_rewrite (vnet_main_t * vnm,
		   u32 sw_if_index,
		   vnet_link_t link_type,
		   const void * dst_address)
{
  vnet_hw_interface_t * hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  srp_main_t * sm = &srp_main;
  srp_and_ethernet_header_t * h;
  u8* rewrite = NULL;
  u16 type;
  uword n_bytes = sizeof (h[0]);

  switch (link_type) {
#define _(a,b) case VNET_LINK_##a: type = ETHERNET_TYPE_##b; break
    _ (IP4, IP4);
    _ (IP6, IP6);
    _ (MPLS, MPLS);
    _ (ARP, ARP);
#undef _
  default:
      return (NULL);
  }

  vec_validate(rewrite, n_bytes-1);
  h = (srp_and_ethernet_header_t *)rewrite;

  clib_memcpy (h->ethernet.src_address, hw->hw_address, sizeof (h->ethernet.src_address));
  if (dst_address)
    clib_memcpy (h->ethernet.dst_address, dst_address, sizeof (h->ethernet.dst_address));
  else
    clib_memset (h->ethernet.dst_address, ~0, sizeof (h->ethernet.dst_address)); /* broadcast */

  h->ethernet.type = clib_host_to_net_u16 (type);

  h->srp.as_u16 = 0;
  h->srp.mode = SRP_MODE_data;
  h->srp.ttl = sm->default_data_ttl;
  srp_header_compute_parity (&h->srp);

  return (rewrite);
}

static void srp_register_interface_helper (u32 * hw_if_indices_by_side, u32 redistribute);

void serialize_srp_main (serialize_main_t * m, va_list * va)
{
  srp_main_t * sm = &srp_main;
  srp_interface_t * si;

  serialize_integer (m, pool_elts (sm->interface_pool), sizeof (u32));
  pool_foreach (si, sm->interface_pool, ({
    serialize_integer (m, si->rings[SRP_RING_OUTER].hw_if_index, sizeof (u32));
    serialize_integer (m, si->rings[SRP_RING_INNER].hw_if_index, sizeof (u32));
  }));
}

void unserialize_srp_main (serialize_main_t * m, va_list * va)
{
  u32 i, n_ifs, hw_if_indices[SRP_N_RING];

  unserialize_integer (m, &n_ifs, sizeof (u32));
  for (i = 0; i < n_ifs; i++)
    {
      unserialize_integer (m, &hw_if_indices[SRP_RING_OUTER], sizeof (u32));
      unserialize_integer (m, &hw_if_indices[SRP_RING_INNER], sizeof (u32));
      srp_register_interface_helper (hw_if_indices, /* redistribute */ 0);
    }
}

static void srp_register_interface_helper (u32 * hw_if_indices_by_side, u32 redistribute)
{
  vnet_main_t * vnm = vnet_get_main();
  srp_main_t * sm = &srp_main;
  srp_interface_t * si;
  vnet_hw_interface_t * hws[SRP_N_RING];
  uword s, * p;

  /* Check if interface has already been registered. */
  p = hash_get (sm->interface_index_by_hw_if_index, hw_if_indices_by_side[0]);
  if (p)
    {
      si = pool_elt_at_index (sm->interface_pool, p[0]);
    }
  else
    {
      pool_get (sm->interface_pool, si);
      clib_memset (si, 0, sizeof (si[0]));
    }
  for (s = 0; s < SRP_N_SIDE; s++)
    {
      hws[s] = vnet_get_hw_interface (vnm, hw_if_indices_by_side[s]);
      si->rings[s].ring = s;
      si->rings[s].hw_if_index = hw_if_indices_by_side[s];
      si->rings[s].sw_if_index = hws[s]->sw_if_index;
      hash_set (sm->interface_index_by_hw_if_index, hw_if_indices_by_side[s], si - sm->interface_pool);
    }

  /* Inherit MAC address from outer ring. */
  clib_memcpy (si->my_address, hws[SRP_RING_OUTER]->hw_address,
	  vec_len (hws[SRP_RING_OUTER]->hw_address));

  /* Default time to wait to restore signal. */
  si->config.wait_to_restore_idle_delay = 60;
  si->config.ips_tx_interval = 1;
}

void srp_register_interface (u32 * hw_if_indices_by_side)
{
  srp_register_interface_helper (hw_if_indices_by_side, /* redistribute */ 1);
}

void srp_interface_set_hw_wrap_function (u32 hw_if_index, srp_hw_wrap_function_t * f)
{
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);
  si->hw_wrap_function = f;
}

void srp_interface_set_hw_enable_function (u32 hw_if_index, srp_hw_enable_function_t * f)
{
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);
  si->hw_enable_function = f;
}

void srp_interface_enable_ips (u32 hw_if_index)
{
  srp_main_t * sm = &srp_main;
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);

  si->ips_process_enable = 1;

  vlib_node_set_state (sm->vlib_main, srp_ips_process_node.index, VLIB_NODE_STATE_POLLING);
}

static uword
srp_is_valid_class_for_interface (vnet_main_t * vnm, u32 hw_if_index, u32 hw_class_index)
{
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);

  if (! si)
    return 0;

  /* Both sides must be admin down. */
  if (vnet_sw_interface_is_admin_up (vnm, si->rings[SRP_RING_OUTER].sw_if_index))
    return 0;
  if (vnet_sw_interface_is_admin_up (vnm, si->rings[SRP_RING_INNER].sw_if_index))
    return 0;
					 
  return 1;
}

static void
srp_interface_hw_class_change (vnet_main_t * vnm, u32 hw_if_index,
			       u32 old_hw_class_index, u32 new_hw_class_index)
{
  srp_main_t * sm = &srp_main;
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);
  vnet_hw_interface_t * hi;
  vnet_device_class_t * dc;
  u32 r, to_srp;

  if (!si) {
      clib_warning ("srp interface no set si = 0");
      return;
  }

  to_srp = new_hw_class_index == srp_hw_interface_class.index;

  /* Changing class on either outer or inner rings implies changing the class
     of the other. */
  for (r = 0; r < SRP_N_RING; r++)
    {
      srp_interface_ring_t * ir = &si->rings[r];

      hi = vnet_get_hw_interface (vnm, ir->hw_if_index);
      dc = vnet_get_device_class (vnm, hi->dev_class_index);

      /* hw_if_index itself will be handled by caller. */
      if (ir->hw_if_index != hw_if_index)
	{
	  vnet_hw_interface_init_for_class (vnm, ir->hw_if_index,
					    new_hw_class_index,
					    to_srp ? si - sm->interface_pool : ~0);

	  if (dc->hw_class_change)
	    dc->hw_class_change (vnm, ir->hw_if_index, new_hw_class_index);
	}
      else
	hi->hw_instance = to_srp ? si - sm->interface_pool : ~0;
    }

  if (si->hw_enable_function)
    si->hw_enable_function (si, /* enable */ to_srp);
}

VNET_HW_INTERFACE_CLASS (srp_hw_interface_class) = {
  .name = "SRP",
  .format_address = format_ethernet_address,
  .format_header = format_srp_header_with_length,
  .format_device = format_srp_device,
  .unformat_hw_address = unformat_ethernet_address,
  .unformat_header = unformat_srp_header,
  .build_rewrite = srp_build_rewrite,
  .update_adjacency = ethernet_update_adjacency,
  .is_valid_class_for_interface = srp_is_valid_class_for_interface,
  .hw_class_change = srp_interface_hw_class_change,
};

void srp_interface_get_interface_config (u32 hw_if_index, srp_interface_config_t * c)
{
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);
  ASSERT (si != 0);
  c[0] = si->config;
}

void srp_interface_set_interface_config (u32 hw_if_index, srp_interface_config_t * c)
{
  srp_interface_t * si = srp_get_interface_from_vnet_hw_interface (hw_if_index);
  ASSERT (si != 0);
  if (memcmp (&si->config, &c[0], sizeof (c[0])))
    {
      si->config = c[0];
    }
}

#if DEBUG > 0

#define VNET_SIMULATED_SRP_TX_NEXT_SRP_INPUT VNET_INTERFACE_TX_N_NEXT
/* Echo packets back to srp input. */
static uword
simulated_srp_interface_tx (vlib_main_t * vm,
			    vlib_node_runtime_t * node,
			    vlib_frame_t * frame)
{
  u32 n_left_from, n_left_to_next, n_copy, * from, * to_next;
  u32 next_index = VNET_SIMULATED_SRP_TX_NEXT_SRP_INPUT;
  u32 i;
  vlib_buffer_t * b;

  n_left_from = frame->n_vectors;
  from = vlib_frame_vector_args (frame);

  while (n_left_from > 0)
    {
      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      n_copy = clib_min (n_left_from, n_left_to_next);

      clib_memcpy_fast (to_next, from, n_copy * sizeof (from[0]));
      n_left_to_next -= n_copy;
      n_left_from -= n_copy;
      for (i = 0; i < n_copy; i++)
	{
	  b = vlib_get_buffer (vm, from[i]);
	  /* TX interface will be fake eth; copy to RX for benefit of srp-input. */
	  b->sw_if_index[VLIB_RX] = b->sw_if_index[VLIB_TX];
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  return n_left_from;
}

static u8 * format_simulated_srp_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "fake-srp%d", dev_instance);
}

VNET_DEVICE_CLASS (srp_simulated_device_class,static) = {
  .name = "Simulated srp",
  .format_device_name = format_simulated_srp_name,
  .tx_function = simulated_srp_interface_tx,
};

static clib_error_t *
create_simulated_srp_interfaces (vlib_main_t * vm,
				 unformat_input_t * input,
				 vlib_cli_command_t * cmd)
{
  vnet_main_t * vnm = vnet_get_main();
  u8 address[6];
  u32 hw_if_index;
  vnet_hw_interface_t * hi;
  static u32 instance;

  if (! unformat_user (input, unformat_ethernet_address, &address))
    {
      clib_memset (address, 0, sizeof (address));
      address[0] = 0xde;
      address[1] = 0xad;
      address[5] = instance;
    }

  hw_if_index = vnet_register_interface (vnm,
					 srp_simulated_device_class.index,
					 instance++,
					 srp_hw_interface_class.index, 0);

  hi = vnet_get_hw_interface (vnm, hw_if_index);

  srp_setup_node (vm, hi->output_node_index);

  hi->min_packet_bytes = 40 + 16;

  /* Standard default ethernet MTU. */
  vnet_sw_interface_set_mtu (vnm, sw_if_index, 1500);

  vec_free (hi->hw_address);
  vec_add (hi->hw_address, address, sizeof (address));

  {
    uword slot;

    slot = vlib_node_add_named_next_with_slot
      (vm, hi->tx_node_index,
       "srp-input",
       VNET_SIMULATED_SRP_TX_NEXT_SRP_INPUT);
    ASSERT (slot == VNET_SIMULATED_SRP_TX_NEXT_SRP_INPUT);
  }

  return /* no error */ 0;
}

static VLIB_CLI_COMMAND (create_simulated_srp_interface_command) = {
  .path = "srp create-interfaces",
  .short_help = "Create simulated srp interface",
  .function = create_simulated_srp_interfaces,
};
#endif
