/*
 * decap.c: vxlan gbp tunnel decap packet processing
 *
 * 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.
 */

#include <vlib/vlib.h>
#include <vnet/pg/pg.h>
#include <vnet/vxlan-gbp/vxlan_gbp.h>

vlib_node_registration_t vxlan4_gbp_input_node;
vlib_node_registration_t vxlan6_gbp_input_node;

typedef struct
{
  u32 next_index;
  u32 tunnel_index;
  u32 error;
  u32 vni;
  u16 sclass;
} vxlan_gbp_rx_trace_t;

static u8 *
format_vxlan_gbp_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 *);
  vxlan_gbp_rx_trace_t *t = va_arg (*args, vxlan_gbp_rx_trace_t *);

  if (t->tunnel_index == ~0)
    return format (s,
		   "VXLAN_GBP decap error - tunnel for vni %d does not exist",
		   t->vni);
  return format (s,
		 "VXLAN_GBP decap from vxlan_gbp_tunnel%d vni %d sclass %d"
		 " next %d error %d",
		 t->tunnel_index, t->vni, t->sclass, t->next_index, t->error);
}

always_inline u32
buf_fib_index (vlib_buffer_t * b, u32 is_ip4)
{
  u32 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
  if (sw_if_index != (u32) ~ 0)
    return sw_if_index;

  u32 *fib_index_by_sw_if_index = is_ip4 ?
    ip4_main.fib_index_by_sw_if_index : ip6_main.fib_index_by_sw_if_index;
  sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];

  return vec_elt (fib_index_by_sw_if_index, sw_if_index);
}

typedef vxlan4_gbp_tunnel_key_t last_tunnel_cache4;

always_inline vxlan_gbp_tunnel_t *
vxlan4_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache4 * cache,
			u32 fib_index, ip4_header_t * ip4_0,
			vxlan_gbp_header_t * vxlan_gbp0,
			vxlan_gbp_tunnel_t ** stats_t0)
{
  /* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */
  vxlan4_gbp_tunnel_key_t key4;
  key4.key[1] = ((u64) fib_index << 32) | vxlan_gbp0->vni_reserved;

  if (PREDICT_FALSE (key4.key[1] != cache->key[1] ||
		     ip4_0->src_address.as_u32 != (u32) cache->key[0]))
    {
      key4.key[0] = ip4_0->src_address.as_u32;
      int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key,
					       &key4);
      if (PREDICT_FALSE (rv != 0))
	return 0;

      *cache = key4;
    }
  vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value);

  /* Validate VXLAN_GBP tunnel SIP against packet DIP */
  if (PREDICT_TRUE (ip4_0->dst_address.as_u32 == t0->src.ip4.as_u32))
    *stats_t0 = t0;
  else
    {
      /* try multicast */
      if (PREDICT_TRUE (!ip4_address_is_multicast (&ip4_0->dst_address)))
	return 0;

      key4.key[0] = ip4_0->dst_address.as_u32;
      /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */
      int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key,
					       &key4);
      if (PREDICT_FALSE (rv != 0))
	return 0;

      *stats_t0 = pool_elt_at_index (vxm->tunnels, key4.value);
    }

  return t0;
}

typedef vxlan6_gbp_tunnel_key_t last_tunnel_cache6;

always_inline vxlan_gbp_tunnel_t *
vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache,
			u32 fib_index, ip6_header_t * ip6_0,
			vxlan_gbp_header_t * vxlan_gbp0,
			vxlan_gbp_tunnel_t ** stats_t0)
{
  /* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */
  vxlan6_gbp_tunnel_key_t key6 = {
    .key = {
	    [0] = ip6_0->src_address.as_u64[0],
	    [1] = ip6_0->src_address.as_u64[1],
	    [2] = (((u64) fib_index) << 32) | vxlan_gbp0->vni_reserved,
	    }
  };

  if (PREDICT_FALSE
      (clib_bihash_key_compare_24_8 (key6.key, cache->key) == 0))
    {
      int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
					       &key6);
      if (PREDICT_FALSE (rv != 0))
	return 0;

      *cache = key6;
    }
  vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value);

  /* Validate VXLAN_GBP tunnel SIP against packet DIP */
  if (PREDICT_TRUE (ip6_address_is_equal (&ip6_0->dst_address, &t0->src.ip6)))
    *stats_t0 = t0;
  else
    {
      /* try multicast */
      if (PREDICT_TRUE (!ip6_address_is_multicast (&ip6_0->dst_address)))
	return 0;

      /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */
      key6.key[0] = ip6_0->dst_address.as_u64[0];
      key6.key[1] = ip6_0->dst_address.as_u64[1];
      int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
					       &key6);
      if (PREDICT_FALSE (rv != 0))
	return 0;

      *stats_t0 = pool_elt_at_index (vxm->tunnels, key6.value);
    }

  return t0;
}

always_inline uword
vxlan_gbp_input (vlib_main_t * vm,
		 vlib_node_runtime_t * node,
		 vlib_frame_t * from_frame, u32 is_ip4)
{
  vxlan_gbp_main_t *vxm = &vxlan_gbp_main;
  vnet_main_t *vnm = vxm->vnet_main;
  vnet_interface_main_t *im = &vnm->interface_main;
  vlib_combined_counter_main_t *rx_counter =
    im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX;
  vlib_combined_counter_main_t *drop_counter =
    im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_DROP;
  last_tunnel_cache4 last4;
  last_tunnel_cache6 last6;
  u32 pkts_decapsulated = 0;
  u32 thread_index = vlib_get_thread_index ();

  if (is_ip4)
    clib_memset (&last4, 0xff, sizeof last4);
  else
    clib_memset (&last6, 0xff, sizeof last6);

  u32 next_index = node->cached_next_index;

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

  while (n_left_from > 0)
    {
      u32 *to_next, 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)
	{
	  /* 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, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	    CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	  }

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

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

	  /* udp leaves current_data pointing at the vxlan_gbp header */
	  void *cur0 = vlib_buffer_get_current (b0);
	  void *cur1 = vlib_buffer_get_current (b1);
	  vxlan_gbp_header_t *vxlan_gbp0 = cur0;
	  vxlan_gbp_header_t *vxlan_gbp1 = cur1;

	  ip4_header_t *ip4_0, *ip4_1;
	  ip6_header_t *ip6_0, *ip6_1;
	  if (is_ip4)
	    {
	      ip4_0 = cur0 - sizeof (udp_header_t) - sizeof (ip4_header_t);
	      ip4_1 = cur1 - sizeof (udp_header_t) - sizeof (ip4_header_t);
	    }
	  else
	    {
	      ip6_0 = cur0 - sizeof (udp_header_t) - sizeof (ip6_header_t);
	      ip6_1 = cur1 - sizeof (udp_header_t) - sizeof (ip6_header_t);
	    }

	  /* pop vxlan_gbp */
	  vlib_buffer_advance (b0, sizeof *vxlan_gbp0);
	  vlib_buffer_advance (b1, sizeof *vxlan_gbp1);

	  u32 fi0 = buf_fib_index (b0, is_ip4);
	  u32 fi1 = buf_fib_index (b1, is_ip4);

	  vxlan_gbp_tunnel_t *t0, *stats_t0 = 0;
	  vxlan_gbp_tunnel_t *t1, *stats_t1 = 0;
	  if (is_ip4)
	    {
	      t0 =
		vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0,
					&stats_t0);
	      t1 =
		vxlan4_gbp_find_tunnel (vxm, &last4, fi1, ip4_1, vxlan_gbp1,
					&stats_t1);
	    }
	  else
	    {
	      t0 =
		vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0,
					&stats_t0);
	      t1 =
		vxlan6_gbp_find_tunnel (vxm, &last6, fi1, ip6_1, vxlan_gbp1,
					&stats_t1);
	    }

	  u32 len0 = vlib_buffer_length_in_chain (vm, b0);
	  u32 len1 = vlib_buffer_length_in_chain (vm, b1);

	  u32 next0, next1;
	  u8 error0 = 0, error1 = 0;
	  u8 flags0 = vxlan_gbp_get_flags (vxlan_gbp0);
	  u8 flags1 = vxlan_gbp_get_flags (vxlan_gbp1);
	  /* Validate VXLAN_GBP tunnel encap-fib index against packet */
	  if (PREDICT_FALSE
	      (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
	    {
	      next0 = VXLAN_GBP_INPUT_NEXT_DROP;

	      if (t0 != 0
		  && flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))
		{
		  error0 = VXLAN_GBP_ERROR_BAD_FLAGS;
		  vlib_increment_combined_counter
		    (drop_counter, thread_index, stats_t0->sw_if_index, 1,
		     len0);
		}
	      else
		error0 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL;
	      b0->error = node->errors[error0];
	    }
	  else
	    {
	      next0 = t0->decap_next_index;
	      vnet_buffer2 (b0)->gbp.flags =
		vxlan_gbp_get_gpflags (vxlan_gbp0);
	      vnet_buffer2 (b0)->gbp.src_epg =
		vxlan_gbp_get_sclass (vxlan_gbp0);

	      /* Required to make the l2 tag push / pop code work on l2 subifs */
	      if (PREDICT_TRUE (next0 == VXLAN_GBP_INPUT_NEXT_L2_INPUT))
		vnet_update_l2_len (b0);

	      /* Set packet input sw_if_index to unicast VXLAN tunnel for learning */
	      vnet_buffer (b0)->sw_if_index[VLIB_RX] = t0->sw_if_index;
	      vlib_increment_combined_counter
		(rx_counter, thread_index, stats_t0->sw_if_index, 1, len0);
	      pkts_decapsulated++;
	    }

	  /* Validate VXLAN_GBP tunnel encap-fib index against packet */
	  if (PREDICT_FALSE
	      (t1 == 0 || flags1 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
	    {
	      next1 = VXLAN_GBP_INPUT_NEXT_DROP;

	      if (t1 != 0
		  && flags1 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))
		{
		  error1 = VXLAN_GBP_ERROR_BAD_FLAGS;
		  vlib_increment_combined_counter
		    (drop_counter, thread_index, stats_t1->sw_if_index, 1,
		     len1);
		}
	      else
		error1 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL;
	      b1->error = node->errors[error1];
	    }
	  else
	    {
	      next1 = t1->decap_next_index;
	      vnet_buffer2 (b1)->gbp.flags =
		vxlan_gbp_get_gpflags (vxlan_gbp1);
	      vnet_buffer2 (b1)->gbp.src_epg =
		vxlan_gbp_get_sclass (vxlan_gbp1);

	      /* Required to make the l2 tag push / pop code work on l2 subifs */
	      if (PREDICT_TRUE (next1 == VXLAN_GBP_INPUT_NEXT_L2_INPUT))
		vnet_update_l2_len (b1);

	      /* Set packet input sw_if_index to unicast VXLAN_GBP tunnel for learning */
	      vnet_buffer (b1)->sw_if_index[VLIB_RX] = t1->sw_if_index;
	      pkts_decapsulated++;

	      vlib_increment_combined_counter
		(rx_counter, thread_index, stats_t1->sw_if_index, 1, len1);
	    }

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      vxlan_gbp_rx_trace_t *tr =
		vlib_add_trace (vm, node, b0, sizeof (*tr));
	      tr->next_index = next0;
	      tr->error = error0;
	      tr->tunnel_index = t0 == 0 ? ~0 : t0 - vxm->tunnels;
	      tr->vni = vxlan_gbp_get_vni (vxlan_gbp0);
	      tr->sclass = vxlan_gbp_get_sclass (vxlan_gbp0);
	    }
	  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      vxlan_gbp_rx_trace_t *tr =
		vlib_add_trace (vm, node, b1, sizeof (*tr));
	      tr->next_index = next1;
	      tr->error = error1;
	      tr->tunnel_index = t1 == 0 ? ~0 : t1 - vxm->tunnels;
	      tr->vni = vxlan_gbp_get_vni (vxlan_gbp1);
	      tr->sclass = vxlan_gbp_get_sclass (vxlan_gbp1);
	    }

	  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 = to_next[0] = from[0];
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);

	  /* udp leaves current_data pointing at the vxlan_gbp header */
	  void *cur0 = vlib_buffer_get_current (b0);
	  vxlan_gbp_header_t *vxlan_gbp0 = cur0;
	  ip4_header_t *ip4_0;
	  ip6_header_t *ip6_0;
	  if (is_ip4)
	    ip4_0 = cur0 - sizeof (udp_header_t) - sizeof (ip4_header_t);
	  else
	    ip6_0 = cur0 - sizeof (udp_header_t) - sizeof (ip6_header_t);

	  /* pop (ip, udp, vxlan_gbp) */
	  vlib_buffer_advance (b0, sizeof (*vxlan_gbp0));

	  u32 fi0 = buf_fib_index (b0, is_ip4);

	  vxlan_gbp_tunnel_t *t0, *stats_t0 = 0;
	  if (is_ip4)
	    t0 =
	      vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0,
				      &stats_t0);
	  else
	    t0 =
	      vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0,
				      &stats_t0);

	  uword len0 = vlib_buffer_length_in_chain (vm, b0);

	  u32 next0;
	  u8 error0 = 0;
	  u8 flags0 = vxlan_gbp_get_flags (vxlan_gbp0);
	  /* Validate VXLAN_GBP tunnel encap-fib index against packet */
	  if (PREDICT_FALSE
	      (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
	    {
	      next0 = VXLAN_GBP_INPUT_NEXT_DROP;

	      if (t0 != 0
		  && flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))
		{
		  error0 = VXLAN_GBP_ERROR_BAD_FLAGS;
		  vlib_increment_combined_counter
		    (drop_counter, thread_index, stats_t0->sw_if_index, 1,
		     len0);
		}
	      else
		error0 = VXLAN_GBP_ERROR_NO_SUCH_TUNNEL;
	      b0->error = node->errors[error0];
	    }
	  else
	    {
	      next0 = t0->decap_next_index;
	      vnet_buffer2 (b0)->gbp.flags =
		vxlan_gbp_get_gpflags (vxlan_gbp0);
	      vnet_buffer2 (b0)->gbp.src_epg =
		vxlan_gbp_get_sclass (vxlan_gbp0);


	      /* Required to make the l2 tag push / pop code work on l2 subifs */
	      if (PREDICT_TRUE (next0 == VXLAN_GBP_INPUT_NEXT_L2_INPUT))
		vnet_update_l2_len (b0);

	      /* Set packet input sw_if_index to unicast VXLAN_GBP tunnel for learning */
	      vnet_buffer (b0)->sw_if_index[VLIB_RX] = t0->sw_if_index;
	      pkts_decapsulated++;

	      vlib_increment_combined_counter
		(rx_counter, thread_index, stats_t0->sw_if_index, 1, len0);
	    }

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      vxlan_gbp_rx_trace_t *tr
		= vlib_add_trace (vm, node, b0, sizeof (*tr));
	      tr->next_index = next0;
	      tr->error = error0;
	      tr->tunnel_index = t0 == 0 ? ~0 : t0 - vxm->tunnels;
	      tr->vni = vxlan_gbp_get_vni (vxlan_gbp0);
	      tr->sclass = vxlan_gbp_get_sclass (vxlan_gbp0);
	    }
	  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);
    }
  /* Do we still need this now that tunnel tx stats is kept? */
  u32 node_idx =
    is_ip4 ? vxlan4_gbp_input_node.index : vxlan6_gbp_input_node.index;
  vlib_node_increment_counter (vm, node_idx, VXLAN_GBP_ERROR_DECAPSULATED,
			       pkts_decapsulated);

  return from_frame->n_vectors;
}

static uword
vxlan4_gbp_input (vlib_main_t * vm,
		  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  return vxlan_gbp_input (vm, node, from_frame, /* is_ip4 */ 1);
}

static uword
vxlan6_gbp_input (vlib_main_t * vm,
		  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  return vxlan_gbp_input (vm, node, from_frame, /* is_ip4 */ 0);
}

static char *vxlan_gbp_error_strings[] = {
#define vxlan_gbp_error(n,s) s,
#include <vnet/vxlan-gbp/vxlan_gbp_error.def>
#undef vxlan_gbp_error
#undef _
};

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (vxlan4_gbp_input_node) =
{
  .function = vxlan4_gbp_input,
  .name = "vxlan4-gbp-input",
  .vector_size = sizeof (u32),
  .n_errors = VXLAN_GBP_N_ERROR,
  .error_strings = vxlan_gbp_error_strings,
  .n_next_nodes = VXLAN_GBP_INPUT_N_NEXT,
  .format_trace = format_vxlan_gbp_rx_trace,
  .next_nodes = {
#define _(s,n) [VXLAN_GBP_INPUT_NEXT_##s] = n,
    foreach_vxlan_gbp_input_next
#undef _
  },
};
VLIB_NODE_FUNCTION_MULTIARCH (vxlan4_gbp_input_node, vxlan4_gbp_input)

VLIB_REGISTER_NODE (vxlan6_gbp_input_node) =
{
  .function = vxlan6_gbp_input,
  .name = "vxlan6-gbp-input",
  .vector_size = sizeof (u32),
  .n_errors = VXLAN_GBP_N_ERROR,
  .error_strings = vxlan_gbp_error_strings,
  .n_next_nodes = VXLAN_GBP_INPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [VXLAN_GBP_INPUT_NEXT_##s] = n,
    foreach_vxlan_gbp_input_next
#undef _
  },
  .format_trace = format_vxlan_gbp_rx_trace,
};
VLIB_NODE_FUNCTION_MULTIARCH (vxlan6_gbp_input_node, vxlan6_gbp_input)
/* *INDENT-ON* */

typedef enum
{
  IP_VXLAN_GBP_BYPASS_NEXT_DROP,
  IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP,
  IP_VXLAN_GBP_BYPASS_N_NEXT,
} ip_vxan_gbp_bypass_next_t;

always_inline uword
ip_vxlan_gbp_bypass_inline (vlib_main_t * vm,
			    vlib_node_runtime_t * node,
			    vlib_frame_t * frame, u32 is_ip4)
{
  vxlan_gbp_main_t *vxm = &vxlan_gbp_main;
  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
  vlib_node_runtime_t *error_node =
    vlib_node_get_runtime (vm, ip4_input_node.index);
  ip4_address_t addr4;		/* last IPv4 address matching a local VTEP address */
  ip6_address_t addr6;		/* last IPv6 address matching a local VTEP address */

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

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    ip4_forward_next_trace (vm, node, frame, VLIB_TX);

  if (is_ip4)
    addr4.data_u32 = ~0;
  else
    ip6_address_set_zero (&addr6);

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

      while (n_left_from >= 4 && n_left_to_next >= 2)
	{
	  vlib_buffer_t *b0, *b1;
	  ip4_header_t *ip40, *ip41;
	  ip6_header_t *ip60, *ip61;
	  udp_header_t *udp0, *udp1;
	  u32 bi0, ip_len0, udp_len0, flags0, next0;
	  u32 bi1, ip_len1, udp_len1, flags1, next1;
	  i32 len_diff0, len_diff1;
	  u8 error0, good_udp0, proto0;
	  u8 error1, good_udp1, proto1;

	  /* 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, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	    CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	  }

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

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);
	  if (is_ip4)
	    {
	      ip40 = vlib_buffer_get_current (b0);
	      ip41 = vlib_buffer_get_current (b1);
	    }
	  else
	    {
	      ip60 = vlib_buffer_get_current (b0);
	      ip61 = vlib_buffer_get_current (b1);
	    }

	  /* Setup packet for next IP feature */
	  vnet_feature_next (&next0, b0);
	  vnet_feature_next (&next1, b1);

	  if (is_ip4)
	    {
	      /* Treat IP frag packets as "experimental" protocol for now
	         until support of IP frag reassembly is implemented */
	      proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
	      proto1 = ip4_is_fragment (ip41) ? 0xfe : ip41->protocol;
	    }
	  else
	    {
	      proto0 = ip60->protocol;
	      proto1 = ip61->protocol;
	    }

	  /* Process packet 0 */
	  if (proto0 != IP_PROTOCOL_UDP)
	    goto exit0;		/* not UDP packet */

	  if (is_ip4)
	    udp0 = ip4_next_header (ip40);
	  else
	    udp0 = ip6_next_header (ip60);

	  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_vxlan_gbp))
	    goto exit0;		/* not VXLAN_GBP packet */

	  /* Validate DIP against VTEPs */
	  if (is_ip4)
	    {
	      if (addr4.as_u32 != ip40->dst_address.as_u32)
		{
		  if (!hash_get (vxm->vtep4, ip40->dst_address.as_u32))
		    goto exit0;	/* no local VTEP for VXLAN_GBP packet */
		  addr4 = ip40->dst_address;
		}
	    }
	  else
	    {
	      if (!ip6_address_is_equal (&addr6, &ip60->dst_address))
		{
		  if (!hash_get_mem (vxm->vtep6, &ip60->dst_address))
		    goto exit0;	/* no local VTEP for VXLAN_GBP packet */
		  addr6 = ip60->dst_address;
		}
	    }

	  flags0 = b0->flags;
	  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;

	  /* Don't verify UDP checksum for packets with explicit zero checksum. */
	  good_udp0 |= udp0->checksum == 0;

	  /* Verify UDP length */
	  if (is_ip4)
	    ip_len0 = clib_net_to_host_u16 (ip40->length);
	  else
	    ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
	  udp_len0 = clib_net_to_host_u16 (udp0->length);
	  len_diff0 = ip_len0 - udp_len0;

	  /* Verify UDP checksum */
	  if (PREDICT_FALSE (!good_udp0))
	    {
	      if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
		{
		  if (is_ip4)
		    flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
		  else
		    flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
		  good_udp0 =
		    (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
		}
	    }

	  if (is_ip4)
	    {
	      error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
	      error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
	    }
	  else
	    {
	      error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
	      error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
	    }

	  next0 = error0 ?
	    IP_VXLAN_GBP_BYPASS_NEXT_DROP :
	    IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP;
	  b0->error = error0 ? error_node->errors[error0] : 0;

	  /* vxlan-gbp-input node expect current at VXLAN_GBP header */
	  if (is_ip4)
	    vlib_buffer_advance (b0,
				 sizeof (ip4_header_t) +
				 sizeof (udp_header_t));
	  else
	    vlib_buffer_advance (b0,
				 sizeof (ip6_header_t) +
				 sizeof (udp_header_t));

	exit0:
	  /* Process packet 1 */
	  if (proto1 != IP_PROTOCOL_UDP)
	    goto exit1;		/* not UDP packet */

	  if (is_ip4)
	    udp1 = ip4_next_header (ip41);
	  else
	    udp1 = ip6_next_header (ip61);

	  if (udp1->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_vxlan_gbp))
	    goto exit1;		/* not VXLAN_GBP packet */

	  /* Validate DIP against VTEPs */
	  if (is_ip4)
	    {
	      if (addr4.as_u32 != ip41->dst_address.as_u32)
		{
		  if (!hash_get (vxm->vtep4, ip41->dst_address.as_u32))
		    goto exit1;	/* no local VTEP for VXLAN_GBP packet */
		  addr4 = ip41->dst_address;
		}
	    }
	  else
	    {
	      if (!ip6_address_is_equal (&addr6, &ip61->dst_address))
		{
		  if (!hash_get_mem (vxm->vtep6, &ip61->dst_address))
		    goto exit1;	/* no local VTEP for VXLAN_GBP packet */
		  addr6 = ip61->dst_address;
		}
	    }

	  flags1 = b1->flags;
	  good_udp1 = (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;

	  /* Don't verify UDP checksum for packets with explicit zero checksum. */
	  good_udp1 |= udp1->checksum == 0;

	  /* Verify UDP length */
	  if (is_ip4)
	    ip_len1 = clib_net_to_host_u16 (ip41->length);
	  else
	    ip_len1 = clib_net_to_host_u16 (ip61->payload_length);
	  udp_len1 = clib_net_to_host_u16 (udp1->length);
	  len_diff1 = ip_len1 - udp_len1;

	  /* Verify UDP checksum */
	  if (PREDICT_FALSE (!good_udp1))
	    {
	      if ((flags1 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
		{
		  if (is_ip4)
		    flags1 = ip4_tcp_udp_validate_checksum (vm, b1);
		  else
		    flags1 = ip6_tcp_udp_icmp_validate_checksum (vm, b1);
		  good_udp1 =
		    (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
		}
	    }

	  if (is_ip4)
	    {
	      error1 = good_udp1 ? 0 : IP4_ERROR_UDP_CHECKSUM;
	      error1 = (len_diff1 >= 0) ? error1 : IP4_ERROR_UDP_LENGTH;
	    }
	  else
	    {
	      error1 = good_udp1 ? 0 : IP6_ERROR_UDP_CHECKSUM;
	      error1 = (len_diff1 >= 0) ? error1 : IP6_ERROR_UDP_LENGTH;
	    }

	  next1 = error1 ?
	    IP_VXLAN_GBP_BYPASS_NEXT_DROP :
	    IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP;
	  b1->error = error1 ? error_node->errors[error1] : 0;

	  /* vxlan_gbp-input node expect current at VXLAN_GBP header */
	  if (is_ip4)
	    vlib_buffer_advance (b1,
				 sizeof (ip4_header_t) +
				 sizeof (udp_header_t));
	  else
	    vlib_buffer_advance (b1,
				 sizeof (ip6_header_t) +
				 sizeof (udp_header_t));

	exit1:
	  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)
	{
	  vlib_buffer_t *b0;
	  ip4_header_t *ip40;
	  ip6_header_t *ip60;
	  udp_header_t *udp0;
	  u32 bi0, ip_len0, udp_len0, flags0, next0;
	  i32 len_diff0;
	  u8 error0, good_udp0, proto0;

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

	  b0 = vlib_get_buffer (vm, bi0);
	  if (is_ip4)
	    ip40 = vlib_buffer_get_current (b0);
	  else
	    ip60 = vlib_buffer_get_current (b0);

	  /* Setup packet for next IP feature */
	  vnet_feature_next (&next0, b0);

	  if (is_ip4)
	    /* Treat IP4 frag packets as "experimental" protocol for now
	       until support of IP frag reassembly is implemented */
	    proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
	  else
	    proto0 = ip60->protocol;

	  if (proto0 != IP_PROTOCOL_UDP)
	    goto exit;		/* not UDP packet */

	  if (is_ip4)
	    udp0 = ip4_next_header (ip40);
	  else
	    udp0 = ip6_next_header (ip60);

	  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_vxlan_gbp))
	    goto exit;		/* not VXLAN_GBP packet */

	  /* Validate DIP against VTEPs */
	  if (is_ip4)
	    {
	      if (addr4.as_u32 != ip40->dst_address.as_u32)
		{
		  if (!hash_get (vxm->vtep4, ip40->dst_address.as_u32))
		    goto exit;	/* no local VTEP for VXLAN_GBP packet */
		  addr4 = ip40->dst_address;
		}
	    }
	  else
	    {
	      if (!ip6_address_is_equal (&addr6, &ip60->dst_address))
		{
		  if (!hash_get_mem (vxm->vtep6, &ip60->dst_address))
		    goto exit;	/* no local VTEP for VXLAN_GBP packet */
		  addr6 = ip60->dst_address;
		}
	    }

	  flags0 = b0->flags;
	  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;

	  /* Don't verify UDP checksum for packets with explicit zero checksum. */
	  good_udp0 |= udp0->checksum == 0;

	  /* Verify UDP length */
	  if (is_ip4)
	    ip_len0 = clib_net_to_host_u16 (ip40->length);
	  else
	    ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
	  udp_len0 = clib_net_to_host_u16 (udp0->length);
	  len_diff0 = ip_len0 - udp_len0;

	  /* Verify UDP checksum */
	  if (PREDICT_FALSE (!good_udp0))
	    {
	      if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
		{
		  if (is_ip4)
		    flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
		  else
		    flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
		  good_udp0 =
		    (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
		}
	    }

	  if (is_ip4)
	    {
	      error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
	      error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
	    }
	  else
	    {
	      error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
	      error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
	    }

	  next0 = error0 ?
	    IP_VXLAN_GBP_BYPASS_NEXT_DROP :
	    IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP;
	  b0->error = error0 ? error_node->errors[error0] : 0;

	  /* vxlan_gbp-input node expect current at VXLAN_GBP header */
	  if (is_ip4)
	    vlib_buffer_advance (b0,
				 sizeof (ip4_header_t) +
				 sizeof (udp_header_t));
	  else
	    vlib_buffer_advance (b0,
				 sizeof (ip6_header_t) +
				 sizeof (udp_header_t));

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

  return frame->n_vectors;
}

static uword
ip4_vxlan_gbp_bypass (vlib_main_t * vm,
		      vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  return ip_vxlan_gbp_bypass_inline (vm, node, frame, /* is_ip4 */ 1);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_vxlan_gbp_bypass_node) =
{
  .function = ip4_vxlan_gbp_bypass,
  .name = "ip4-vxlan-gbp-bypass",
  .vector_size = sizeof (u32),
  .n_next_nodes = IP_VXLAN_GBP_BYPASS_N_NEXT,
  .next_nodes = {
	  [IP_VXLAN_GBP_BYPASS_NEXT_DROP] = "error-drop",
	  [IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP] = "vxlan4-gbp-input",
  },
  .format_buffer = format_ip4_header,
  .format_trace = format_ip4_forward_next_trace,
};

VLIB_NODE_FUNCTION_MULTIARCH (ip4_vxlan_gbp_bypass_node, ip4_vxlan_gbp_bypass)
/* *INDENT-ON* */

/* Dummy init function to get us linked in. */
clib_error_t *
ip4_vxlan_gbp_bypass_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (ip4_vxlan_gbp_bypass_init);

static uword
ip6_vxlan_gbp_bypass (vlib_main_t * vm,
		      vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  return ip_vxlan_gbp_bypass_inline (vm, node, frame, /* is_ip4 */ 0);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_vxlan_gbp_bypass_node) =
{
  .function = ip6_vxlan_gbp_bypass,
  .name = "ip6-vxlan-gbp-bypass",
  .vector_size = sizeof (u32),
  .n_next_nodes = IP_VXLAN_GBP_BYPASS_N_NEXT,
  .next_nodes = {
    [IP_VXLAN_GBP_BYPASS_NEXT_DROP] = "error-drop",
    [IP_VXLAN_GBP_BYPASS_NEXT_VXLAN_GBP] = "vxlan6-gbp-input",
  },
  .format_buffer = format_ip6_header,
  .format_trace = format_ip6_forward_next_trace,
};

VLIB_NODE_FUNCTION_MULTIARCH (ip6_vxlan_gbp_bypass_node, ip6_vxlan_gbp_bypass)
/* *INDENT-ON* */

/* Dummy init function to get us linked in. */
clib_error_t *
ip6_vxlan_gbp_bypass_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (ip6_vxlan_gbp_bypass_init);

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