/*
 * l2_bvi.c : layer 2 Bridged Virtual Interface
 *
 * Copyright (c) 2013 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 <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/l2/l2_fwd.h>
#include <vnet/l2/l2_flood.h>
#include <vnet/l2/l2_bvi.h>

/* Allocated BVI instances */
static uword *l2_bvi_instances;

/* Call the L2 nodes that need the ethertype mapping */
void
l2bvi_register_input_type (vlib_main_t * vm,
			   ethernet_type_t type, u32 node_index)
{
  l2fwd_register_input_type (vm, type, node_index);
  l2flood_register_input_type (vm, type, node_index);
}

static u8 *
format_bvi_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "bvi%d", dev_instance);
}

static clib_error_t *
bvi_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
    VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
  return 0;
}

static clib_error_t *
bvi_mac_change (vnet_hw_interface_t * hi,
		const u8 * old_address, const u8 * mac_address)
{
  l2input_interface_mac_change (hi->sw_if_index, old_address, mac_address);

  return (NULL);
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (bvi_device_class) = {
  .name = "BVI",
  .format_device_name = format_bvi_name,
  .admin_up_down_function = bvi_admin_up_down,
  .mac_addr_change_function = bvi_mac_change,
};
/* *INDENT-ON* */

/*
 * Maintain a bitmap of allocated bvi instance numbers.
 */
#define BVI_MAX_INSTANCE		(16 * 1024)

static u32
bvi_instance_alloc (u32 want)
{
  /*
   * Check for dynamically allocaetd instance number.
   */
  if (~0 == want)
    {
      u32 bit;

      bit = clib_bitmap_first_clear (l2_bvi_instances);
      if (bit >= BVI_MAX_INSTANCE)
	{
	  return ~0;
	}
      l2_bvi_instances = clib_bitmap_set (l2_bvi_instances, bit, 1);
      return bit;
    }

  /*
   * In range?
   */
  if (want >= BVI_MAX_INSTANCE)
    {
      return ~0;
    }

  /*
   * Already in use?
   */
  if (clib_bitmap_get (l2_bvi_instances, want))
    {
      return ~0;
    }

  /*
   * Grant allocation request.
   */
  l2_bvi_instances = clib_bitmap_set (l2_bvi_instances, want, 1);

  return want;
}

static int
bvi_instance_free (u32 instance)
{
  if (instance >= BVI_MAX_INSTANCE)
    {
      return -1;
    }

  if (clib_bitmap_get (l2_bvi_instances, instance) == 0)
    {
      return -1;
    }

  l2_bvi_instances = clib_bitmap_set (l2_bvi_instances, instance, 0);
  return 0;
}

int
l2_bvi_create (u32 user_instance,
	       const mac_address_t * mac_in, u32 * sw_if_indexp)
{
  vnet_main_t *vnm = vnet_get_main ();
  vlib_main_t *vm = vlib_get_main ();
  u32 instance, hw_if_index, slot;
  vnet_hw_interface_t *hw_if;
  clib_error_t *error;
  mac_address_t mac;

  int rv = 0;

  ASSERT (sw_if_indexp);

  *sw_if_indexp = (u32) ~ 0;

  /*
   * Allocate a bvi instance.  Either select on dynamically
   * or try to use the desired user_instance number.
   */
  instance = bvi_instance_alloc (user_instance);
  if (instance == ~0)
    {
      return VNET_API_ERROR_INVALID_REGISTRATION;
    }

  /*
   * Default MAC address (b0b0:0000:0000 + instance) is allocated
   * if zero mac_address is configured. Otherwise, user-configurable MAC
   * address is programmed on the bvi interface.
   */
  if (mac_address_is_zero (mac_in))
    {
      u8 bytes[] = {
	[0] = 0xb0,
	[1] = 0xb0,
	[5] = instance,
      };
      mac_address_from_bytes (&mac, bytes);
    }
  else
    {
      mac_address_copy (&mac, mac_in);
    }

  error = ethernet_register_interface (vnm,
				       bvi_device_class.index,
				       instance, mac.bytes, &hw_if_index,
				       /* flag change */ 0);

  if (error)
    {
      rv = VNET_API_ERROR_INVALID_REGISTRATION;
      clib_error_report (error);
      return rv;
    }

  hw_if = vnet_get_hw_interface (vnm, hw_if_index);

  slot = vlib_node_add_named_next_with_slot (vm, hw_if->tx_node_index,
					     "l2-input", 0);
  ASSERT (slot == 0);

  {
    vnet_sw_interface_t *si = vnet_get_hw_sw_interface (vnm, hw_if_index);
    *sw_if_indexp = si->sw_if_index;

    si->flood_class = VNET_FLOOD_CLASS_BVI;
  }

  return 0;
}

int
l2_bvi_delete (u32 sw_if_index)
{
  vnet_main_t *vnm = vnet_get_main ();

  if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  if (hw == 0 || hw->dev_class_index != bvi_device_class.index)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  if (bvi_instance_free (hw->dev_instance) < 0)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  ethernet_delete_interface (vnm, hw->hw_if_index);

  return 0;
}

static clib_error_t *
l2_bvi_create_cli (vlib_main_t * vm,
		   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 instance, sw_if_index;
  clib_error_t *error;
  mac_address_t mac;
  int rv;

  error = NULL;
  instance = sw_if_index = ~0;
  mac_address_set_zero (&mac);

  if (unformat_user (input, unformat_line_input, line_input))
    {
      while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
	{
	  if (unformat (line_input, "mac %U", unformat_mac_address_t, &mac))
	    ;
	  else if (unformat (line_input, "instance %d", &instance))
	    ;
	  else
	    {
	      error = clib_error_return (0, "unknown input: %U",
					 format_unformat_error, line_input);
	      break;
	    }
	}

      unformat_free (line_input);

      if (error)
	return error;
    }

  rv = l2_bvi_create (instance, &mac, &sw_if_index);

  if (rv)
    return clib_error_return (0, "BVI create failed");

  vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main (),
		   sw_if_index);
  return 0;
}

/*?
 * Create a BVI interface. Optionally, a MAC Address can be
 * provided. If not provided, 0b:0b::00:00:00:<instance> will be used.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{bvi create [mac <mac-addr>] [instance <instance>]}
 * Example of how to create a bvi interface:
 * @cliexcmd{bvi create}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_bvi_create_command, static) = {
  .path = "bvi create",
  .short_help = "bvi create [mac <mac-addr>] [instance <instance>]",
  .function = l2_bvi_create_cli,
};
/* *INDENT-ON* */

static clib_error_t *
l2_bvi_delete_cli (vlib_main_t * vm,
		   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm;
  u32 sw_if_index;
  int rv;

  vnm = vnet_get_main ();
  sw_if_index = ~0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
	;
      else
	break;
    }

  if (~0 != sw_if_index)
    {
      rv = l2_bvi_delete (sw_if_index);

      if (rv)
	return clib_error_return (0, "BVI delete failed");
    }
  else
    return clib_error_return (0, "no such interface: %U",
			      format_unformat_error, input);

  return 0;
}

/*?
 * Delete a BVI interface.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{bvi delete <interace>
 * Example of how to create a bvi interface:
 * @cliexcmd{bvi delete bvi0}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (l2_bvi_delete_command, static) = {
  .path = "bvi delete",
  .short_help = "bvi delete <interface>",
  .function = l2_bvi_delete_cli,
};
/* *INDENT-ON* */


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