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

static 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 = vm->thread_index;
  u32 len;
  vnet_interface_main_t *im = &gm->vnet_main->interface_main;

  if (!is_ipv6)
    clib_memset (&cached_tunnel_key.gtk_v4, 0xff,
		 sizeof (cached_tunnel_key.gtk_v4));
  else
    clib_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;
}

VLIB_NODE_FN (gre4_input_node) (vlib_main_t * vm,
				vlib_node_runtime_t * node,
				vlib_frame_t * from_frame)
{
  return gre_input (vm, node, from_frame, /* is_ip6 */ 0);
}

VLIB_NODE_FN (gre6_input_node) (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) = {
  .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) = {
  .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,
};
/* *INDENT-ON* */

#ifndef CLIB_MARCH_VARIANT
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);

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