+ /* we need 4 extra bytes for HMAC calculation when ESN are used */
+ if ((sa0->flags & IPSEC_SA_FLAG_USE_ESN) && pd->icv_sz &&
+ (pd->current_data + pd->current_length + 4 > buffer_data_size))
+ {
+ b[0]->error = node->errors[ESP_DECRYPT_ERROR_NO_TAIL_SPACE];
+ next[0] = ESP_DECRYPT_NEXT_DROP;
+ goto next;
+ }
+
+ /* anti-reply check */
+ if (ipsec_sa_anti_replay_check (sa0, &((esp_header_t *) payload)->seq))
+ {
+ b[0]->error = node->errors[ESP_DECRYPT_ERROR_REPLAY];
+ next[0] = ESP_DECRYPT_NEXT_DROP;
+ goto next;
+ }
+
+ len = pd->current_length - cpd.icv_sz;
+ current_sa_pkts += 1;
+ current_sa_bytes += pd->current_length;
+
+ if (PREDICT_TRUE (cpd.icv_sz > 0))
+ {
+ vnet_crypto_op_t *op;
+ vec_add2_aligned (ptd->integ_ops, op, 1, CLIB_CACHE_LINE_BYTES);
+
+ vnet_crypto_op_init (op, sa0->integ_op_type);
+ op->key = sa0->integ_key.data;
+ op->key_len = sa0->integ_key.len;
+ op->src = payload;
+ op->hmac_trunc_len = cpd.icv_sz;
+ op->flags = VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
+ op->user_data = b - bufs;
+ op->dst = payload + len;
+ op->len = len;
+ if (PREDICT_TRUE (sa0->flags & IPSEC_SA_FLAG_USE_ESN))