+ pd->seq = clib_host_to_net_u32 (ah0->seq_no);
+
+ /* anti-replay check */
+ if (ipsec_sa_anti_replay_check (sa0, pd->seq))
+ {
+ b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
+ next[0] = AH_DECRYPT_NEXT_DROP;
+ goto next;
+ }
+
+ current_sa_bytes += b[0]->current_length;
+ current_sa_pkts += 1;
+
+ pd->icv_size = sa0->integ_icv_size;
+ pd->nexthdr_cached = ah0->nexthdr;
+ if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
+ {
+ if (PREDICT_FALSE (ipsec_sa_is_set_USE_ESN (sa0) &&
+ pd->current_data + b[0]->current_length
+ + sizeof (u32) > buffer_data_size))
+ {
+ b[0]->error = node->errors[AH_DECRYPT_ERROR_NO_TAIL_SPACE];
+ next[0] = AH_DECRYPT_NEXT_DROP;
+ goto next;
+ }
+
+ 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_id);
+
+ op->src = (u8 *) ih4;
+ op->len = b[0]->current_length;
+ op->digest = (u8 *) ih4 - pd->icv_size;
+ op->flags = VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
+ op->digest_len = pd->icv_size;
+ op->key_index = sa0->integ_key_index;
+ op->user_data = b - bufs;
+ if (ipsec_sa_is_set_USE_ESN (sa0))
+ {
+ u32 seq_hi = clib_host_to_net_u32 (sa0->seq_hi);
+
+ op->len += sizeof (seq_hi);
+ clib_memcpy (op->src + b[0]->current_length, &seq_hi,
+ sizeof (seq_hi));
+ }
+ clib_memcpy (op->digest, ah0->auth_data, pd->icv_size);
+ clib_memset (ah0->auth_data, 0, pd->icv_size);