/*
 * 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/pg/pg.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/replication.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;
}

l2flood_main_t l2flood_main;

static vlib_node_registration_t l2flood_node;

#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.
 */
static uword
l2flood_node_fn (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)
	{
	  u32 next0, sw_if_index0, bi0, ci0;
	  u16 n_clones, n_cloned, clone0;
	  l2_bridge_domain_t *bd_config;
	  l2_flood_member_t *member;
	  vlib_buffer_t *b0, *c0;
	  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_DROP;

	  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;
	    }

	  vec_validate (msm->clones[thread_index], n_clones);
	  vec_reset_length (msm->clones[thread_index]);

	  /*
	   * the header offset needs to be large enoguh 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,
					(vnet_buffer (b0)->l2.l2_len +
					 sizeof (udp_header_t) +
					 2 * sizeof (ip6_header_t)));

	  if (PREDICT_FALSE (n_cloned != n_clones))
	    {
	      b0->error = node->errors[L2FLOOD_ERROR_REPL_FAIL];
	    }

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

		  if (c0 != b0)
		    vlib_buffer_copy_trace_flag (vm, b0, ci0);

		  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 (t->src, h0->src_address, 6);
		  clib_memcpy (t->dst, h0->dst_address, 6);
		}

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

	      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);
		}
	    }

	  /*
	   * the last clone that might go to a BVI
	   */
	  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;

	      if (c0 != b0)
		vlib_buffer_copy_trace_flag (vm, b0, ci0);

	      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 (t->src, h0->src_address, 6);
	      clib_memcpy (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))
		{
		  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];
		    }
		}
	    }
	  else
	    {
	      /* Do normal L2 forwarding */
	      vnet_buffer (c0)->sw_if_index[VLIB_TX] = member->sw_if_index;
	      next0 = L2FLOOD_NEXT_L2_OUTPUT;
	    }

	  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,static) = {
  .function = l2flood_node_fn,
  .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* */

VLIB_NODE_FUNCTION_MULTIARCH (l2flood_node, l2flood_node_fn)
     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);
}


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