#include <vnet/ipsec/esp.h>
#include <vnet/ipsec/ah.h>
#include <vnet/ipsec/ipsec_io.h>
+#include <vnet/ipsec/ipsec.api_enum.h>
#define foreach_ah_decrypt_next \
_(DROP, "error-drop") \
AH_DECRYPT_N_NEXT,
} ah_decrypt_next_t;
-#define foreach_ah_decrypt_error \
- _ (RX_PKTS, "AH pkts received") \
- _ (DECRYPTION_FAILED, "AH decryption failed") \
- _ (INTEG_ERROR, "Integrity check failed") \
- _ (NO_TAIL_SPACE, "not enough buffer tail space (dropped)") \
- _ (DROP_FRAGMENTS, "IP fragments drop") \
- _ (REPLAY, "SA replayed packet")
-
-typedef enum
-{
-#define _(sym,str) AH_DECRYPT_ERROR_##sym,
- foreach_ah_decrypt_error
-#undef _
- AH_DECRYPT_N_ERROR,
-} ah_decrypt_error_t;
-
-static char *ah_decrypt_error_strings[] = {
-#define _(sym,string) string,
- foreach_ah_decrypt_error
-#undef _
-};
-
typedef struct
{
ipsec_integ_alg_t integ_alg;
};
u32 sa_index;
u32 seq;
+ u32 seq_hi;
u8 icv_padding_len;
u8 icv_size;
u8 ip_hdr_size;
current_sa_pkts,
current_sa_bytes);
current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
- sa0 = pool_elt_at_index (im->sad, current_sa_index);
+ sa0 = ipsec_sa_get (current_sa_index);
current_sa_bytes = current_sa_pkts = 0;
vlib_prefetch_combined_counter (&ipsec_sa_counters,
pd->seq = clib_host_to_net_u32 (ah0->seq_no);
/* anti-replay check */
- if (ipsec_sa_anti_replay_check (sa0, pd->seq))
+ if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, ~0, false,
+ &pd->seq_hi))
{
b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
next[0] = AH_DECRYPT_NEXT_DROP;
op->user_data = b - bufs;
if (ipsec_sa_is_set_USE_ESN (sa0))
{
- u32 seq_hi = clib_host_to_net_u32 (sa0->seq_hi);
+ u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
op->len += sizeof (seq_hi);
clib_memcpy (op->src + b[0]->current_length, &seq_hi,
{
ip4_header_t *oh4;
ip6_header_t *oh6;
+ u64 n_lost = 0;
if (next[0] < AH_DECRYPT_N_NEXT)
goto trace;
- sa0 = vec_elt_at_index (im->sad, pd->sa_index);
+ sa0 = ipsec_sa_get (pd->sa_index);
if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
{
- /* redo the anit-reply check. see esp_decrypt for details */
- if (ipsec_sa_anti_replay_check (sa0, pd->seq))
+ /* redo the anti-reply check. see esp_decrypt for details */
+ if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, pd->seq_hi,
+ true, NULL))
{
b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
next[0] = AH_DECRYPT_NEXT_DROP;
goto trace;
}
- ipsec_sa_anti_replay_advance (sa0, pd->seq);
+ n_lost = ipsec_sa_anti_replay_advance (sa0, thread_index, pd->seq,
+ pd->seq_hi);
+ vlib_prefetch_simple_counter (&ipsec_sa_lost_counters, thread_index,
+ pd->sa_index);
}
u16 ah_hdr_len = sizeof (ah_header_t) + pd->icv_size
}
}
+ if (PREDICT_FALSE (n_lost))
+ vlib_increment_simple_counter (&ipsec_sa_lost_counters, thread_index,
+ pd->sa_index, n_lost);
+
vnet_buffer (b[0])->sw_if_index[VLIB_TX] = (u32) ~ 0;
trace:
if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
{
- sa0 = pool_elt_at_index (im->sad,
- vnet_buffer (b[0])->ipsec.sad_index);
+ sa0 = ipsec_sa_get (vnet_buffer (b[0])->ipsec.sad_index);
ah_decrypt_trace_t *tr =
vlib_add_trace (vm, node, b[0], sizeof (*tr));
tr->integ_alg = sa0->integ_alg;
.format_trace = format_ah_decrypt_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
- .error_strings = ah_decrypt_error_strings,
+ .n_errors = AH_DECRYPT_N_ERROR,
+ .error_counters = ah_decrypt_error_counters,
.n_next_nodes = AH_DECRYPT_N_NEXT,
.next_nodes = {
.format_trace = format_ah_decrypt_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
- .error_strings = ah_decrypt_error_strings,
+ .n_errors = AH_DECRYPT_N_ERROR,
+ .error_counters = ah_decrypt_error_counters,
.n_next_nodes = AH_DECRYPT_N_NEXT,
.next_nodes = {
};
/* *INDENT-ON* */
+#ifndef CLIB_MARCH_VARIANT
+
+static clib_error_t *
+ah_decrypt_init (vlib_main_t *vm)
+{
+ ipsec_main_t *im = &ipsec_main;
+
+ im->ah4_dec_fq_index =
+ vlib_frame_queue_main_init (ah4_decrypt_node.index, 0);
+ im->ah6_dec_fq_index =
+ vlib_frame_queue_main_init (ah6_decrypt_node.index, 0);
+
+ return 0;
+}
+
+VLIB_INIT_FUNCTION (ah_decrypt_init);
+
+#endif
+
/*
* fd.io coding-style-patch-verification: ON
*