/*
 * node.c: gre packet processing
 *
 * Copyright (c) 2012 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/pg/pg.h>
#include <vnet/gre/gre.h>
#include <vnet/mpls/mpls.h>
#include <vppinfra/sparse_vec.h>

#define foreach_gre_input_next			\
_(PUNT, "error-punt")                           \
_(DROP, "error-drop")                           \
_(ETHERNET_INPUT, "ethernet-input")             \
_(IP4_INPUT, "ip4-input")                       \
_(IP6_INPUT, "ip6-input")			\
_(MPLS_INPUT, "mpls-input")

typedef enum
{
#define _(s,n) GRE_INPUT_NEXT_##s,
  foreach_gre_input_next
#undef _
    GRE_INPUT_N_NEXT,
} gre_input_next_t;

typedef struct
{
  u32 tunnel_id;
  u32 length;
  ip46_address_t src;
  ip46_address_t dst;
  u8 is_ipv6;
} gre_rx_trace_t;

u8 *
format_gre_rx_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 *);
  gre_rx_trace_t *t = va_arg (*args, gre_rx_trace_t *);

  s = format (s, "GRE: tunnel %d len %d src %U dst %U",
	      t->tunnel_id, clib_net_to_host_u16 (t->length),
	      format_ip46_address, &t->src, IP46_TYPE_ANY,
	      format_ip46_address, &t->dst, IP46_TYPE_ANY);
  return s;
}

typedef struct
{
  /* Sparse vector mapping gre protocol in network byte order
     to next index. */
  u16 *next_by_protocol;
} gre_input_runtime_t;

always_inline uword
gre_input (vlib_main_t * vm,
	   vlib_node_runtime_t * node, vlib_frame_t * from_frame, u8 is_ipv6)
{
  gre_main_t *gm = &gre_main;
  __attribute__ ((unused)) u32 n_left_from, next_index, *from, *to_next;
  gre_tunnel_key_t cached_tunnel_key;

  u32 cached_tunnel_sw_if_index = ~0, tunnel_sw_if_index = ~0;

  u32 thread_index = vlib_get_thread_index ();
  u32 len;
  vnet_interface_main_t *im = &gm->vnet_main->interface_main;

  if (!is_ipv6)
    memset (&cached_tunnel_key.gtk_v4, 0xff,
	    sizeof (cached_tunnel_key.gtk_v4));
  else
    memset (&cached_tunnel_key.gtk_v6, 0xff,
	    sizeof (cached_tunnel_key.gtk_v6));

  from = vlib_frame_vector_args (from_frame);
  n_left_from = 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 >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  vlib_buffer_t *b0, *b1;
	  gre_header_t *h0, *h1;
	  u16 version0, version1;
	  int verr0, verr1;
	  u32 i0, i1, next0, next1, protocol0, protocol1;
	  ip4_header_t *ip4_0, *ip4_1;
	  ip6_header_t *ip6_0, *ip6_1;
	  gre_tunnel_key_t key0, key1;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *p2, *p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);

	    CLIB_PREFETCH (p2->data, sizeof (h0[0]), LOAD);
	    CLIB_PREFETCH (p3->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);

	  if (!is_ipv6)
	    {
	      /* ip4_local hands us the ip header, not the gre header */
	      ip4_0 = vlib_buffer_get_current (b0);
	      ip4_1 = vlib_buffer_get_current (b1);

	      vlib_buffer_advance (b0, sizeof (*ip4_0));
	      vlib_buffer_advance (b1, sizeof (*ip4_1));
	    }
	  else
	    {
	      /* ip6_local hands us the ip header, not the gre header */
	      ip6_0 = vlib_buffer_get_current (b0);
	      ip6_1 = vlib_buffer_get_current (b1);

	      vlib_buffer_advance (b0, sizeof (*ip6_0));
	      vlib_buffer_advance (b1, sizeof (*ip6_1));
	    }

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

	  /* Index sparse array with network byte order. */
	  protocol0 = h0->protocol;
	  protocol1 = h1->protocol;
	  sparse_vec_index2 (gm->next_by_protocol, protocol0, protocol1,
			     &i0, &i1);
	  next0 = vec_elt (gm->next_by_protocol, i0).next_index;
	  next1 = vec_elt (gm->next_by_protocol, i1).next_index;
	  u8 ttype0 = vec_elt (gm->next_by_protocol, i0).tunnel_type;
	  u8 ttype1 = vec_elt (gm->next_by_protocol, i1).tunnel_type;

	  b0->error =
	    node->errors[i0 ==
			 SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL
			 : GRE_ERROR_NONE];
	  b1->error =
	    node->errors[i1 ==
			 SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL
			 : GRE_ERROR_NONE];

	  version0 = clib_net_to_host_u16 (h0->flags_and_version);
	  verr0 = version0 & GRE_VERSION_MASK;
	  version1 = clib_net_to_host_u16 (h1->flags_and_version);
	  verr1 = version1 & GRE_VERSION_MASK;

	  b0->error = verr0 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
	    : b0->error;
	  next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;
	  b1->error = verr1 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
	    : b1->error;
	  next1 = verr1 ? GRE_INPUT_NEXT_DROP : next1;


	  /* RPF check for ip4/ip6 input */
	  if (PREDICT_TRUE (next0 > GRE_INPUT_NEXT_DROP))
	    {
	      if (is_ipv6)
		{
		  gre_mk_key6 (&ip6_0->dst_address,
			       &ip6_0->src_address,
			       vnet_buffer (b0)->ip.fib_index,
			       ttype0, 0, &key0.gtk_v6);
		}
	      else
		{
		  gre_mk_key4 (ip4_0->dst_address,
			       ip4_0->src_address,
			       vnet_buffer (b0)->ip.fib_index,
			       ttype0, 0, &key0.gtk_v4);
		}

	      if ((!is_ipv6 && !gre_match_key4 (&cached_tunnel_key.gtk_v4,
						&key0.gtk_v4)) ||
		  (is_ipv6 && !gre_match_key6 (&cached_tunnel_key.gtk_v6,
					       &key0.gtk_v6)))
		{
		  gre_tunnel_t *t;
		  uword *p;

		  if (!is_ipv6)
		    {
		      p = hash_get_mem (gm->tunnel_by_key4, &key0.gtk_v4);
		    }
		  else
		    {
		      p = hash_get_mem (gm->tunnel_by_key6, &key0.gtk_v6);
		    }
		  if (!p)
		    {
		      next0 = GRE_INPUT_NEXT_DROP;
		      b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
		      goto drop0;
		    }
		  t = pool_elt_at_index (gm->tunnels, p[0]);
		  tunnel_sw_if_index = t->sw_if_index;

		  cached_tunnel_sw_if_index = tunnel_sw_if_index;
		  if (!is_ipv6)
		    {
		      cached_tunnel_key.gtk_v4 = key0.gtk_v4;
		    }
		  else
		    {
		      cached_tunnel_key.gtk_v6 = key0.gtk_v6;
		    }
		}
	      else
		{
		  tunnel_sw_if_index = cached_tunnel_sw_if_index;
		}
	    }
	  else
	    {
	      next0 = GRE_INPUT_NEXT_DROP;
	      goto drop0;
	    }
	  len = vlib_buffer_length_in_chain (vm, b0);
	  vlib_increment_combined_counter (im->combined_sw_if_counters
					   + VNET_INTERFACE_COUNTER_RX,
					   thread_index,
					   tunnel_sw_if_index,
					   1 /* packets */ ,
					   len /* bytes */ );

	  vnet_buffer (b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;

	drop0:
	  if (PREDICT_TRUE (next1 > GRE_INPUT_NEXT_DROP))
	    {
	      if (is_ipv6)
		{
		  gre_mk_key6 (&ip6_1->dst_address,
			       &ip6_1->src_address,
			       vnet_buffer (b1)->ip.fib_index,
			       ttype1, 0, &key1.gtk_v6);
		}
	      else
		{
		  gre_mk_key4 (ip4_1->dst_address,
			       ip4_1->src_address,
			       vnet_buffer (b1)->ip.fib_index,
			       ttype1, 0, &key1.gtk_v4);
		}

	      if ((!is_ipv6 && !gre_match_key4 (&cached_tunnel_key.gtk_v4,
						&key1.gtk_v4)) ||
		  (is_ipv6 && !gre_match_key6 (&cached_tunnel_key.gtk_v6,
					       &key1.gtk_v6)))
		{
		  gre_tunnel_t *t;
		  uword *p;

		  if (!is_ipv6)
		    {
		      p = hash_get_mem (gm->tunnel_by_key4, &key1.gtk_v4);
		    }
		  else
		    {
		      p = hash_get_mem (gm->tunnel_by_key6, &key1.gtk_v6);
		    }
		  if (!p)
		    {
		      next1 = GRE_INPUT_NEXT_DROP;
		      b1->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
		      goto drop1;
		    }
		  t = pool_elt_at_index (gm->tunnels, p[0]);
		  tunnel_sw_if_index = t->sw_if_index;

		  cached_tunnel_sw_if_index = tunnel_sw_if_index;
		  if (!is_ipv6)
		    {
		      cached_tunnel_key.gtk_v4 = key1.gtk_v4;
		    }
		  else
		    {
		      cached_tunnel_key.gtk_v6 = key1.gtk_v6;
		    }
		}
	      else
		{
		  tunnel_sw_if_index = cached_tunnel_sw_if_index;
		}
	    }
	  else
	    {
	      next1 = GRE_INPUT_NEXT_DROP;
	      goto drop1;
	    }
	  len = vlib_buffer_length_in_chain (vm, b1);
	  vlib_increment_combined_counter (im->combined_sw_if_counters
					   + VNET_INTERFACE_COUNTER_RX,
					   thread_index,
					   tunnel_sw_if_index,
					   1 /* packets */ ,
					   len /* bytes */ );

	  vnet_buffer (b1)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;

	drop1:
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      gre_rx_trace_t *tr = vlib_add_trace (vm, node,
						   b0, sizeof (*tr));
	      tr->tunnel_id = tunnel_sw_if_index;
	      if (!is_ipv6)
		{
		  tr->length = ip4_0->length;
		  tr->src.ip4.as_u32 = ip4_0->src_address.as_u32;
		  tr->dst.ip4.as_u32 = ip4_0->dst_address.as_u32;
		}
	      else
		{
		  tr->length = ip6_0->payload_length;
		  tr->src.ip6.as_u64[0] = ip6_0->src_address.as_u64[0];
		  tr->src.ip6.as_u64[1] = ip6_0->src_address.as_u64[1];
		  tr->dst.ip6.as_u64[0] = ip6_0->dst_address.as_u64[0];
		  tr->dst.ip6.as_u64[1] = ip6_0->dst_address.as_u64[1];
		}
	    }

	  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      gre_rx_trace_t *tr = vlib_add_trace (vm, node,
						   b1, sizeof (*tr));
	      tr->tunnel_id = tunnel_sw_if_index;
	      if (!is_ipv6)
		{
		  tr->length = ip4_1->length;
		  tr->src.ip4.as_u32 = ip4_1->src_address.as_u32;
		  tr->dst.ip4.as_u32 = ip4_1->dst_address.as_u32;
		}
	      else
		{
		  tr->length = ip6_1->payload_length;
		  tr->src.ip6.as_u64[0] = ip6_1->src_address.as_u64[0];
		  tr->src.ip6.as_u64[1] = ip6_1->src_address.as_u64[1];
		  tr->dst.ip6.as_u64[0] = ip6_1->dst_address.as_u64[0];
		  tr->dst.ip6.as_u64[1] = ip6_1->dst_address.as_u64[1];
		}
	    }

	  vlib_buffer_advance (b0, sizeof (*h0));
	  vlib_buffer_advance (b1, sizeof (*h1));

	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  gre_header_t *h0;
	  ip4_header_t *ip4_0;
	  ip6_header_t *ip6_0;
	  u16 version0;
	  int verr0;
	  u32 i0, next0;
	  gre_tunnel_key_t key0;

	  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);
	  ip4_0 = vlib_buffer_get_current (b0);
	  ip6_0 = (void *) ip4_0;

	  if (!is_ipv6)
	    {
	      vlib_buffer_advance (b0, sizeof (*ip4_0));
	    }
	  else
	    {
	      vlib_buffer_advance (b0, sizeof (*ip6_0));
	    }

	  h0 = vlib_buffer_get_current (b0);

	  i0 = sparse_vec_index (gm->next_by_protocol, h0->protocol);
	  next0 = vec_elt (gm->next_by_protocol, i0).next_index;
	  u8 ttype0 = vec_elt (gm->next_by_protocol, i0).tunnel_type;

	  b0->error =
	    node->errors[i0 == SPARSE_VEC_INVALID_INDEX
			 ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];

	  version0 = clib_net_to_host_u16 (h0->flags_and_version);
	  verr0 = version0 & GRE_VERSION_MASK;
	  b0->error = verr0 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
	    : b0->error;
	  next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;


	  /* For IP payload we need to find source interface
	     so we can increase counters and help forward node to
	     pick right FIB */
	  /* RPF check for ip4/ip6 input */
	  if (PREDICT_TRUE (next0 > GRE_INPUT_NEXT_DROP))
	    {
	      if (is_ipv6)
		{
		  gre_mk_key6 (&ip6_0->dst_address,
			       &ip6_0->src_address,
			       vnet_buffer (b0)->ip.fib_index,
			       ttype0, 0, &key0.gtk_v6);
		}
	      else
		{
		  gre_mk_key4 (ip4_0->dst_address,
			       ip4_0->src_address,
			       vnet_buffer (b0)->ip.fib_index,
			       ttype0, 0, &key0.gtk_v4);
		}

	      if ((!is_ipv6 && !gre_match_key4 (&cached_tunnel_key.gtk_v4,
						&key0.gtk_v4)) ||
		  (is_ipv6 && !gre_match_key6 (&cached_tunnel_key.gtk_v6,
					       &key0.gtk_v6)))
		{
		  gre_tunnel_t *t;
		  uword *p;

		  if (!is_ipv6)
		    {
		      p = hash_get_mem (gm->tunnel_by_key4, &key0.gtk_v4);
		    }
		  else
		    {
		      p = hash_get_mem (gm->tunnel_by_key6, &key0.gtk_v6);
		    }
		  if (!p)
		    {
		      next0 = GRE_INPUT_NEXT_DROP;
		      b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
		      goto drop;
		    }
		  t = pool_elt_at_index (gm->tunnels, p[0]);
		  tunnel_sw_if_index = t->sw_if_index;

		  cached_tunnel_sw_if_index = tunnel_sw_if_index;
		  if (!is_ipv6)
		    {
		      cached_tunnel_key.gtk_v4 = key0.gtk_v4;
		    }
		  else
		    {
		      cached_tunnel_key.gtk_v6 = key0.gtk_v6;
		    }
		}
	      else
		{
		  tunnel_sw_if_index = cached_tunnel_sw_if_index;
		}
	    }
	  else
	    {
	      next0 = GRE_INPUT_NEXT_DROP;
	      goto drop;
	    }
	  len = vlib_buffer_length_in_chain (vm, b0);
	  vlib_increment_combined_counter (im->combined_sw_if_counters
					   + VNET_INTERFACE_COUNTER_RX,
					   thread_index,
					   tunnel_sw_if_index,
					   1 /* packets */ ,
					   len /* bytes */ );

	  vnet_buffer (b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;

	drop:
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      gre_rx_trace_t *tr = vlib_add_trace (vm, node,
						   b0, sizeof (*tr));
	      tr->tunnel_id = tunnel_sw_if_index;
	      if (!is_ipv6)
		{
		  tr->length = ip4_0->length;
		  tr->src.ip4.as_u32 = ip4_0->src_address.as_u32;
		  tr->dst.ip4.as_u32 = ip4_0->dst_address.as_u32;
		}
	      else
		{
		  tr->length = ip6_0->payload_length;
		  tr->src.ip6.as_u64[0] = ip6_0->src_address.as_u64[0];
		  tr->src.ip6.as_u64[1] = ip6_0->src_address.as_u64[1];
		  tr->dst.ip6.as_u64[0] = ip6_0->dst_address.as_u64[0];
		  tr->dst.ip6.as_u64[1] = ip6_0->dst_address.as_u64[1];
		}
	    }

	  vlib_buffer_advance (b0, sizeof (*h0));

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }
  vlib_node_increment_counter (vm,
			       !is_ipv6 ? gre4_input_node.index :
			       gre6_input_node.index, GRE_ERROR_PKTS_DECAP,
			       from_frame->n_vectors);
  return from_frame->n_vectors;
}

static uword
gre4_input (vlib_main_t * vm,
	    vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  return gre_input (vm, node, from_frame, /* is_ip6 */ 0);
}

static uword
gre6_input (vlib_main_t * vm,
	    vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  return gre_input (vm, node, from_frame, /* is_ip6 */ 1);
}

static char *gre_error_strings[] = {
#define gre_error(n,s) s,
#include "error.def"
#undef gre_error
};

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (gre4_input_node) = {
  .function = gre4_input,
  .name = "gre4-input",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .n_errors = GRE_N_ERROR,
  .error_strings = gre_error_strings,

  .n_next_nodes = GRE_INPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [GRE_INPUT_NEXT_##s] = n,
    foreach_gre_input_next
#undef _
  },

  .format_buffer = format_gre_header_with_length,
  .format_trace = format_gre_rx_trace,
  .unformat_buffer = unformat_gre_header,
};

VLIB_REGISTER_NODE (gre6_input_node) = {
  .function = gre6_input,
  .name = "gre6-input",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .runtime_data_bytes = sizeof (gre_input_runtime_t),

  .n_errors = GRE_N_ERROR,
  .error_strings = gre_error_strings,

  .n_next_nodes = GRE_INPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [GRE_INPUT_NEXT_##s] = n,
    foreach_gre_input_next
#undef _
  },

  .format_buffer = format_gre_header_with_length,
  .format_trace = format_gre_rx_trace,
  .unformat_buffer = unformat_gre_header,
};

VLIB_NODE_FUNCTION_MULTIARCH (gre4_input_node, gre4_input)
VLIB_NODE_FUNCTION_MULTIARCH (gre6_input_node, gre6_input)
/* *INDENT-ON* */

void
gre_register_input_protocol (vlib_main_t * vm,
			     gre_protocol_t protocol, u32 node_index,
			     gre_tunnel_type_t tunnel_type)
{
  gre_main_t *em = &gre_main;
  gre_protocol_info_t *pi;
  next_info_t *n;
  u32 i;

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

  pi = gre_get_protocol_info (em, protocol);
  pi->node_index = node_index;
  pi->tunnel_type = tunnel_type;
  pi->next_index = vlib_node_add_next (vm, gre4_input_node.index, node_index);
  i = vlib_node_add_next (vm, gre6_input_node.index, node_index);
  ASSERT (i == pi->next_index);

  /* Setup gre protocol -> next index sparse vector mapping. */
  n = sparse_vec_validate (em->next_by_protocol,
			   clib_host_to_net_u16 (protocol));
  n->next_index = pi->next_index;
  n->tunnel_type = tunnel_type;
}

static void
gre_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_gre_header_with_length;
  n->unformat_buffer = unformat_gre_header;
  pn->unformat_edit = unformat_pg_gre_header;
}

static clib_error_t *
gre_input_init (vlib_main_t * vm)
{
  gre_main_t *gm = &gre_main;
  vlib_node_t *ethernet_input, *ip4_input, *ip6_input, *mpls_unicast_input;

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

  gre_setup_node (vm, gre4_input_node.index);
  gre_setup_node (vm, gre6_input_node.index);

  gm->next_by_protocol = sparse_vec_new
    ( /* elt bytes */ sizeof (gm->next_by_protocol[0]),
     /* bits in index */ BITS (((gre_header_t *) 0)->protocol));

  /* These could be moved to the supported protocol input node defn's */
  ethernet_input = vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
  ASSERT (ethernet_input);
  ip4_input = vlib_get_node_by_name (vm, (u8 *) "ip4-input");
  ASSERT (ip4_input);
  ip6_input = vlib_get_node_by_name (vm, (u8 *) "ip6-input");
  ASSERT (ip6_input);
  mpls_unicast_input = vlib_get_node_by_name (vm, (u8 *) "mpls-input");
  ASSERT (mpls_unicast_input);

  gre_register_input_protocol (vm, GRE_PROTOCOL_teb,
			       ethernet_input->index, GRE_TUNNEL_TYPE_TEB);

  gre_register_input_protocol (vm, GRE_PROTOCOL_ip4,
			       ip4_input->index, GRE_TUNNEL_TYPE_L3);

  gre_register_input_protocol (vm, GRE_PROTOCOL_ip6,
			       ip6_input->index, GRE_TUNNEL_TYPE_L3);

  gre_register_input_protocol (vm, GRE_PROTOCOL_mpls_unicast,
			       mpls_unicast_input->index, GRE_TUNNEL_TYPE_L3);

  ip4_register_protocol (IP_PROTOCOL_GRE, gre4_input_node.index);
  ip6_register_protocol (IP_PROTOCOL_GRE, gre6_input_node.index);

  return 0;
}

VLIB_INIT_FUNCTION (gre_input_init);

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