/*
 * 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.
 */
/*
 * snap_node.c: snap packet processing
 *
 * Copyright (c) 2010 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 <vlib/vlib.h>
#include <vnet/pg/pg.h>
#include <vnet/llc/llc.h>
#include <vnet/snap/snap.h>

typedef enum
{
  SNAP_INPUT_NEXT_DROP,
  SNAP_INPUT_NEXT_PUNT,
  SNAP_INPUT_NEXT_ETHERNET_TYPE,
  SNAP_INPUT_N_NEXT,
} snap_input_next_t;

typedef struct
{
  u8 packet_data[32];
} snap_input_trace_t;

static u8 *
format_snap_input_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
  snap_input_trace_t *t = va_arg (*va, snap_input_trace_t *);

  s = format (s, "%U", format_snap_header, t->packet_data);

  return s;
}

static uword
snap_input (vlib_main_t * vm,
	    vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  snap_main_t *sm = &snap_main;
  u32 n_left_from, next_index, *from, *to_next;

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

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vlib_trace_frame_buffers_only (vm, node,
				   from,
				   n_left_from,
				   sizeof (from[0]),
				   sizeof (snap_input_trace_t));

  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 >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  vlib_buffer_t *b0, *b1;
	  snap_header_t *h0, *h1;
	  snap_protocol_info_t *pi0, *pi1;
	  u8 next0, next1, is_ethernet0, is_ethernet1, len0, len1,
	    enqueue_code;
	  u32 oui0, oui1;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *b2, *b3;

	    b2 = vlib_get_buffer (vm, from[2]);
	    b3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (b2, LOAD);
	    vlib_prefetch_buffer_header (b3, LOAD);

	    CLIB_PREFETCH (b2->data, sizeof (h0[0]), LOAD);
	    CLIB_PREFETCH (b3->data, sizeof (h1[0]), LOAD);
	  }

	  bi0 = from[0];
	  bi1 = from[1];
	  to_next[0] = bi0;
	  to_next[1] = bi1;
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);

	  h0 = vlib_buffer_get_current (b0);
	  h1 = vlib_buffer_get_current (b1);

	  oui0 = snap_header_get_oui (h0);
	  oui1 = snap_header_get_oui (h1);

	  is_ethernet0 = oui0 == IEEE_OUI_ethernet;
	  is_ethernet1 = oui1 == IEEE_OUI_ethernet;

	  len0 = sizeof (h0[0]) - (is_ethernet0 ? sizeof (h0->protocol) : 0);
	  len1 = sizeof (h1[0]) - (is_ethernet1 ? sizeof (h1->protocol) : 0);

	  vlib_buffer_advance (b0, len0);
	  vlib_buffer_advance (b1, len1);

	  pi0 = snap_get_protocol_info (sm, h0);
	  pi1 = snap_get_protocol_info (sm, h1);

	  next0 = pi0 ? pi0->next_index : SNAP_INPUT_NEXT_DROP;
	  next1 = pi1 ? pi1->next_index : SNAP_INPUT_NEXT_DROP;

	  next0 = is_ethernet0 ? SNAP_INPUT_NEXT_ETHERNET_TYPE : next0;
	  next1 = is_ethernet1 ? SNAP_INPUT_NEXT_ETHERNET_TYPE : next1;

	  /* In case of error. */
	  b0->error = node->errors[SNAP_ERROR_UNKNOWN_PROTOCOL];
	  b1->error = node->errors[SNAP_ERROR_UNKNOWN_PROTOCOL];

	  enqueue_code = (next0 != next_index) + 2 * (next1 != next_index);

	  if (PREDICT_FALSE (enqueue_code != 0))
	    {
	      switch (enqueue_code)
		{
		case 1:
		  /* A B A */
		  to_next[-2] = bi1;
		  to_next -= 1;
		  n_left_to_next += 1;
		  vlib_set_next_frame_buffer (vm, node, next0, bi0);
		  break;

		case 2:
		  /* A A B */
		  to_next -= 1;
		  n_left_to_next += 1;
		  vlib_set_next_frame_buffer (vm, node, next1, bi1);
		  break;

		case 3:
		  /* A B B or A B C */
		  to_next -= 2;
		  n_left_to_next += 2;
		  vlib_set_next_frame_buffer (vm, node, next0, bi0);
		  vlib_set_next_frame_buffer (vm, node, next1, bi1);
		  if (next0 == next1)
		    {
		      vlib_put_next_frame (vm, node, next_index,
					   n_left_to_next);
		      next_index = next1;
		      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 bi0;
	  vlib_buffer_t *b0;
	  snap_header_t *h0;
	  snap_protocol_info_t *pi0;
	  u8 next0, is_ethernet0, len0;
	  u32 oui0;

	  bi0 = from[0];
	  to_next[0] = bi0;
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  b0 = vlib_get_buffer (vm, bi0);

	  h0 = vlib_buffer_get_current (b0);

	  oui0 = snap_header_get_oui (h0);

	  is_ethernet0 = oui0 == IEEE_OUI_ethernet;

	  len0 = sizeof (h0[0]) - (is_ethernet0 ? sizeof (h0->protocol) : 0);

	  vlib_buffer_advance (b0, len0);

	  pi0 = snap_get_protocol_info (sm, h0);

	  next0 = pi0 ? pi0->next_index : SNAP_INPUT_NEXT_DROP;

	  next0 = is_ethernet0 ? SNAP_INPUT_NEXT_ETHERNET_TYPE : next0;

	  /* In case of error. */
	  b0->error = node->errors[SNAP_ERROR_UNKNOWN_PROTOCOL];

	  /* Sent packet to wrong next? */
	  if (PREDICT_FALSE (next0 != next_index))
	    {
	      /* Return old frame; remove incorrectly enqueued packet. */
	      vlib_put_next_frame (vm, node, next_index, n_left_to_next + 1);

	      /* Send to correct next. */
	      next_index = next0;
	      vlib_get_next_frame (vm, node, next_index,
				   to_next, n_left_to_next);

	      to_next[0] = bi0;
	      to_next += 1;
	      n_left_to_next -= 1;
	    }
	}

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

  return from_frame->n_vectors;
}

static char *snap_error_strings[] = {
#define _(f,s) s,
  foreach_snap_error
#undef _
};

VLIB_REGISTER_NODE (snap_input_node) = {
  .function = snap_input,
  .name = "snap-input",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .n_errors = SNAP_N_ERROR,
  .error_strings = snap_error_strings,

  .n_next_nodes = SNAP_INPUT_N_NEXT,
  .next_nodes = {
    [SNAP_INPUT_NEXT_DROP] = "error-drop",
    [SNAP_INPUT_NEXT_PUNT] = "error-punt",
    [SNAP_INPUT_NEXT_ETHERNET_TYPE] = "ethernet-input-type",
  },

  .format_buffer = format_snap_header_with_length,
  .format_trace = format_snap_input_trace,
  .unformat_buffer = unformat_snap_header,
};

static void
snap_setup_node (vlib_main_t *vm, u32 node_index)
{
  vlib_node_t *n = vlib_get_node (vm, node_index);
  pg_node_t *pn = pg_get_node (node_index);

  n->format_buffer = format_snap_header_with_length;
  n->unformat_buffer = unformat_snap_header;
  pn->unformat_edit = unformat_pg_snap_header;
}

static clib_error_t *
snap_input_init (vlib_main_t * vm)
{
  {
    clib_error_t *error = vlib_call_init_function (vm, snap_init);
    if (error)
      clib_error_report (error);
  }

  snap_setup_node (vm, snap_input_node.index);

  llc_register_input_protocol (vm, LLC_PROTOCOL_snap, snap_input_node.index);

  return 0;
}

VLIB_INIT_FUNCTION (snap_input_init);

void
snap_register_input_protocol (vlib_main_t * vm,
			      char *name,
			      u32 ieee_oui, u16 protocol, u32 node_index)
{
  snap_main_t *sm = &snap_main;
  snap_protocol_info_t *pi;
  snap_header_t h;
  snap_oui_and_protocol_t key;

  {
    clib_error_t *error = vlib_call_init_function (vm, snap_input_init);
    if (error)
      clib_error_report (error);
  }

  h.protocol = clib_host_to_net_u16 (protocol);
  h.oui[0] = (ieee_oui >> 16) & 0xff;
  h.oui[1] = (ieee_oui >> 8) & 0xff;
  h.oui[2] = (ieee_oui >> 0) & 0xff;
  pi = snap_get_protocol_info (sm, &h);
  if (pi)
    return;

  vec_add2 (sm->protocols, pi, 1);

  pi->name = format (0, "%s", name);
  pi->node_index = node_index;
  pi->next_index = vlib_node_add_next (vm, snap_input_node.index, node_index);

  key.oui = ieee_oui;
  key.protocol = clib_host_to_net_u16 (protocol);

  mhash_set (&sm->protocol_hash, &key, pi - sm->protocols, /* old_value */ 0);
  hash_set_mem (sm->protocol_info_by_name, name, pi - sm->protocols);
}

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