/*
 * l2_flood.c : layer 2 flooding
 *
 * 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/ethernet/ethernet.h>
#include <vlib/cli.h>
#include <vnet/l2/l2_input.h>
#include <vnet/l2/feat_bitmap.h>
#include <vnet/l2/l2_bvi.h>
#include <vnet/l2/l2_fib.h>

#include <vppinfra/error.h>
#include <vppinfra/hash.h>


/**
 * @file
 * @brief Ethernet Flooding.
 *
 * Flooding uses the packet replication infrastructure to send a copy of the
 * packet to each member interface. Logically the replication infrastructure
 * expects two graph nodes: a prep node that initiates replication and sends the
 * packet to the first destination, and a recycle node that is passed the packet
 * after it has been transmitted.
 *
 * To decrease the amount of code, l2 flooding implements both functions in
 * the same graph node. This node can tell if is it being called as the "prep"
 * or "recycle" using replication_is_recycled().
 */


typedef struct
{

  /* Next nodes for each feature */
  u32 feat_next_node_index[32];

  /* next node index for the L3 input node of each ethertype */
  next_by_ethertype_t l3_next;

  /* convenience variables */
  vlib_main_t *vlib_main;
  vnet_main_t *vnet_main;

  /* per-cpu vector of cloned packets */
  u32 **clones;
  l2_flood_member_t ***members;
} l2flood_main_t;

typedef struct
{
  u8 src[6];
  u8 dst[6];
  u32 sw_if_index;
  u16 bd_index;
} l2flood_trace_t;


/* packet trace format function */
static u8 *
format_l2flood_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  l2flood_trace_t *t = va_arg (*args, l2flood_trace_t *);

  s = format (s, "l2-flood: sw_if_index %d dst %U src %U bd_index %d",
	      t->sw_if_index,
	      format_ethernet_address, t->dst,
	      format_ethernet_address, t->src, t->bd_index);
  return s;
}

extern l2flood_main_t l2flood_main;

#ifndef CLIB_MARCH_VARIANT
l2flood_main_t l2flood_main;
#endif /* CLIB_MARCH_VARIANT */

#define foreach_l2flood_error					\
_(L2FLOOD,           "L2 flood packets")			\
_(REPL_FAIL,         "L2 replication failures")			\
_(NO_MEMBERS,        "L2 replication complete")			\
_(BVI_BAD_MAC,       "BVI L3 mac mismatch")		        \
_(BVI_ETHERTYPE,     "BVI packet with unhandled ethertype")

typedef enum
{
#define _(sym,str) L2FLOOD_ERROR_##sym,
  foreach_l2flood_error
#undef _
    L2FLOOD_N_ERROR,
} l2flood_error_t;

static char *l2flood_error_strings[] = {
#define _(sym,string) string,
  foreach_l2flood_error
#undef _
};

typedef enum
{
  L2FLOOD_NEXT_L2_OUTPUT,
  L2FLOOD_NEXT_DROP,
  L2FLOOD_N_NEXT,
} l2flood_next_t;

/*
 * Perform flooding on one packet
 *
 * Due to the way BVI processing can modify the packet, the BVI interface
 * (if present) must be processed last in the replication. The member vector
 * is arranged so that the BVI interface is always the first element.
 * Flooding walks the vector in reverse.
 *
 * BVI processing causes the packet to go to L3 processing. This strips the
 * L2 header, which is fine because the replication infrastructure restores
 * it. However L3 processing can trigger larger changes to the packet. For
 * example, an ARP request could be turned into an ARP reply, an ICMP request
 * could be turned into an ICMP reply. If BVI processing is not performed
 * last, the modified packet would be replicated to the remaining members.
 */
VLIB_NODE_FN (l2flood_node) (vlib_main_t * vm,
			     vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left_from, *from, *to_next;
  l2flood_next_t next_index;
  l2flood_main_t *msm = &l2flood_main;
  u32 thread_index = vm->thread_index;

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;
  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u16 n_clones, n_cloned, clone0;
	  l2_bridge_domain_t *bd_config;
	  u32 sw_if_index0, bi0, ci0;
	  l2_flood_member_t *member;
	  vlib_buffer_t *b0, *c0;
	  u16 next0;
	  u8 in_shg;
	  i32 mi;

	  /* speculatively enqueue b0 to the current next frame */
	  bi0 = from[0];
	  from += 1;
	  n_left_from -= 1;
	  next0 = L2FLOOD_NEXT_L2_OUTPUT;

	  b0 = vlib_get_buffer (vm, bi0);

	  /* Get config for the bridge domain interface */
	  bd_config = vec_elt_at_index (l2input_main.bd_configs,
					vnet_buffer (b0)->l2.bd_index);
	  in_shg = vnet_buffer (b0)->l2.shg;
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];

	  vec_validate (msm->members[thread_index],
			vec_len (bd_config->members));

	  vec_reset_length (msm->members[thread_index]);

	  /* Find first members that passes the reflection and SHG checks */
	  for (mi = bd_config->flood_count - 1; mi >= 0; mi--)
	    {
	      member = &bd_config->members[mi];
	      if ((member->sw_if_index != sw_if_index0) &&
		  (!in_shg || (member->shg != in_shg)))
		{
		  vec_add1 (msm->members[thread_index], member);
		}
	    }

	  n_clones = vec_len (msm->members[thread_index]);

	  if (0 == n_clones)
	    {
	      /* No members to flood to */
	      to_next[0] = bi0;
	      to_next += 1;
	      n_left_to_next -= 1;

	      b0->error = node->errors[L2FLOOD_ERROR_NO_MEMBERS];
	      vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					       to_next, n_left_to_next,
					       bi0, L2FLOOD_NEXT_DROP);
	      continue;
	    }
	  else if (n_clones > 1)
	    {
	      vec_validate (msm->clones[thread_index], n_clones);

	      /*
	       * the header offset needs to be large enough to incorporate
	       * all the L3 headers that could be touched when doing BVI
	       * processing. So take the current l2 length plus 2 * IPv6
	       * headers (for tunnel encap)
	       */
	      n_cloned = vlib_buffer_clone (vm, bi0,
					    msm->clones[thread_index],
					    n_clones,
					    VLIB_BUFFER_CLONE_HEAD_SIZE);

	      vec_set_len (msm->clones[thread_index], n_cloned);

	      if (PREDICT_FALSE (n_cloned != n_clones))
		{
		  b0->error = node->errors[L2FLOOD_ERROR_REPL_FAIL];
		  /* Worst-case, no clones, consume the original buf */
		  if (n_cloned == 0)
		    {
		      ci0 = bi0;
		      member = msm->members[thread_index][0];
		      goto use_original_buffer;
		    }
		}

	      /*
	       * for all but the last clone, these are not BVI bound
	       */
	      for (clone0 = 0; clone0 < n_cloned - 1; clone0++)
		{
		  member = msm->members[thread_index][clone0];
		  ci0 = msm->clones[thread_index][clone0];
		  c0 = vlib_get_buffer (vm, ci0);

		  to_next[0] = ci0;
		  to_next += 1;
		  n_left_to_next -= 1;

		  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
				     (b0->flags & VLIB_BUFFER_IS_TRACED)))
		    {
		      ethernet_header_t *h0;
		      l2flood_trace_t *t;

		      t = vlib_add_trace (vm, node, c0, sizeof (*t));
		      h0 = vlib_buffer_get_current (c0);
		      t->sw_if_index = sw_if_index0;
		      t->bd_index = vnet_buffer (c0)->l2.bd_index;
		      clib_memcpy_fast (t->src, h0->src_address, 6);
		      clib_memcpy_fast (t->dst, h0->dst_address, 6);
		    }

		  /* Do normal L2 forwarding */
		  vnet_buffer (c0)->sw_if_index[VLIB_TX] =
		    member->sw_if_index;

		  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
						   to_next, n_left_to_next,
						   ci0, next0);
		  if (PREDICT_FALSE (0 == n_left_to_next))
		    {
		      vlib_put_next_frame (vm, node, next_index,
					   n_left_to_next);
		      vlib_get_next_frame (vm, node, next_index, to_next,
					   n_left_to_next);
		    }
		}
	      member = msm->members[thread_index][clone0];
	      ci0 = msm->clones[thread_index][clone0];
	    }
	  else
	    {
	      /* one clone */
	      ci0 = bi0;
	      member = msm->members[thread_index][0];
	    }

	use_original_buffer:
	  /*
	   * the last clone that might go to a BVI
	   */
	  c0 = vlib_get_buffer (vm, ci0);

	  to_next[0] = ci0;
	  to_next += 1;
	  n_left_to_next -= 1;

	  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
			     (b0->flags & VLIB_BUFFER_IS_TRACED)))
	    {
	      ethernet_header_t *h0;
	      l2flood_trace_t *t;

	      t = vlib_add_trace (vm, node, c0, sizeof (*t));
	      h0 = vlib_buffer_get_current (c0);
	      t->sw_if_index = sw_if_index0;
	      t->bd_index = vnet_buffer (c0)->l2.bd_index;
	      clib_memcpy_fast (t->src, h0->src_address, 6);
	      clib_memcpy_fast (t->dst, h0->dst_address, 6);
	    }
	  /* Forward packet to the current member */
	  if (PREDICT_FALSE (member->flags & L2_FLOOD_MEMBER_BVI))
	    {
	      /* Do BVI processing */
	      u32 rc;
	      rc = l2_to_bvi (vm,
			      msm->vnet_main,
			      c0, member->sw_if_index, &msm->l3_next, &next0);

	      if (PREDICT_FALSE (rc != TO_BVI_ERR_OK))
		{
		  if (rc == TO_BVI_ERR_BAD_MAC)
		    {
		      c0->error = node->errors[L2FLOOD_ERROR_BVI_BAD_MAC];
		    }
		  else if (rc == TO_BVI_ERR_ETHERTYPE)
		    {
		      c0->error = node->errors[L2FLOOD_ERROR_BVI_ETHERTYPE];
		    }
		  next0 = L2FLOOD_NEXT_DROP;
		}
	    }
	  else
	    {
	      /* Do normal L2 forwarding */
	      vnet_buffer (c0)->sw_if_index[VLIB_TX] = member->sw_if_index;
	    }

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   ci0, next0);
	  if (PREDICT_FALSE (0 == n_left_to_next))
	    {
	      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
	      vlib_get_next_frame (vm, node, next_index,
				   to_next, n_left_to_next);
	    }
	}

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

  vlib_node_increment_counter (vm, node->node_index,
			       L2FLOOD_ERROR_L2FLOOD, frame->n_vectors);

  return frame->n_vectors;
}


/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2flood_node) = {
  .name = "l2-flood",
  .vector_size = sizeof (u32),
  .format_trace = format_l2flood_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(l2flood_error_strings),
  .error_strings = l2flood_error_strings,

  .n_next_nodes = L2FLOOD_N_NEXT,

  /* edit / add dispositions here */
  .next_nodes = {
        [L2FLOOD_NEXT_L2_OUTPUT] = "l2-output",
        [L2FLOOD_NEXT_DROP] = "error-drop",
  },
};
/* *INDENT-ON* */

#ifndef CLIB_MARCH_VARIANT
clib_error_t *
l2flood_init (vlib_main_t * vm)
{
  l2flood_main_t *mp = &l2flood_main;

  mp->vlib_main = vm;
  mp->vnet_main = vnet_get_main ();

  vec_validate (mp->clones, vlib_num_workers ());
  vec_validate (mp->members, vlib_num_workers ());

  /* Initialize the feature next-node indexes */
  feat_bitmap_init_next_nodes (vm,
			       l2flood_node.index,
			       L2INPUT_N_FEAT,
			       l2input_get_feat_names (),
			       mp->feat_next_node_index);

  return NULL;
}

VLIB_INIT_FUNCTION (l2flood_init);



/** Add the L3 input node for this ethertype to the next nodes structure. */
void
l2flood_register_input_type (vlib_main_t * vm,
			     ethernet_type_t type, u32 node_index)
{
  l2flood_main_t *mp = &l2flood_main;
  u32 next_index;

  next_index = vlib_node_add_next (vm, l2flood_node.index, node_index);

  next_by_ethertype_register (&mp->l3_next, type, next_index);
}
#endif /* CLIB_MARCH_VARIANT */


/**
 * Set subinterface flood enable/disable.
 * The CLI format is:
 * set interface l2 flood <interface> [disable]
 */
static clib_error_t *
int_flood (vlib_main_t * vm,
	   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = 0;
  u32 sw_if_index;
  u32 enable;

  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      error = clib_error_return (0, "unknown interface `%U'",
				 format_unformat_error, input);
      goto done;
    }

  enable = 1;
  if (unformat (input, "disable"))
    {
      enable = 0;
    }

  /* set the interface flag */
  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_FLOOD, enable);

done:
  return error;
}

/*?
 * Layer 2 flooding can be enabled and disabled on each
 * interface and on each bridge-domain. Use this command to
 * manage interfaces. It is enabled by default.
 *
 * @cliexpar
 * Example of how to enable flooding:
 * @cliexcmd{set interface l2 flood GigabitEthernet0/8/0}
 * Example of how to disable flooding:
 * @cliexcmd{set interface l2 flood GigabitEthernet0/8/0 disable}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (int_flood_cli, static) = {
  .path = "set interface l2 flood",
  .short_help = "set interface l2 flood <interface> [disable]",
  .function = int_flood,
};
/* *INDENT-ON* */

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