/*
 * Copyright (c) 2018 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.
 */

/**
 * @brief Handle IPv4 header options in the data-path
 */

#include <vnet/ip/ip.h>

typedef enum ip4_options_next_t_
{
  IP4_OPTIONS_NEXT_PUNT,
  IP4_OPTIONS_NEXT_LOCAL,
  IP4_OPTIONS_N_NEXT,
} ip4_options_next_t;

typedef struct ip4_options_trace_t_
{
  u8 option[4];
} ip4_options_trace_t;

VLIB_NODE_FN (ip4_options_node) (vlib_main_t * vm,
				 vlib_node_runtime_t * node,
				 vlib_frame_t * frame)
{
  uword n_left_from, n_left_to_next, next_index;
  u32 *from, *to_next;

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

  while (n_left_from > 0)
    {
      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      /*
       * IP options packets, when properly used, are very low rate,
       * so this code is not dual-looped for extra performance.
       */
      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  ip4_options_next_t next;
	  ip4_header_t *ip4;
	  vlib_buffer_t *b;
	  u8 *options;
	  u32 bi;

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

	  b = vlib_get_buffer (vm, bi);
	  ip4 = vlib_buffer_get_current (b);
	  next = IP4_OPTIONS_NEXT_PUNT;

	  options = (u8 *) (ip4 + 1);

	  /*
	   * mask out the copy flag to leave the option type
	   */
	  switch (options[0] & 0x7f)
	    {
	    case IP4_ROUTER_ALERT_OPTION:
	      /*
	       * check the option length
	       */
	      if (options[1] != 4)
		break;
	      /*
	       * if it's an IGMP packet, pass up the local stack
	       */
	      if (IP_PROTOCOL_IGMP == ip4->protocol)
		{
		  ip_lookup_set_buffer_fib_index (
		    ip4_main.fib_index_by_sw_if_index, b);
		  next = IP4_OPTIONS_NEXT_LOCAL;
		}
	      break;
	    default:
	      break;
	    }

	  if (b->flags & VLIB_BUFFER_IS_TRACED)
	    {
	      ip4_options_trace_t *t =
		vlib_add_trace (vm, node, b, sizeof (*t));

	      clib_memcpy_fast (t->option, options, 4);
	    }
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi, next);

	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }
  return frame->n_vectors;
}

u8 *
format_ip4_options_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 *);
  ip4_options_trace_t *t = va_arg (*args, ip4_options_trace_t *);
  u32 indent = format_get_indent (s);

  s = format (s, "%Uoption:[0x%x,0x%x,0x%x,0x%x]",
	      format_white_space, indent,
	      t->option[0], t->option[1], t->option[2], t->option[3]);
  return s;
}

VLIB_REGISTER_NODE (ip4_options_node) = {
  .name = "ip4-options",
  .vector_size = sizeof (u32),

  .n_next_nodes = IP4_OPTIONS_N_NEXT,
  .next_nodes = {
    [IP4_OPTIONS_NEXT_PUNT] = "ip4-punt",
    [IP4_OPTIONS_NEXT_LOCAL] = "ip4-local",
  },
  .format_buffer = format_ip4_header,
  .format_trace = format_ip4_options_trace,
};

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