ipsec: fix protect update log if nexthop is NULL
[vpp.git] / src / vnet / ipsec / ah_decrypt.c
index 03a9dc8..1ad372a 100644 (file)
@@ -98,6 +98,7 @@ typedef struct
   };
   u32 sa_index;
   u32 seq;
+  u32 seq_hi;
   u8 icv_padding_len;
   u8 icv_size;
   u8 ip_hdr_size;
@@ -169,7 +170,7 @@ ah_decrypt_inline (vlib_main_t * vm,
                                             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,
@@ -187,6 +188,7 @@ ah_decrypt_inline (vlib_main_t * vm,
 
       if (PREDICT_TRUE (thread_index != sa0->thread_index))
        {
+         vnet_buffer (b[0])->ipsec.thread_index = sa0->thread_index;
          next[0] = AH_DECRYPT_NEXT_HANDOFF;
          goto next;
        }
@@ -220,7 +222,8 @@ ah_decrypt_inline (vlib_main_t * vm,
       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;
@@ -256,7 +259,7 @@ ah_decrypt_inline (vlib_main_t * vm,
          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,
@@ -312,22 +315,27 @@ ah_decrypt_inline (vlib_main_t * vm,
     {
       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
@@ -394,12 +402,15 @@ ah_decrypt_inline (vlib_main_t * vm,
            }
        }
 
+      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;
@@ -472,6 +483,25 @@ VLIB_REGISTER_NODE (ah6_decrypt_node) = {
 };
 /* *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
  *