- u32 i_bi0;
- u32 next0;
- vlib_buffer_t *i_b0;
- ah_header_t *ah0;
- ipsec_sa_t *sa0;
- u32 sa_index0 = ~0;
- u32 seq;
- ip4_header_t *ih4 = 0, *oh4 = 0;
- ip6_header_t *ih6 = 0, *oh6 = 0;
- u8 ip_hdr_size = 0;
- u8 tos = 0;
- u8 ttl = 0;
- u32 ip_version_traffic_class_and_flow_label = 0;
- u8 hop_limit = 0;
- u8 nexthdr = 0;
- u8 icv_padding_len = 0;
-
-
- i_bi0 = from[0];
- from += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- next0 = AH_DECRYPT_NEXT_DROP;
-
- i_b0 = vlib_get_buffer (vm, i_bi0);
- to_next[0] = i_bi0;
- to_next += 1;
- ih4 = vlib_buffer_get_current (i_b0);
- ih6 = vlib_buffer_get_current (i_b0);
- sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
- sa0 = pool_elt_at_index (im->sad, sa_index0);
+ ip6_ext_header_t *prev = NULL;
+ ah0 =
+ ip6_ext_header_find (vm, b[0], ih6, IP_PROTOCOL_IPSEC_AH, &prev);
+ pd->ip_hdr_size = sizeof (ip6_header_t);
+ ASSERT ((u8 *) ah0 - (u8 *) ih6 == pd->ip_hdr_size);
+ }
+ else
+ {
+ if (ip4_is_fragment (ih4))
+ {
+ b[0]->error = node->errors[AH_DECRYPT_ERROR_DROP_FRAGMENTS];
+ next[0] = AH_DECRYPT_NEXT_DROP;
+ goto next;
+ }
+ pd->ip_hdr_size = ip4_header_bytes (ih4);
+ ah0 = (ah_header_t *) ((u8 *) ih4 + pd->ip_hdr_size);
+ }
+
+ 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);