ipsec: store anti_replay_window_size in runtime data 64/42364/2
authorDamjan Marion <[email protected]>
Thu, 13 Feb 2025 15:39:35 +0000 (16:39 +0100)
committerDamjan Marion <[email protected]>
Thu, 13 Feb 2025 22:35:48 +0000 (23:35 +0100)
Type: improvement
Change-Id: I0626af365855ad5301419e72e9430a47a5d0e5d7
Signed-off-by: Damjan Marion <[email protected]>
src/vnet/ipsec/ipsec_api.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_sa.c
src/vnet/ipsec/ipsec_sa.h

index 262a8cb..7833c3d 100644 (file)
@@ -1361,7 +1361,7 @@ send_ipsec_sa_v5_details (ipsec_sa_t *sa, void *arg)
       mp->replay_window =
        clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (irt));
       mp->entry.anti_replay_window_size =
-       clib_host_to_net_u32 (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (irt));
+       clib_host_to_net_u32 (irt->anti_replay_window_size);
     }
 
   if (ort)
index 0bbdc85..5d32c69 100644 (file)
@@ -479,8 +479,7 @@ format_ipsec_sa (u8 * s, va_list * args)
     s = format (s, "\n   outbound seq %lu", ort->seq64);
   if (irt)
     {
-      s = format (s, "\n   window-size: %llu",
-                 IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (irt));
+      s = format (s, "\n   window-size: %llu", irt->anti_replay_window_size);
       s = format (s, "\n   window: Bl <- %U Tl", format_ipsec_replay_window,
                  ipsec_sa_anti_replay_get_64b_window (irt));
     }
index eb4270a..cadd08b 100644 (file)
@@ -427,6 +427,7 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
   clib_error_t *err;
   ipsec_sa_t *sa;
   u32 sa_index;
+  u16 thread_index = (vlib_num_workers ()) ? ~0 : 0;
   u64 rand[2];
   uword *p;
   int rv;
@@ -440,17 +441,34 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
 
   pool_get_aligned_zero (im->sa_pool, sa, CLIB_CACHE_LINE_BYTES);
   sa_index = sa - im->sa_pool;
+  sa->flags = flags;
+
   vec_validate (im->inb_sa_runtimes, sa_index);
   vec_validate (im->outb_sa_runtimes, sa_index);
 
+  if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa) && anti_replay_window_size > 64)
+    {
+      ipsec_sa_set_ANTI_REPLAY_HUGE (sa);
+      anti_replay_window_size = 1 << max_log2 (anti_replay_window_size);
+    }
+  else
+    anti_replay_window_size = BITS (irt->replay_window);
+
   irt = clib_mem_alloc_aligned (sizeof (ipsec_sa_inb_rt_t),
-                               _Alignof (ipsec_sa_inb_rt_t));
+                               alignof (ipsec_sa_inb_rt_t));
   ort = clib_mem_alloc_aligned (sizeof (ipsec_sa_outb_rt_t),
-                               _Alignof (ipsec_sa_outb_rt_t));
+                               alignof (ipsec_sa_outb_rt_t));
   im->inb_sa_runtimes[sa_index] = irt;
   im->outb_sa_runtimes[sa_index] = ort;
-  clib_memset (irt, 0, sizeof (ipsec_sa_inb_rt_t));
-  clib_memset (ort, 0, sizeof (ipsec_sa_outb_rt_t));
+
+  *irt = (ipsec_sa_inb_rt_t){
+    .thread_index = thread_index,
+    .anti_replay_window_size = anti_replay_window_size,
+  };
+
+  *ort = (ipsec_sa_outb_rt_t){
+    .thread_index = thread_index,
+  };
 
   clib_pcg64i_srandom_r (&ort->iv_prng, rand[0], rand[1]);
 
@@ -470,12 +488,7 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
   sa->spi = spi;
   sa->stat_index = sa_index;
   sa->protocol = proto;
-  sa->flags = flags;
   sa->salt = salt;
-  if (irt)
-    irt->thread_index = (vlib_num_workers ()) ? ~0 : 0;
-  if (ort)
-    ort->thread_index = (vlib_num_workers ()) ? ~0 : 0;
 
   if (integ_alg != IPSEC_INTEG_ALG_NONE)
     {
@@ -485,9 +498,6 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
   ipsec_sa_set_crypto_alg (sa, crypto_alg);
   ipsec_sa_set_async_op_ids (sa);
 
-  if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa) && anti_replay_window_size > 64)
-    ipsec_sa_set_ANTI_REPLAY_HUGE (sa);
-
   clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
 
   if (crypto_alg != IPSEC_CRYPTO_ALG_NONE)
@@ -603,7 +613,6 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
   /* window size rounded up to next power of 2 */
   if (ipsec_sa_is_set_ANTI_REPLAY_HUGE (sa))
     {
-      anti_replay_window_size = 1 << max_log2 (anti_replay_window_size);
       irt->replay_window_huge =
        clib_bitmap_set_region (0, 0, 1, anti_replay_window_size);
     }
index ce2964a..4509a44 100644 (file)
@@ -166,6 +166,7 @@ typedef struct
   u16 async_op_id;
   vnet_crypto_key_index_t cipher_key_index;
   vnet_crypto_key_index_t integ_key_index;
+  u32 anti_replay_window_size;
   union
   {
     u64 replay_window;
@@ -336,42 +337,10 @@ extern uword unformat_ipsec_key (unformat_input_t *input, va_list *args);
  * Anti Replay definitions
  */
 
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE(_irt)                                \
-  (u32) (PREDICT_FALSE (_irt->anti_reply_huge) ?                              \
-          clib_bitmap_bytes (_irt->replay_window_huge) * 8 :                 \
-          BITS (_irt->replay_window))
-
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN(_irt, _is_huge)            \
-  (u32) (_is_huge ? clib_bitmap_bytes (_irt->replay_window_huge) * 8 :        \
-                   BITS (_irt->replay_window))
-
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_N_SEEN(_irt)                              \
-  (u64) (PREDICT_FALSE (_irt->anti_reply_huge) ?                              \
-          clib_bitmap_count_set_bits (_irt->replay_window_huge) :            \
-          count_set_bits (_irt->replay_window))
-
 #define IPSEC_SA_ANTI_REPLAY_WINDOW_N_SEEN_KNOWN_WIN(_irt, _is_huge)          \
   (u64) (_is_huge ? clib_bitmap_count_set_bits (_irt->replay_window_huge) :   \
                    count_set_bits (_irt->replay_window))
 
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_MAX_INDEX(_irt)                           \
-  (u32) (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (_irt) - 1)
-
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_MAX_INDEX_KNOWN_WIN(_irt, _is_huge)       \
-  (u32) (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (_irt, _is_huge) - 1)
-
-/*
- * sequence number less than the lower bound are outside of the window
- * From RFC4303 Appendix A:
- *  Bl = Tl - W + 1
- */
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND(_sa)                          \
-  (u32) (_sa->seq - IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (_sa) + 1)
-
-#define IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND_KNOWN_WIN(_sa, _is_huge)      \
-  (u32) (_sa->seq -                                                           \
-        IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN (_sa, _is_huge) + 1)
-
 always_inline u64
 ipsec_sa_anti_replay_get_64b_window (const ipsec_sa_inb_rt_t *irt)
 {
@@ -379,7 +348,7 @@ ipsec_sa_anti_replay_get_64b_window (const ipsec_sa_inb_rt_t *irt)
     return irt->replay_window;
 
   u64 w;
-  u32 window_size = IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (irt);
+  u32 window_size = irt->anti_replay_window_size;
   u32 tl_win_index = irt->seq & (window_size - 1);
 
   if (PREDICT_TRUE (tl_win_index >= 63))
@@ -400,7 +369,7 @@ always_inline int
 ipsec_sa_anti_replay_check (const ipsec_sa_inb_rt_t *irt, u32 seq,
                            bool ar_huge)
 {
-  u32 window_size = IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN (irt, ar_huge);
+  u32 window_size = irt->anti_replay_window_size;
 
   /* we assume that the packet is in the window.
    * if the packet falls left (sa->seq - seq >= window size),
@@ -435,9 +404,8 @@ ipsec_sa_anti_replay_and_sn_advance (const ipsec_sa_inb_rt_t *irt, u32 seq,
 {
   ASSERT ((post_decrypt == false) == (hi_seq_req != 0));
 
-  u32 window_size = IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN (irt, ar_huge);
-  u32 window_lower_bound =
-    IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND_KNOWN_WIN (irt, ar_huge);
+  u32 window_size = irt->anti_replay_window_size;
+  u32 window_lower_bound = irt->seq - window_size + 1;
 
   if (!irt->use_esn)
     {
@@ -623,7 +591,7 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc,
 {
   u32 n_lost = 0;
   u32 seen = 0;
-  u32 window_size = IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN (irt, ar_huge);
+  u32 window_size = irt->anti_replay_window_size;
 
   if (inc < window_size)
     {
@@ -778,7 +746,7 @@ ipsec_sa_anti_replay_advance (ipsec_sa_inb_rt_t *irt, u32 thread_index,
                              u32 seq, u32 hi_seq, bool ar_huge)
 {
   u64 n_lost = 0;
-  u32 window_size = IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE_KNOWN_WIN (irt, ar_huge);
+  u32 window_size = irt->anti_replay_window_size;
   u32 pos;
 
   if (irt->use_esn)