/*
 * 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.
 */

#include <vlib/vlib.h>
#include <vppinfra/error.h>
#include <vnet/feature/feature.h>
#include <vnet/l2/l2_input.h>
#include <vnet/l2/l2_output.h>

#include <vnet/span/span.h>

span_main_t span_main;

typedef enum
{
  SPAN_DISABLE = 0,
  SPAN_RX = 1,
  SPAN_TX = 2,
  SPAN_BOTH = SPAN_RX | SPAN_TX
} span_state_t;

static_always_inline u32
span_dst_set (span_mirror_t * sm, u32 dst_sw_if_index, int enable)
{
  if (dst_sw_if_index == ~0)
    {
      ASSERT (enable == 0);
      clib_bitmap_zero (sm->mirror_ports);
    }
  else
    sm->mirror_ports =
      clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);

  u32 last = sm->num_mirror_ports;
  sm->num_mirror_ports = clib_bitmap_count_set_bits (sm->mirror_ports);
  return last;
}

int
span_add_delete_entry (vlib_main_t * vm,
		       u32 src_sw_if_index, u32 dst_sw_if_index, u8 state,
		       span_feat_t sf)
{
  span_main_t *sm = &span_main;

  if (state > SPAN_BOTH)
    return VNET_API_ERROR_UNIMPLEMENTED;

  if ((src_sw_if_index == ~0) || (dst_sw_if_index == ~0 && state > 0)
      || (src_sw_if_index == dst_sw_if_index))
    return VNET_API_ERROR_INVALID_INTERFACE;

  vec_validate_aligned (sm->interfaces, src_sw_if_index,
			CLIB_CACHE_LINE_BYTES);

  span_interface_t *si = vec_elt_at_index (sm->interfaces, src_sw_if_index);

  int rx = ! !(state & SPAN_RX);
  int tx = ! !(state & SPAN_TX);

  span_mirror_t *rxm = &si->mirror_rxtx[sf][VLIB_RX];
  span_mirror_t *txm = &si->mirror_rxtx[sf][VLIB_TX];

  u32 last_rx_ports_count = span_dst_set (rxm, dst_sw_if_index, rx);
  u32 last_tx_ports_count = span_dst_set (txm, dst_sw_if_index, tx);

  int enable_rx = last_rx_ports_count == 0 && rxm->num_mirror_ports == 1;
  int disable_rx = last_rx_ports_count > 0 && rxm->num_mirror_ports == 0;
  int enable_tx = last_tx_ports_count == 0 && txm->num_mirror_ports == 1;
  int disable_tx = last_tx_ports_count > 0 && txm->num_mirror_ports == 0;

  switch (sf)
    {
    case SPAN_FEAT_DEVICE:
      if (enable_rx || disable_rx)
	vnet_feature_enable_disable ("device-input", "span-input",
				     src_sw_if_index, rx, 0, 0);
      if (enable_rx || disable_rx)
	vnet_feature_enable_disable ("port-rx-eth", "span-input",
				     src_sw_if_index, rx, 0, 0);
      if (enable_tx || disable_tx)
	vnet_feature_enable_disable ("interface-output", "span-output",
				     src_sw_if_index, tx, 0, 0);
      break;
    case SPAN_FEAT_L2:
      if (enable_rx || disable_rx)
	l2input_intf_bitmap_enable (src_sw_if_index, L2INPUT_FEAT_SPAN, rx);
      if (enable_tx || disable_tx)
	l2output_intf_bitmap_enable (src_sw_if_index, L2OUTPUT_FEAT_SPAN, tx);
      break;
    default:
      return VNET_API_ERROR_UNIMPLEMENTED;
    }

  if (dst_sw_if_index != ~0 && dst_sw_if_index > sm->max_sw_if_index)
    sm->max_sw_if_index = dst_sw_if_index;

  return 0;
}

static uword
unformat_span_state (unformat_input_t * input, va_list * args)
{
  span_state_t *state = va_arg (*args, span_state_t *);
  if (unformat (input, "disable"))
    *state = SPAN_DISABLE;
  else if (unformat (input, "rx"))
    *state = SPAN_RX;
  else if (unformat (input, "tx"))
    *state = SPAN_TX;
  else if (unformat (input, "both"))
    *state = SPAN_BOTH;
  else
    return 0;
  return 1;
}

static clib_error_t *
set_interface_span_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  span_main_t *sm = &span_main;
  u32 src_sw_if_index = ~0;
  u32 dst_sw_if_index = ~0;
  span_feat_t sf = SPAN_FEAT_DEVICE;
  span_state_t state = SPAN_BOTH;
  int state_set = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_vnet_sw_interface,
		    sm->vnet_main, &src_sw_if_index))
	;
      else if (unformat (input, "destination %U", unformat_vnet_sw_interface,
			 sm->vnet_main, &dst_sw_if_index))
	;
      else if (unformat (input, "%U", unformat_span_state, &state))
	{
	  if (state_set)
	    return clib_error_return (0, "Multiple mirror states in input");
	  state_set = 1;
	}
      else if (unformat (input, "l2"))
	sf = SPAN_FEAT_L2;
      else
	return clib_error_return (0, "Invalid input");
    }

  int rv =
    span_add_delete_entry (vm, src_sw_if_index, dst_sw_if_index, state, sf);
  if (rv == VNET_API_ERROR_INVALID_INTERFACE)
    return clib_error_return (0, "Invalid interface");
  return 0;
}

VLIB_CLI_COMMAND (set_interface_span_command, static) = {
  .path = "set interface span",
  .short_help = "set interface span <if-name> [l2] {disable | destination <if-name> [both|rx|tx]}",
  .function = set_interface_span_command_fn,
};

static clib_error_t *
show_interfaces_span_command_fn (vlib_main_t * vm,
				 unformat_input_t * input,
				 vlib_cli_command_t * cmd)
{
  span_main_t *sm = &span_main;
  span_interface_t *si;
  vnet_main_t *vnm = &vnet_main;
  u8 header = 1;
  static const char *states[] = {
    [SPAN_DISABLE] = "none",
    [SPAN_RX] = "rx",
    [SPAN_TX] = "tx",
    [SPAN_BOTH] = "both"
  };
  u8 *s = 0;

  vec_foreach (si, sm->interfaces)
  {
  span_mirror_t * drxm = &si->mirror_rxtx[SPAN_FEAT_DEVICE][VLIB_RX];
  span_mirror_t * dtxm = &si->mirror_rxtx[SPAN_FEAT_DEVICE][VLIB_TX];

  span_mirror_t * lrxm = &si->mirror_rxtx[SPAN_FEAT_L2][VLIB_RX];
  span_mirror_t * ltxm = &si->mirror_rxtx[SPAN_FEAT_L2][VLIB_TX];

    if (drxm->num_mirror_ports || dtxm->num_mirror_ports ||
        lrxm->num_mirror_ports || ltxm->num_mirror_ports)
      {
	u32 i;
	clib_bitmap_t *d = clib_bitmap_dup_or (drxm->mirror_ports, dtxm->mirror_ports);
	clib_bitmap_t *l = clib_bitmap_dup_or (lrxm->mirror_ports, ltxm->mirror_ports);
	clib_bitmap_t *b = clib_bitmap_dup_or (d, l);
	if (header)
	  {
	    vlib_cli_output (vm, "%-32s %-32s  %6s   %6s", "Source", "Destination",
			     "Device", "L2");
	    header = 0;
	  }
	s = format (s, "%U", format_vnet_sw_if_index_name, vnm,
		    si - sm->interfaces);
	clib_bitmap_foreach (i, b)
	  {
	    int device = (clib_bitmap_get (drxm->mirror_ports, i) +
		         clib_bitmap_get (dtxm->mirror_ports, i) * 2);
	    int l2 = (clib_bitmap_get (lrxm->mirror_ports, i) +
		      clib_bitmap_get (ltxm->mirror_ports, i) * 2);

	    vlib_cli_output (vm, "%-32v %-32U (%6s) (%6s)", s,
			     format_vnet_sw_if_index_name, vnm, i,
			     states[device], states[l2]);
	    vec_reset_length (s);
	  }
	clib_bitmap_free (b);
	clib_bitmap_free (l);
	clib_bitmap_free (d);
      }
      }
  vec_free (s);
  return 0;
}

VLIB_CLI_COMMAND (show_interfaces_span_command, static) = {
  .path = "show interface span",
  .short_help = "Shows SPAN mirror table",
  .function = show_interfaces_span_command_fn,
};

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