/*
 * esp_decrypt.c : IPSec ESP decrypt node
 *
 * 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.
 */
#include <vnet/vnet.h>
#include <vnet/api_errno.h>
#include <vnet/ip/ip.h>
#include <vnet/l2/l2_input.h>

#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/esp.h>
#include <vnet/ipsec/ipsec_io.h>
#include <vnet/ipsec/ipsec_tun.h>

#include <vnet/gre/packet.h>

#define foreach_esp_decrypt_next                                              \
  _ (DROP, "error-drop")                                                      \
  _ (IP4_INPUT, "ip4-input-no-checksum")                                      \
  _ (IP6_INPUT, "ip6-input")                                                  \
  _ (L2_INPUT, "l2-input")                                                    \
  _ (MPLS_INPUT, "mpls-input")                                                \
  _ (HANDOFF, "handoff")

#define _(v, s) ESP_DECRYPT_NEXT_##v,
typedef enum
{
  foreach_esp_decrypt_next
#undef _
    ESP_DECRYPT_N_NEXT,
} esp_decrypt_next_t;

#define foreach_esp_decrypt_post_next                                         \
  _ (DROP, "error-drop")                                                      \
  _ (IP4_INPUT, "ip4-input-no-checksum")                                      \
  _ (IP6_INPUT, "ip6-input")                                                  \
  _ (MPLS_INPUT, "mpls-input")                                                \
  _ (L2_INPUT, "l2-input")

#define _(v, s) ESP_DECRYPT_POST_NEXT_##v,
typedef enum
{
  foreach_esp_decrypt_post_next
#undef _
    ESP_DECRYPT_POST_N_NEXT,
} esp_decrypt_post_next_t;

#define foreach_esp_decrypt_error                                             \
  _ (RX_PKTS, "ESP pkts received")                                            \
  _ (RX_POST_PKTS, "ESP-POST pkts received")                                  \
  _ (HANDOFF, "hand-off")                                                     \
  _ (DECRYPTION_FAILED, "ESP decryption failed")                              \
  _ (INTEG_ERROR, "Integrity check failed")                                   \
  _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)")             \
  _ (REPLAY, "SA replayed packet")                                            \
  _ (RUNT, "undersized packet")                                               \
  _ (NO_BUFFERS, "no buffers (packet dropped)")                               \
  _ (OVERSIZED_HEADER, "buffer with oversized header (dropped)")              \
  _ (NO_TAIL_SPACE, "no enough buffer tail space (dropped)")                  \
  _ (TUN_NO_PROTO, "no tunnel protocol")                                      \
  _ (UNSUP_PAYLOAD, "unsupported payload")

typedef enum
{
#define _(sym,str) ESP_DECRYPT_ERROR_##sym,
  foreach_esp_decrypt_error
#undef _
    ESP_DECRYPT_N_ERROR,
} esp_decrypt_error_t;

static char *esp_decrypt_error_strings[] = {
#define _(sym,string) string,
  foreach_esp_decrypt_error
#undef _
};

typedef struct
{
  u32 seq;
  u32 sa_seq;
  u32 sa_seq_hi;
  u32 pkt_seq_hi;
  ipsec_crypto_alg_t crypto_alg;
  ipsec_integ_alg_t integ_alg;
} esp_decrypt_trace_t;

/* The number of byres in the hisequence number */
#define N_HI_ESN_BYTES 4

/* packet trace format function */
static u8 *
format_esp_decrypt_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 *);
  esp_decrypt_trace_t *t = va_arg (*args, esp_decrypt_trace_t *);

  s = format (s,
	      "esp: crypto %U integrity %U pkt-seq %d sa-seq %u sa-seq-hi %u "
	      "pkt-seq-hi %u",
	      format_ipsec_crypto_alg, t->crypto_alg, format_ipsec_integ_alg,
	      t->integ_alg, t->seq, t->sa_seq, t->sa_seq_hi, t->pkt_seq_hi);
  return s;
}

#define ESP_ENCRYPT_PD_F_FD_TRANSPORT (1 << 2)

static_always_inline void
esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
		 vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts,
		 int e)
{
  vnet_crypto_op_t *op = ops;
  u32 n_fail, n_ops = vec_len (ops);

  if (n_ops == 0)
    return;

  n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);

  while (n_fail)
    {
      ASSERT (op - ops < n_ops);
      if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
	{
	  u32 err, bi = op->user_data;
	  if (op->status == VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC)
	    err = e;
	  else
	    err = ESP_DECRYPT_ERROR_CRYPTO_ENGINE_ERROR;
	  b[bi]->error = node->errors[err];
	  nexts[bi] = ESP_DECRYPT_NEXT_DROP;
	  n_fail--;
	}
      op++;
    }
}

static_always_inline void
esp_process_chained_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
			 vnet_crypto_op_t * ops, vlib_buffer_t * b[],
			 u16 * nexts, vnet_crypto_op_chunk_t * chunks, int e)
{

  vnet_crypto_op_t *op = ops;
  u32 n_fail, n_ops = vec_len (ops);

  if (PREDICT_TRUE (n_ops == 0))
    return;

  n_fail = n_ops - vnet_crypto_process_chained_ops (vm, op, chunks, n_ops);

  while (n_fail)
    {
      ASSERT (op - ops < n_ops);
      if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
	{
	  u32 err, bi = op->user_data;
	  if (op->status == VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC)
	    err = e;
	  else
	    err = ESP_DECRYPT_ERROR_CRYPTO_ENGINE_ERROR;
	  b[bi]->error = node->errors[err];
	  nexts[bi] = ESP_DECRYPT_NEXT_DROP;
	  n_fail--;
	}
      op++;
    }
}

always_inline void
esp_remove_tail (vlib_main_t * vm, vlib_buffer_t * b, vlib_buffer_t * last,
		 u16 tail)
{
  vlib_buffer_t *before_last = b;

  if (last->current_length > tail)
    {
      last->current_length -= tail;
      return;
    }
  ASSERT (b->flags & VLIB_BUFFER_NEXT_PRESENT);

  while (b->flags & VLIB_BUFFER_NEXT_PRESENT)
    {
      before_last = b;
      b = vlib_get_buffer (vm, b->next_buffer);
    }
  before_last->current_length -= tail - last->current_length;
  vlib_buffer_free_one (vm, before_last->next_buffer);
  before_last->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
}

/* ICV is splitted in last two buffers so move it to the last buffer and
   return pointer to it */
static_always_inline u8 *
esp_move_icv (vlib_main_t * vm, vlib_buffer_t * first,
	      esp_decrypt_packet_data_t * pd,
	      esp_decrypt_packet_data2_t * pd2, u16 icv_sz, u16 * dif)
{
  vlib_buffer_t *before_last, *bp;
  u16 last_sz = pd2->lb->current_length;
  u16 first_sz = icv_sz - last_sz;

  bp = before_last = first;
  while (bp->flags & VLIB_BUFFER_NEXT_PRESENT)
    {
      before_last = bp;
      bp = vlib_get_buffer (vm, bp->next_buffer);
    }

  u8 *lb_curr = vlib_buffer_get_current (pd2->lb);
  memmove (lb_curr + first_sz, lb_curr, last_sz);
  clib_memcpy_fast (lb_curr, vlib_buffer_get_tail (before_last) - first_sz,
		    first_sz);
  before_last->current_length -= first_sz;
  if (before_last == first)
    pd->current_length -= first_sz;
  clib_memset (vlib_buffer_get_tail (before_last), 0, first_sz);
  if (dif)
    dif[0] = first_sz;
  pd2->lb = before_last;
  pd2->icv_removed = 1;
  pd2->free_buffer_index = before_last->next_buffer;
  before_last->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
  return lb_curr;
}

static_always_inline u16
esp_insert_esn (vlib_main_t *vm, ipsec_sa_t *sa, esp_decrypt_packet_data_t *pd,
		esp_decrypt_packet_data2_t *pd2, u32 *data_len, u8 **digest,
		u16 *len, vlib_buffer_t *b, u8 *payload)
{
  if (!ipsec_sa_is_set_USE_ESN (sa))
    return 0;
  /* shift ICV by 4 bytes to insert ESN */
  u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
  u8 tmp[ESP_MAX_ICV_SIZE];

  if (pd2->icv_removed)
    {
      u16 space_left = vlib_buffer_space_left_at_end (vm, pd2->lb);
      if (space_left >= N_HI_ESN_BYTES)
	{
	  clib_memcpy_fast (vlib_buffer_get_tail (pd2->lb), &seq_hi,
			    N_HI_ESN_BYTES);
	  *data_len += N_HI_ESN_BYTES;
	}
      else
	return N_HI_ESN_BYTES;

      len[0] = b->current_length;
    }
  else
    {
      clib_memcpy_fast (tmp, payload + len[0], ESP_MAX_ICV_SIZE);
      clib_memcpy_fast (payload + len[0], &seq_hi, N_HI_ESN_BYTES);
      clib_memcpy_fast (payload + len[0] + N_HI_ESN_BYTES, tmp,
			ESP_MAX_ICV_SIZE);
      *data_len += N_HI_ESN_BYTES;
      *digest += N_HI_ESN_BYTES;
    }
  return N_HI_ESN_BYTES;
}

static_always_inline u8 *
esp_move_icv_esn (vlib_main_t * vm, vlib_buffer_t * first,
		  esp_decrypt_packet_data_t * pd,
		  esp_decrypt_packet_data2_t * pd2, u16 icv_sz,
		  ipsec_sa_t * sa, u8 * extra_esn, u32 * len)
{
  u16 dif = 0;
  u8 *digest = esp_move_icv (vm, first, pd, pd2, icv_sz, &dif);
  if (dif)
    *len -= dif;

  if (ipsec_sa_is_set_USE_ESN (sa))
    {
      u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
      u16 space_left = vlib_buffer_space_left_at_end (vm, pd2->lb);

      if (space_left >= N_HI_ESN_BYTES)
	{
	  clib_memcpy_fast (vlib_buffer_get_tail (pd2->lb), &seq_hi,
			    N_HI_ESN_BYTES);
	  *len += N_HI_ESN_BYTES;
	}
      else
	{
	  /* no space for ESN at the tail, use the next buffer
	   * (with ICV data) */
	  ASSERT (pd2->icv_removed);
	  vlib_buffer_t *tmp = vlib_get_buffer (vm, pd2->free_buffer_index);
	  clib_memcpy_fast (vlib_buffer_get_current (tmp) - N_HI_ESN_BYTES,
			    &seq_hi, N_HI_ESN_BYTES);
	  extra_esn[0] = 1;
	}
    }
  return digest;
}

static_always_inline int
esp_decrypt_chain_integ (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
			 const esp_decrypt_packet_data_t *pd,
			 esp_decrypt_packet_data2_t *pd2, ipsec_sa_t *sa0,
			 vlib_buffer_t *b, u8 icv_sz, u8 *start_src,
			 u32 start_len, u8 **digest, u16 *n_ch,
			 u32 *integ_total_len)
{
  vnet_crypto_op_chunk_t *ch;
  vlib_buffer_t *cb = vlib_get_buffer (vm, b->next_buffer);
  u16 n_chunks = 1;
  u32 total_len;
  vec_add2 (ptd->chunks, ch, 1);
  total_len = ch->len = start_len;
  ch->src = start_src;

  while (1)
    {
      vec_add2 (ptd->chunks, ch, 1);
      n_chunks += 1;
      ch->src = vlib_buffer_get_current (cb);
      if (pd2->lb == cb)
	{
	  if (pd2->icv_removed)
	    ch->len = cb->current_length;
	  else
	    ch->len = cb->current_length - icv_sz;
	  if (ipsec_sa_is_set_USE_ESN (sa0))
	    {
	      u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
	      u8 tmp[ESP_MAX_ICV_SIZE];
	      u8 *esn;
	      vlib_buffer_t *tmp_b;
	      u16 space_left = vlib_buffer_space_left_at_end (vm, pd2->lb);
	      if (space_left < N_HI_ESN_BYTES)
		{
		  if (pd2->icv_removed)
		    {
		      /* use pre-data area from the last bufer
		         that was removed from the chain */
		      tmp_b = vlib_get_buffer (vm, pd2->free_buffer_index);
		      esn = tmp_b->data - N_HI_ESN_BYTES;
		    }
		  else
		    {
		      /* no space, need to allocate new buffer */
		      u32 tmp_bi = 0;
		      if (vlib_buffer_alloc (vm, &tmp_bi, 1) != 1)
			return -1;
		      tmp_b = vlib_get_buffer (vm, tmp_bi);
		      esn = tmp_b->data;
		      pd2->free_buffer_index = tmp_bi;
		    }
		  clib_memcpy_fast (esn, &seq_hi, N_HI_ESN_BYTES);

		  vec_add2 (ptd->chunks, ch, 1);
		  n_chunks += 1;
		  ch->src = esn;
		  ch->len = N_HI_ESN_BYTES;
		}
	      else
		{
		  if (pd2->icv_removed)
		    {
		      clib_memcpy_fast (vlib_buffer_get_tail (pd2->lb),
					&seq_hi, N_HI_ESN_BYTES);
		    }
		  else
		    {
		      clib_memcpy_fast (tmp, *digest, ESP_MAX_ICV_SIZE);
		      clib_memcpy_fast (*digest, &seq_hi, N_HI_ESN_BYTES);
		      clib_memcpy_fast (*digest + N_HI_ESN_BYTES, tmp,
					ESP_MAX_ICV_SIZE);
		      *digest += N_HI_ESN_BYTES;
		    }
		  ch->len += N_HI_ESN_BYTES;
		}
	    }
	  total_len += ch->len;
	  break;
	}
      else
	total_len += ch->len = cb->current_length;

      if (!(cb->flags & VLIB_BUFFER_NEXT_PRESENT))
	break;

      cb = vlib_get_buffer (vm, cb->next_buffer);
    }

  if (n_ch)
    *n_ch = n_chunks;
  if (integ_total_len)
    *integ_total_len = total_len;

  return 0;
}

static_always_inline u32
esp_decrypt_chain_crypto (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
			  esp_decrypt_packet_data_t * pd,
			  esp_decrypt_packet_data2_t * pd2,
			  ipsec_sa_t * sa0, vlib_buffer_t * b, u8 icv_sz,
			  u8 * start, u32 start_len, u8 ** tag, u16 * n_ch)
{
  vnet_crypto_op_chunk_t *ch;
  vlib_buffer_t *cb = b;
  u16 n_chunks = 1;
  u32 total_len;
  vec_add2 (ptd->chunks, ch, 1);
  total_len = ch->len = start_len;
  ch->src = ch->dst = start;
  cb = vlib_get_buffer (vm, cb->next_buffer);
  n_chunks = 1;

  while (1)
    {
      vec_add2 (ptd->chunks, ch, 1);
      n_chunks += 1;
      ch->src = ch->dst = vlib_buffer_get_current (cb);
      if (pd2->lb == cb)
	{
	  if (ipsec_sa_is_set_IS_AEAD (sa0))
	    {
	      if (pd2->lb->current_length < icv_sz)
		{
		  u16 dif = 0;
		  *tag = esp_move_icv (vm, b, pd, pd2, icv_sz, &dif);

		  /* this chunk does not contain crypto data */
		  n_chunks -= 1;
		  /* and fix previous chunk's length as it might have
		     been changed */
		  ASSERT (n_chunks > 0);
		  if (pd2->lb == b)
		    {
		      total_len -= dif;
		      ch[-1].len -= dif;
		    }
		  else
		    {
		      total_len = total_len + pd2->lb->current_length -
			ch[-1].len;
		      ch[-1].len = pd2->lb->current_length;
		    }
		  break;
		}
	      else
		*tag = vlib_buffer_get_tail (pd2->lb) - icv_sz;
	    }

	  if (pd2->icv_removed)
	    total_len += ch->len = cb->current_length;
	  else
	    total_len += ch->len = cb->current_length - icv_sz;
	}
      else
	total_len += ch->len = cb->current_length;

      if (!(cb->flags & VLIB_BUFFER_NEXT_PRESENT))
	break;

      cb = vlib_get_buffer (vm, cb->next_buffer);
    }

  if (n_ch)
    *n_ch = n_chunks;

  return total_len;
}

static_always_inline void
esp_decrypt_prepare_sync_op (vlib_main_t * vm, vlib_node_runtime_t * node,
			     ipsec_per_thread_data_t * ptd,
			     vnet_crypto_op_t *** crypto_ops,
			     vnet_crypto_op_t *** integ_ops,
			     vnet_crypto_op_t * op,
			     ipsec_sa_t * sa0, u8 * payload,
			     u16 len, u8 icv_sz, u8 iv_sz,
			     esp_decrypt_packet_data_t * pd,
			     esp_decrypt_packet_data2_t * pd2,
			     vlib_buffer_t * b, u16 * next, u32 index)
{
  const u8 esp_sz = sizeof (esp_header_t);

  if (PREDICT_TRUE (sa0->integ_op_id != VNET_CRYPTO_OP_NONE))
    {
      vnet_crypto_op_init (op, sa0->integ_op_id);
      op->key_index = sa0->integ_key_index;
      op->src = payload;
      op->flags = VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
      op->user_data = index;
      op->digest = payload + len;
      op->digest_len = icv_sz;
      op->len = len;

      if (pd->is_chain)
	{
	  /* buffer is chained */
	  op->len = pd->current_length;

	  /* special case when ICV is splitted and needs to be reassembled
	   * first -> move it to the last buffer. Also take into account
	   * that ESN needs to be added after encrypted data and may or
	   * may not fit in the tail.*/
	  if (pd2->lb->current_length < icv_sz)
	    {
	      u8 extra_esn = 0;
	      op->digest =
		esp_move_icv_esn (vm, b, pd, pd2, icv_sz, sa0,
				  &extra_esn, &op->len);

	      if (extra_esn)
		{
		  /* esn is in the last buffer, that was unlinked from
		   * the chain */
		  op->len = b->current_length;
		}
	      else
		{
		  if (pd2->lb == b)
		    {
		      /* we now have a single buffer of crypto data, adjust
		       * the length (second buffer contains only ICV) */
		      *integ_ops = &ptd->integ_ops;
		      *crypto_ops = &ptd->crypto_ops;
		      len = b->current_length;
		      goto out;
		    }
		}
	    }
	  else
	    op->digest = vlib_buffer_get_tail (pd2->lb) - icv_sz;

	  op->flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
	  op->chunk_index = vec_len (ptd->chunks);
	  if (esp_decrypt_chain_integ (vm, ptd, pd, pd2, sa0, b, icv_sz,
				       payload, pd->current_length,
				       &op->digest, &op->n_chunks, 0) < 0)
	    {
	      b->error = node->errors[ESP_DECRYPT_ERROR_NO_BUFFERS];
	      next[0] = ESP_DECRYPT_NEXT_DROP;
	      return;
	    }
	}
      else
	esp_insert_esn (vm, sa0, pd, pd2, &op->len, &op->digest, &len, b,
			payload);
    out:
      vec_add_aligned (*(integ_ops[0]), op, 1, CLIB_CACHE_LINE_BYTES);
    }

  payload += esp_sz;
  len -= esp_sz;

  if (sa0->crypto_dec_op_id != VNET_CRYPTO_OP_NONE)
    {
      vnet_crypto_op_init (op, sa0->crypto_dec_op_id);
      op->key_index = sa0->crypto_key_index;
      op->iv = payload;

      if (ipsec_sa_is_set_IS_CTR (sa0))
	{
	  /* construct nonce in a scratch space in front of the IP header */
	  esp_ctr_nonce_t *nonce =
	    (esp_ctr_nonce_t *) (payload - esp_sz - pd->hdr_sz -
				 sizeof (*nonce));
	  if (ipsec_sa_is_set_IS_AEAD (sa0))
	    {
	      /* constuct aad in a scratch space in front of the nonce */
	      esp_header_t *esp0 = (esp_header_t *) (payload - esp_sz);
	      op->aad = (u8 *) nonce - sizeof (esp_aead_t);
	      op->aad_len = esp_aad_fill (op->aad, esp0, sa0, pd->seq_hi);
	      op->tag = payload + len;
	      op->tag_len = 16;
	    }
	  else
	    {
	      nonce->ctr = clib_host_to_net_u32 (1);
	    }
	  nonce->salt = sa0->salt;
	  ASSERT (sizeof (u64) == iv_sz);
	  nonce->iv = *(u64 *) op->iv;
	  op->iv = (u8 *) nonce;
	}
      op->src = op->dst = payload += iv_sz;
      op->len = len - iv_sz;
      op->user_data = index;

      if (pd->is_chain && (pd2->lb != b))
	{
	  /* buffer is chained */
	  op->flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
	  op->chunk_index = vec_len (ptd->chunks);
	  esp_decrypt_chain_crypto (vm, ptd, pd, pd2, sa0, b, icv_sz,
				    payload, len - pd->iv_sz + pd->icv_sz,
				    &op->tag, &op->n_chunks);
	}

      vec_add_aligned (*(crypto_ops[0]), op, 1, CLIB_CACHE_LINE_BYTES);
    }
}

static_always_inline esp_decrypt_error_t
esp_decrypt_prepare_async_frame (vlib_main_t *vm, vlib_node_runtime_t *node,
				 ipsec_per_thread_data_t *ptd,
				 vnet_crypto_async_frame_t *f, ipsec_sa_t *sa0,
				 u8 *payload, u16 len, u8 icv_sz, u8 iv_sz,
				 esp_decrypt_packet_data_t *pd,
				 esp_decrypt_packet_data2_t *pd2, u32 bi,
				 vlib_buffer_t *b, u16 *next, u16 async_next)
{
  const u8 esp_sz = sizeof (esp_header_t);
  esp_decrypt_packet_data_t *async_pd = &(esp_post_data (b))->decrypt_data;
  esp_decrypt_packet_data2_t *async_pd2 = esp_post_data2 (b);
  u8 *tag = payload + len, *iv = payload + esp_sz, *aad = 0;
  u32 key_index;
  u32 crypto_len, integ_len = 0;
  i16 crypto_start_offset, integ_start_offset = 0;
  u8 flags = 0;

  if (!ipsec_sa_is_set_IS_AEAD (sa0))
    {
      /* linked algs */
      key_index = sa0->linked_key_index;
      integ_start_offset = payload - b->data;
      integ_len = len;
      if (PREDICT_TRUE (sa0->integ_op_id != VNET_CRYPTO_OP_NONE))
	flags |= VNET_CRYPTO_OP_FLAG_HMAC_CHECK;

      if (pd->is_chain)
	{
	  /* buffer is chained */
	  integ_len = pd->current_length;

	  /* special case when ICV is splitted and needs to be reassembled
	   * first -> move it to the last buffer. Also take into account
	   * that ESN needs to be added after encrypted data and may or
	   * may not fit in the tail.*/
	  if (pd2->lb->current_length < icv_sz)
	    {
	      u8 extra_esn = 0;
	      tag = esp_move_icv_esn (vm, b, pd, pd2, icv_sz, sa0,
				      &extra_esn, &integ_len);

	      if (extra_esn)
		{
		  /* esn is in the last buffer, that was unlinked from
		   * the chain */
		  integ_len = b->current_length;
		}
	      else
		{
		  if (pd2->lb == b)
		    {
		      /* we now have a single buffer of crypto data, adjust
		       * the length (second buffer contains only ICV) */
		      len = b->current_length;
		      goto out;
		    }
		}
	    }
	  else
	    tag = vlib_buffer_get_tail (pd2->lb) - icv_sz;

	  flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
	  if (esp_decrypt_chain_integ (vm, ptd, pd, pd2, sa0, b, icv_sz,
				       payload, pd->current_length, &tag, 0,
				       &integ_len) < 0)
	    {
	      /* allocate buffer failed, will not add to frame and drop */
	      return (ESP_DECRYPT_ERROR_NO_BUFFERS);
	    }
	}
      else
	esp_insert_esn (vm, sa0, pd, pd2, &integ_len, &tag, &len, b, payload);
    }
  else
    key_index = sa0->crypto_key_index;

out:
  /* crypto */
  payload += esp_sz;
  len -= esp_sz;
  iv = payload;

  if (ipsec_sa_is_set_IS_CTR (sa0))
    {
      /* construct nonce in a scratch space in front of the IP header */
      esp_ctr_nonce_t *nonce =
	(esp_ctr_nonce_t *) (payload - esp_sz - pd->hdr_sz - sizeof (*nonce));
      if (ipsec_sa_is_set_IS_AEAD (sa0))
	{
	  /* constuct aad in a scratch space in front of the nonce */
	  esp_header_t *esp0 = (esp_header_t *) (payload - esp_sz);
	  aad = (u8 *) nonce - sizeof (esp_aead_t);
	  esp_aad_fill (aad, esp0, sa0, pd->seq_hi);
	  tag = payload + len;
	}
      else
	{
	  nonce->ctr = clib_host_to_net_u32 (1);
	}
      nonce->salt = sa0->salt;
      ASSERT (sizeof (u64) == iv_sz);
      nonce->iv = *(u64 *) iv;
      iv = (u8 *) nonce;
    }

  crypto_start_offset = (payload += iv_sz) - b->data;
  crypto_len = len - iv_sz;

  if (pd->is_chain && (pd2->lb != b))
    {
      /* buffer is chained */
      flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;

      crypto_len = esp_decrypt_chain_crypto (vm, ptd, pd, pd2, sa0, b, icv_sz,
					     payload,
					     len - pd->iv_sz + pd->icv_sz,
					     &tag, 0);
    }

  *async_pd = *pd;
  *async_pd2 = *pd2;

  /* for AEAD integ_len - crypto_len will be negative, it is ok since it
   * is ignored by the engine. */
  vnet_crypto_async_add_to_frame (
    vm, f, key_index, crypto_len, integ_len - crypto_len, crypto_start_offset,
    integ_start_offset, bi, async_next, iv, tag, aad, flags);

  return (ESP_DECRYPT_ERROR_RX_PKTS);
}

static_always_inline void
esp_decrypt_post_crypto (vlib_main_t *vm, const vlib_node_runtime_t *node,
			 const u16 *next_by_next_header,
			 const esp_decrypt_packet_data_t *pd,
			 const esp_decrypt_packet_data2_t *pd2,
			 vlib_buffer_t *b, u16 *next, int is_ip6, int is_tun,
			 int is_async)
{
  ipsec_sa_t *sa0 = ipsec_sa_get (pd->sa_index);
  vlib_buffer_t *lb = b;
  const u8 esp_sz = sizeof (esp_header_t);
  const u8 tun_flags = IPSEC_SA_FLAG_IS_TUNNEL | IPSEC_SA_FLAG_IS_TUNNEL_V6;
  u8 pad_length = 0, next_header = 0;
  u16 icv_sz;

  /*
   * redo the anti-reply check
   * in this frame say we have sequence numbers, s, s+1, s+1, s+1
   * and s and s+1 are in the window. When we did the anti-replay
   * check above we did so against the state of the window (W),
   * after packet s-1. So each of the packets in the sequence will be
   * accepted.
   * This time s will be cheked against Ws-1, s+1 chceked against Ws
   * (i.e. the window state is updated/advnaced)
   * so this time the successive s+! packet will be dropped.
   * This is a consequence of batching the decrypts. If the
   * check-dcrypt-advance process was done for each packet it would
   * be fine. But we batch the decrypts because it's much more efficient
   * to do so in SW and if we offload to HW and the process is async.
   *
   * You're probably thinking, but this means an attacker can send the
   * above sequence and cause VPP to perform decrpyts that will fail,
   * and that's true. But if the attacker can determine s (a valid
   * sequence number in the window) which is non-trivial, it can generate
   * a sequence s, s+1, s+2, s+3, ... s+n and nothing will prevent any
   * implementation, sequential or batching, from decrypting these.
   */
  if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, pd->seq_hi, true,
					   NULL))
    {
      b->error = node->errors[ESP_DECRYPT_ERROR_REPLAY];
      next[0] = ESP_DECRYPT_NEXT_DROP;
      return;
    }

  u64 n_lost =
    ipsec_sa_anti_replay_advance (sa0, vm->thread_index, pd->seq, pd->seq_hi);

  vlib_prefetch_simple_counter (&ipsec_sa_lost_counters, vm->thread_index,
				pd->sa_index);

  if (pd->is_chain)
    {
      lb = pd2->lb;
      icv_sz = pd2->icv_removed ? 0 : pd->icv_sz;
      if (pd2->free_buffer_index)
	{
	  vlib_buffer_free_one (vm, pd2->free_buffer_index);
	  lb->next_buffer = 0;
	}
      if (lb->current_length < sizeof (esp_footer_t) + icv_sz)
	{
	  /* esp footer is either splitted in two buffers or in the before
	   * last buffer */

	  vlib_buffer_t *before_last = b, *bp = b;
	  while (bp->flags & VLIB_BUFFER_NEXT_PRESENT)
	    {
	      before_last = bp;
	      bp = vlib_get_buffer (vm, bp->next_buffer);
	    }
	  u8 *bt = vlib_buffer_get_tail (before_last);

	  if (lb->current_length == icv_sz)
	    {
	      esp_footer_t *f = (esp_footer_t *) (bt - sizeof (*f));
	      pad_length = f->pad_length;
	      next_header = f->next_header;
	    }
	  else
	    {
	      pad_length = (bt - 1)[0];
	      next_header = ((u8 *) vlib_buffer_get_current (lb))[0];
	    }
	}
      else
	{
	  esp_footer_t *f =
	    (esp_footer_t *) (lb->data + lb->current_data +
			      lb->current_length - sizeof (esp_footer_t) -
			      icv_sz);
	  pad_length = f->pad_length;
	  next_header = f->next_header;
	}
    }
  else
    {
      icv_sz = pd->icv_sz;
      esp_footer_t *f =
	(esp_footer_t *) (lb->data + lb->current_data + lb->current_length -
			  sizeof (esp_footer_t) - icv_sz);
      pad_length = f->pad_length;
      next_header = f->next_header;
    }

  u16 adv = pd->iv_sz + esp_sz;
  u16 tail = sizeof (esp_footer_t) + pad_length + icv_sz;
  u16 tail_orig = sizeof (esp_footer_t) + pad_length + pd->icv_sz;
  b->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;

  if ((pd->flags & tun_flags) == 0 && !is_tun)	/* transport mode */
    {
      u8 udp_sz = (is_ip6 == 0 && pd->flags & IPSEC_SA_FLAG_UDP_ENCAP) ?
	sizeof (udp_header_t) : 0;
      u16 ip_hdr_sz = pd->hdr_sz - udp_sz;
      u8 *old_ip = b->data + pd->current_data - ip_hdr_sz - udp_sz;
      u8 *ip = old_ip + adv + udp_sz;

      if (is_ip6 && ip_hdr_sz > 64)
	memmove (ip, old_ip, ip_hdr_sz);
      else
	clib_memcpy_le64 (ip, old_ip, ip_hdr_sz);

      b->current_data = pd->current_data + adv - ip_hdr_sz;
      b->current_length += ip_hdr_sz - adv;
      esp_remove_tail (vm, b, lb, tail);

      if (is_ip6)
	{
	  ip6_header_t *ip6 = (ip6_header_t *) ip;
	  u16 len = clib_net_to_host_u16 (ip6->payload_length);
	  len -= adv + tail_orig;
	  ip6->payload_length = clib_host_to_net_u16 (len);
	  ip6->protocol = next_header;
	  next[0] = ESP_DECRYPT_NEXT_IP6_INPUT;
	}
      else
	{
	  ip4_header_t *ip4 = (ip4_header_t *) ip;
	  ip_csum_t sum = ip4->checksum;
	  u16 len = clib_net_to_host_u16 (ip4->length);
	  len = clib_host_to_net_u16 (len - adv - tail_orig - udp_sz);
	  sum = ip_csum_update (sum, ip4->protocol, next_header,
				ip4_header_t, protocol);
	  sum = ip_csum_update (sum, ip4->length, len, ip4_header_t, length);
	  ip4->checksum = ip_csum_fold (sum);
	  ip4->protocol = next_header;
	  ip4->length = len;
	  next[0] = ESP_DECRYPT_NEXT_IP4_INPUT;
	}
    }
  else
    {
      if (PREDICT_TRUE (next_header == IP_PROTOCOL_IP_IN_IP))
	{
	  next[0] = ESP_DECRYPT_NEXT_IP4_INPUT;
	  b->current_data = pd->current_data + adv;
	  b->current_length = pd->current_length - adv;
	  esp_remove_tail (vm, b, lb, tail);
	}
      else if (next_header == IP_PROTOCOL_IPV6)
	{
	  next[0] = ESP_DECRYPT_NEXT_IP6_INPUT;
	  b->current_data = pd->current_data + adv;
	  b->current_length = pd->current_length - adv;
	  esp_remove_tail (vm, b, lb, tail);
	}
      else if (next_header == IP_PROTOCOL_MPLS_IN_IP)
	{
	  next[0] = ESP_DECRYPT_NEXT_MPLS_INPUT;
	  b->current_data = pd->current_data + adv;
	  b->current_length = pd->current_length - adv;
	  esp_remove_tail (vm, b, lb, tail);
	}
      else if (is_tun && next_header == IP_PROTOCOL_GRE)
	{
	  gre_header_t *gre;

	  b->current_data = pd->current_data + adv;
	  b->current_length = pd->current_length - adv - tail;

	  gre = vlib_buffer_get_current (b);

	  vlib_buffer_advance (b, sizeof (*gre));

	  switch (clib_net_to_host_u16 (gre->protocol))
	    {
	    case GRE_PROTOCOL_teb:
	      vnet_update_l2_len (b);
	      next[0] = ESP_DECRYPT_NEXT_L2_INPUT;
	      break;
	    case GRE_PROTOCOL_ip4:
	      next[0] = ESP_DECRYPT_NEXT_IP4_INPUT;
	      break;
	    case GRE_PROTOCOL_ip6:
	      next[0] = ESP_DECRYPT_NEXT_IP6_INPUT;
	      break;
	    default:
	      b->error = node->errors[ESP_DECRYPT_ERROR_UNSUP_PAYLOAD];
	      next[0] = ESP_DECRYPT_NEXT_DROP;
	      break;
	    }
	}
      else if ((next[0] = vec_elt (next_by_next_header, next_header)) !=
	       (u16) ~0)
	{
	  b->current_data = pd->current_data + adv;
	  b->current_length = pd->current_length - adv;
	  esp_remove_tail (vm, b, lb, tail);
	}
      else
	{
	  next[0] = ESP_DECRYPT_NEXT_DROP;
	  b->error = node->errors[ESP_DECRYPT_ERROR_UNSUP_PAYLOAD];
	  return;
	}

      if (is_tun)
	{
	  if (ipsec_sa_is_set_IS_PROTECT (sa0))
	    {
	      /*
	       * There are two encap possibilities
	       * 1) the tunnel and ths SA are prodiving encap, i.e. it's
	       *   MAC | SA-IP | TUN-IP | ESP | PAYLOAD
	       * implying the SA is in tunnel mode (on a tunnel interface)
	       * 2) only the tunnel provides encap
	       *   MAC | TUN-IP | ESP | PAYLOAD
	       * implying the SA is in transport mode.
	       *
	       * For 2) we need only strip the tunnel encap and we're good.
	       *  since the tunnel and crypto ecnap (int the tun=protect
	       * object) are the same and we verified above that these match
	       * for 1) we need to strip the SA-IP outer headers, to
	       * reveal the tunnel IP and then check that this matches
	       * the configured tunnel.
	       */
	      const ipsec_tun_protect_t *itp;

	      itp =
		ipsec_tun_protect_get (vnet_buffer (b)->ipsec.protect_index);

	      if (PREDICT_TRUE (next_header == IP_PROTOCOL_IP_IN_IP))
		{
		  const ip4_header_t *ip4;

		  ip4 = vlib_buffer_get_current (b);

		  if (!ip46_address_is_equal_v4 (&itp->itp_tun.src,
						 &ip4->dst_address) ||
		      !ip46_address_is_equal_v4 (&itp->itp_tun.dst,
						 &ip4->src_address))
		    {
		      next[0] = ESP_DECRYPT_NEXT_DROP;
		      b->error = node->errors[ESP_DECRYPT_ERROR_TUN_NO_PROTO];
		    }
		}
	      else if (next_header == IP_PROTOCOL_IPV6)
		{
		  const ip6_header_t *ip6;

		  ip6 = vlib_buffer_get_current (b);

		  if (!ip46_address_is_equal_v6 (&itp->itp_tun.src,
						 &ip6->dst_address) ||
		      !ip46_address_is_equal_v6 (&itp->itp_tun.dst,
						 &ip6->src_address))
		    {
		      next[0] = ESP_DECRYPT_NEXT_DROP;
		      b->error = node->errors[ESP_DECRYPT_ERROR_TUN_NO_PROTO];
		    }
		}
	    }
	}
    }

  if (PREDICT_FALSE (n_lost))
    vlib_increment_simple_counter (&ipsec_sa_lost_counters, vm->thread_index,
				   pd->sa_index, n_lost);
}

always_inline uword
esp_decrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
		    vlib_frame_t *from_frame, int is_ip6, int is_tun,
		    u16 async_next_node)
{
  ipsec_main_t *im = &ipsec_main;
  const u16 *next_by_next_header = im->next_header_registrations;
  u32 thread_index = vm->thread_index;
  u16 len;
  ipsec_per_thread_data_t *ptd = vec_elt_at_index (im->ptd, thread_index);
  u32 *from = vlib_frame_vector_args (from_frame);
  u32 n_left = from_frame->n_vectors;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
  vlib_buffer_t *sync_bufs[VLIB_FRAME_SIZE];
  u16 sync_nexts[VLIB_FRAME_SIZE], *sync_next = sync_nexts, n_sync = 0;
  u16 async_nexts[VLIB_FRAME_SIZE], *async_next = async_nexts;
  u16 noop_nexts[VLIB_FRAME_SIZE], *noop_next = noop_nexts, n_noop = 0;
  u32 sync_bi[VLIB_FRAME_SIZE];
  u32 noop_bi[VLIB_FRAME_SIZE];
  esp_decrypt_packet_data_t pkt_data[VLIB_FRAME_SIZE], *pd = pkt_data;
  esp_decrypt_packet_data2_t pkt_data2[VLIB_FRAME_SIZE], *pd2 = pkt_data2;
  esp_decrypt_packet_data_t cpd = { };
  u32 current_sa_index = ~0, current_sa_bytes = 0, current_sa_pkts = 0;
  const u8 esp_sz = sizeof (esp_header_t);
  ipsec_sa_t *sa0 = 0;
  vnet_crypto_op_t _op, *op = &_op;
  vnet_crypto_op_t **crypto_ops;
  vnet_crypto_op_t **integ_ops;
  int is_async = im->async_mode;
  vnet_crypto_async_op_id_t async_op = ~0;
  vnet_crypto_async_frame_t *async_frames[VNET_CRYPTO_ASYNC_OP_N_IDS];
  esp_decrypt_error_t err;

  vlib_get_buffers (vm, from, b, n_left);
  if (!is_async)
    {
      vec_reset_length (ptd->crypto_ops);
      vec_reset_length (ptd->integ_ops);
      vec_reset_length (ptd->chained_crypto_ops);
      vec_reset_length (ptd->chained_integ_ops);
    }
  vec_reset_length (ptd->async_frames);
  vec_reset_length (ptd->chunks);
  clib_memset (sync_nexts, -1, sizeof (sync_nexts));
  clib_memset (async_frames, 0, sizeof (async_frames));

  while (n_left > 0)
    {
      u8 *payload;

      err = ESP_DECRYPT_ERROR_RX_PKTS;
      if (n_left > 2)
	{
	  u8 *p;
	  vlib_prefetch_buffer_header (b[2], LOAD);
	  p = vlib_buffer_get_current (b[1]);
	  clib_prefetch_load (p);
	  p -= CLIB_CACHE_LINE_BYTES;
	  clib_prefetch_load (p);
	}

      u32 n_bufs = vlib_buffer_chain_linearize (vm, b[0]);
      if (n_bufs == 0)
	{
	  err = ESP_DECRYPT_ERROR_NO_BUFFERS;
	  esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
			      ESP_DECRYPT_NEXT_DROP);
	  goto next;
	}

      if (vnet_buffer (b[0])->ipsec.sad_index != current_sa_index)
	{
	  if (current_sa_pkts)
	    vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
					     current_sa_index,
					     current_sa_pkts,
					     current_sa_bytes);
	  current_sa_bytes = current_sa_pkts = 0;

	  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
	  sa0 = ipsec_sa_get (current_sa_index);

	  /* fetch the second cacheline ASAP */
	  clib_prefetch_load (sa0->cacheline1);
	  cpd.icv_sz = sa0->integ_icv_size;
	  cpd.iv_sz = sa0->crypto_iv_size;
	  cpd.flags = sa0->flags;
	  cpd.sa_index = current_sa_index;
	  is_async = im->async_mode | ipsec_sa_is_set_IS_ASYNC (sa0);
	}

      if (PREDICT_FALSE (~0 == sa0->thread_index))
	{
	  /* this is the first packet to use this SA, claim the SA
	   * for this thread. this could happen simultaneously on
	   * another thread */
	  clib_atomic_cmp_and_swap (&sa0->thread_index, ~0,
				    ipsec_sa_assign_thread (thread_index));
	}

      if (PREDICT_FALSE (thread_index != sa0->thread_index))
	{
	  vnet_buffer (b[0])->ipsec.thread_index = sa0->thread_index;
	  err = ESP_DECRYPT_ERROR_HANDOFF;
	  esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
			      ESP_DECRYPT_NEXT_HANDOFF);
	  goto next;
	}

      /* store packet data for next round for easier prefetch */
      pd->sa_data = cpd.sa_data;
      pd->current_data = b[0]->current_data;
      pd->hdr_sz = pd->current_data - vnet_buffer (b[0])->l3_hdr_offset;
      payload = b[0]->data + pd->current_data;
      pd->seq = clib_host_to_net_u32 (((esp_header_t *) payload)->seq);
      pd->is_chain = 0;
      pd2->lb = b[0];
      pd2->free_buffer_index = 0;
      pd2->icv_removed = 0;

      if (n_bufs > 1)
	{
	  pd->is_chain = 1;
	  /* find last buffer in the chain */
	  while (pd2->lb->flags & VLIB_BUFFER_NEXT_PRESENT)
	    pd2->lb = vlib_get_buffer (vm, pd2->lb->next_buffer);

	  crypto_ops = &ptd->chained_crypto_ops;
	  integ_ops = &ptd->chained_integ_ops;
	}
      else
	{
	  crypto_ops = &ptd->crypto_ops;
	  integ_ops = &ptd->integ_ops;
	}

      pd->current_length = b[0]->current_length;

      /* anti-reply check */
      if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, ~0, false,
					       &pd->seq_hi))
	{
	  err = ESP_DECRYPT_ERROR_REPLAY;
	  esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
			      ESP_DECRYPT_NEXT_DROP);
	  goto next;
	}

      if (pd->current_length < cpd.icv_sz + esp_sz + cpd.iv_sz)
	{
	  err = ESP_DECRYPT_ERROR_RUNT;
	  esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
			      ESP_DECRYPT_NEXT_DROP);
	  goto next;
	}

      len = pd->current_length - cpd.icv_sz;
      current_sa_pkts += 1;
      current_sa_bytes += vlib_buffer_length_in_chain (vm, b[0]);

      if (is_async)
	{
	  async_op = sa0->crypto_async_dec_op_id;

	  /* get a frame for this op if we don't yet have one or it's full
	   */
	  if (NULL == async_frames[async_op] ||
	      vnet_crypto_async_frame_is_full (async_frames[async_op]))
	    {
	      async_frames[async_op] =
		vnet_crypto_async_get_frame (vm, async_op);
	      /* Save the frame to the list we'll submit at the end */
	      vec_add1 (ptd->async_frames, async_frames[async_op]);
	    }

	  err = esp_decrypt_prepare_async_frame (
	    vm, node, ptd, async_frames[async_op], sa0, payload, len,
	    cpd.icv_sz, cpd.iv_sz, pd, pd2, from[b - bufs], b[0], async_next,
	    async_next_node);
	  if (ESP_DECRYPT_ERROR_RX_PKTS != err)
	    {
	      esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
				  ESP_DECRYPT_NEXT_DROP);
	    }
	}
      else
	esp_decrypt_prepare_sync_op (
	  vm, node, ptd, &crypto_ops, &integ_ops, op, sa0, payload, len,
	  cpd.icv_sz, cpd.iv_sz, pd, pd2, b[0], sync_next, b - bufs);
      /* next */
    next:
      if (ESP_DECRYPT_ERROR_RX_PKTS != err)
	{
	  noop_bi[n_noop] = from[b - bufs];
	  n_noop++;
	  noop_next++;
	}
      else if (!is_async)
	{
	  sync_bi[n_sync] = from[b - bufs];
	  sync_bufs[n_sync] = b[0];
	  n_sync++;
	  sync_next++;
	  pd += 1;
	  pd2 += 1;
	}
      else
	async_next++;

      n_left -= 1;
      b += 1;
    }

  if (PREDICT_TRUE (~0 != current_sa_index))
    vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
				     current_sa_index, current_sa_pkts,
				     current_sa_bytes);

  /* submit or free all of the open frames */
  vnet_crypto_async_frame_t **async_frame;

  vec_foreach (async_frame, ptd->async_frames)
    {
      /* free frame and move on if no ops were successfully added */
      if (PREDICT_FALSE (!(*async_frame)->n_elts))
	{
	  vnet_crypto_async_free_frame (vm, *async_frame);
	  continue;
	}
      if (vnet_crypto_async_submit_open_frame (vm, *async_frame) < 0)
	{
	  n_noop += esp_async_recycle_failed_submit (
	    vm, *async_frame, node, ESP_DECRYPT_ERROR_CRYPTO_ENGINE_ERROR,
	    n_noop, noop_bi, noop_nexts, ESP_DECRYPT_NEXT_DROP);
	  vnet_crypto_async_reset_frame (*async_frame);
	  vnet_crypto_async_free_frame (vm, *async_frame);
	}
    }

  if (n_sync)
    {
      esp_process_ops (vm, node, ptd->integ_ops, sync_bufs, sync_nexts,
		       ESP_DECRYPT_ERROR_INTEG_ERROR);
      esp_process_chained_ops (vm, node, ptd->chained_integ_ops, sync_bufs,
			       sync_nexts, ptd->chunks,
			       ESP_DECRYPT_ERROR_INTEG_ERROR);

      esp_process_ops (vm, node, ptd->crypto_ops, sync_bufs, sync_nexts,
		       ESP_DECRYPT_ERROR_DECRYPTION_FAILED);
      esp_process_chained_ops (vm, node, ptd->chained_crypto_ops, sync_bufs,
			       sync_nexts, ptd->chunks,
			       ESP_DECRYPT_ERROR_DECRYPTION_FAILED);
    }

  /* Post decryption ronud - adjust packet data start and length and next
     node */

  n_left = n_sync;
  sync_next = sync_nexts;
  pd = pkt_data;
  pd2 = pkt_data2;
  b = sync_bufs;

  while (n_left)
    {
      if (n_left >= 2)
	{
	  void *data = b[1]->data + pd[1].current_data;

	  /* buffer metadata */
	  vlib_prefetch_buffer_header (b[1], LOAD);

	  /* esp_footer_t */
	  CLIB_PREFETCH (data + pd[1].current_length - pd[1].icv_sz - 2,
			 CLIB_CACHE_LINE_BYTES, LOAD);

	  /* packet headers */
	  CLIB_PREFETCH (data - CLIB_CACHE_LINE_BYTES,
			 CLIB_CACHE_LINE_BYTES * 2, LOAD);
	}

      /* save the sa_index as GRE_teb post_crypto changes L2 opaque */
      if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
	current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;

      if (sync_next[0] >= ESP_DECRYPT_N_NEXT)
	esp_decrypt_post_crypto (vm, node, next_by_next_header, pd, pd2, b[0],
				 sync_next, is_ip6, is_tun, 0);

      /* trace: */
      if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
	{
	  esp_decrypt_trace_t *tr;
	  tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
	  sa0 = ipsec_sa_get (current_sa_index);
	  tr->crypto_alg = sa0->crypto_alg;
	  tr->integ_alg = sa0->integ_alg;
	  tr->seq = pd->seq;
	  tr->sa_seq = sa0->seq;
	  tr->sa_seq_hi = sa0->seq_hi;
	  tr->pkt_seq_hi = pd->seq_hi;
	}

      /* next */
      n_left -= 1;
      sync_next += 1;
      pd += 1;
      pd2 += 1;
      b += 1;
    }

  vlib_node_increment_counter (vm, node->node_index, ESP_DECRYPT_ERROR_RX_PKTS,
			       from_frame->n_vectors);

  if (n_sync)
    vlib_buffer_enqueue_to_next (vm, node, sync_bi, sync_nexts, n_sync);

  if (n_noop)
    vlib_buffer_enqueue_to_next (vm, node, noop_bi, noop_nexts, n_noop);

  return (from_frame->n_vectors);
}

always_inline uword
esp_decrypt_post_inline (vlib_main_t * vm,
			 vlib_node_runtime_t * node,
			 vlib_frame_t * from_frame, int is_ip6, int is_tun)
{
  const ipsec_main_t *im = &ipsec_main;
  const u16 *next_by_next_header = im->next_header_registrations;
  u32 *from = vlib_frame_vector_args (from_frame);
  u32 n_left = from_frame->n_vectors;
  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
  vlib_get_buffers (vm, from, b, n_left);

  while (n_left > 0)
    {
      esp_decrypt_packet_data_t *pd = &(esp_post_data (b[0]))->decrypt_data;

      if (n_left > 2)
	{
	  vlib_prefetch_buffer_header (b[2], LOAD);
	  vlib_prefetch_buffer_header (b[1], LOAD);
	}

      if (!pd->is_chain)
	esp_decrypt_post_crypto (vm, node, next_by_next_header, pd, 0, b[0],
				 next, is_ip6, is_tun, 1);
      else
	{
	  esp_decrypt_packet_data2_t *pd2 = esp_post_data2 (b[0]);
	  esp_decrypt_post_crypto (vm, node, next_by_next_header, pd, pd2,
				   b[0], next, is_ip6, is_tun, 1);
	}

      /*trace: */
      if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
	{
	  ipsec_sa_t *sa0 = ipsec_sa_get (pd->sa_index);
	  esp_decrypt_trace_t *tr;
	  esp_decrypt_packet_data_t *async_pd =
	    &(esp_post_data (b[0]))->decrypt_data;
	  tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
	  sa0 = ipsec_sa_get (async_pd->sa_index);

	  tr->crypto_alg = sa0->crypto_alg;
	  tr->integ_alg = sa0->integ_alg;
	  tr->seq = pd->seq;
	  tr->sa_seq = sa0->seq;
	  tr->sa_seq_hi = sa0->seq_hi;
	}

      n_left--;
      next++;
      b++;
    }

  n_left = from_frame->n_vectors;
  vlib_node_increment_counter (vm, node->node_index,
			       ESP_DECRYPT_ERROR_RX_POST_PKTS, n_left);

  vlib_buffer_enqueue_to_next (vm, node, from, nexts, n_left);

  return n_left;
}

VLIB_NODE_FN (esp4_decrypt_node) (vlib_main_t * vm,
				  vlib_node_runtime_t * node,
				  vlib_frame_t * from_frame)
{
  return esp_decrypt_inline (vm, node, from_frame, 0, 0,
			     esp_decrypt_async_next.esp4_post_next);
}

VLIB_NODE_FN (esp4_decrypt_post_node) (vlib_main_t * vm,
				       vlib_node_runtime_t * node,
				       vlib_frame_t * from_frame)
{
  return esp_decrypt_post_inline (vm, node, from_frame, 0, 0);
}

VLIB_NODE_FN (esp4_decrypt_tun_node) (vlib_main_t * vm,
				      vlib_node_runtime_t * node,
				      vlib_frame_t * from_frame)
{
  return esp_decrypt_inline (vm, node, from_frame, 0, 1,
			     esp_decrypt_async_next.esp4_tun_post_next);
}

VLIB_NODE_FN (esp4_decrypt_tun_post_node) (vlib_main_t * vm,
					   vlib_node_runtime_t * node,
					   vlib_frame_t * from_frame)
{
  return esp_decrypt_post_inline (vm, node, from_frame, 0, 1);
}

VLIB_NODE_FN (esp6_decrypt_node) (vlib_main_t * vm,
				  vlib_node_runtime_t * node,
				  vlib_frame_t * from_frame)
{
  return esp_decrypt_inline (vm, node, from_frame, 1, 0,
			     esp_decrypt_async_next.esp6_post_next);
}

VLIB_NODE_FN (esp6_decrypt_post_node) (vlib_main_t * vm,
				       vlib_node_runtime_t * node,
				       vlib_frame_t * from_frame)
{
  return esp_decrypt_post_inline (vm, node, from_frame, 1, 0);
}

VLIB_NODE_FN (esp6_decrypt_tun_node) (vlib_main_t * vm,
				      vlib_node_runtime_t * node,
				      vlib_frame_t * from_frame)
{
  return esp_decrypt_inline (vm, node, from_frame, 1, 1,
			     esp_decrypt_async_next.esp6_tun_post_next);
}

VLIB_NODE_FN (esp6_decrypt_tun_post_node) (vlib_main_t * vm,
					   vlib_node_runtime_t * node,
					   vlib_frame_t * from_frame)
{
  return esp_decrypt_post_inline (vm, node, from_frame, 1, 1);
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (esp4_decrypt_node) = {
  .name = "esp4-decrypt",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .n_next_nodes = ESP_DECRYPT_N_NEXT,
  .next_nodes = {
    [ESP_DECRYPT_NEXT_DROP] = "ip4-drop",
    [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
    [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
    [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-drop",
    [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
    [ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-handoff",
  },
};

VLIB_REGISTER_NODE (esp4_decrypt_post_node) = {
  .name = "esp4-decrypt-post",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .sibling_of = "esp4-decrypt",
};

VLIB_REGISTER_NODE (esp6_decrypt_node) = {
  .name = "esp6-decrypt",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .n_next_nodes = ESP_DECRYPT_N_NEXT,
  .next_nodes = {
    [ESP_DECRYPT_NEXT_DROP] = "ip6-drop",
    [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
    [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
    [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-drop",
    [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
    [ESP_DECRYPT_NEXT_HANDOFF]=  "esp6-decrypt-handoff",
  },
};

VLIB_REGISTER_NODE (esp6_decrypt_post_node) = {
  .name = "esp6-decrypt-post",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .sibling_of = "esp6-decrypt",
};

VLIB_REGISTER_NODE (esp4_decrypt_tun_node) = {
  .name = "esp4-decrypt-tun",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,
  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,
  .n_next_nodes = ESP_DECRYPT_N_NEXT,
  .next_nodes = {
    [ESP_DECRYPT_NEXT_DROP] = "ip4-drop",
    [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
    [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
    [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-input",
    [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
    [ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-tun-handoff",
  },
};

VLIB_REGISTER_NODE (esp4_decrypt_tun_post_node) = {
  .name = "esp4-decrypt-tun-post",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .sibling_of = "esp4-decrypt-tun",
};

VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = {
  .name = "esp6-decrypt-tun",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,
  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,
  .n_next_nodes = ESP_DECRYPT_N_NEXT,
  .next_nodes = {
    [ESP_DECRYPT_NEXT_DROP] = "ip6-drop",
    [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
    [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
    [ESP_DECRYPT_NEXT_MPLS_INPUT] = "mpls-input",
    [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input",
    [ESP_DECRYPT_NEXT_HANDOFF]=  "esp6-decrypt-tun-handoff",
  },
};

VLIB_REGISTER_NODE (esp6_decrypt_tun_post_node) = {
  .name = "esp6-decrypt-tun-post",
  .vector_size = sizeof (u32),
  .format_trace = format_esp_decrypt_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
  .error_strings = esp_decrypt_error_strings,

  .sibling_of = "esp6-decrypt-tun",
};
/* *INDENT-ON* */

#ifndef CLIB_MARCH_VARIANT

static clib_error_t *
esp_decrypt_init (vlib_main_t *vm)
{
  ipsec_main_t *im = &ipsec_main;

  im->esp4_dec_fq_index =
    vlib_frame_queue_main_init (esp4_decrypt_node.index, 0);
  im->esp6_dec_fq_index =
    vlib_frame_queue_main_init (esp6_decrypt_node.index, 0);
  im->esp4_dec_tun_fq_index =
    vlib_frame_queue_main_init (esp4_decrypt_tun_node.index, 0);
  im->esp6_dec_tun_fq_index =
    vlib_frame_queue_main_init (esp6_decrypt_tun_node.index, 0);

  return 0;
}

VLIB_INIT_FUNCTION (esp_decrypt_init);

#endif

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