diff options
author | 2025-02-13 17:09:52 +0100 | |
---|---|---|
committer | 2025-02-13 23:36:06 +0100 | |
commit | 508facbdde97b7d007e081940c264ab6559c1b23 (patch) | |
tree | 8b4c2fcbf3fb6d0eede455668632bc9ef8aeb3c6 /src/vnet | |
parent | 117237f6225de001bd8385ac5b518a20b16dfa0d (diff) |
ipsec: embed anti-replay bitmap in the runtime data
Type: improvement
Change-Id: I753917c6d7e30b8d5e3291b85a7532a455ebc2bb
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.c | 31 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.h | 79 |
2 files changed, 47 insertions, 63 deletions
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c index cadd08bcf74..b59175144da 100644 --- a/src/vnet/ipsec/ipsec_sa.c +++ b/src/vnet/ipsec/ipsec_sa.c @@ -426,7 +426,7 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto, ipsec_sa_outb_rt_t *ort; clib_error_t *err; ipsec_sa_t *sa; - u32 sa_index; + u32 sa_index, irt_sz; u16 thread_index = (vlib_num_workers ()) ? ~0 : 0; u64 rand[2]; uword *p; @@ -443,19 +443,22 @@ ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto, 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); + anti_replay_window_size = BITS (irt->replay_window[0]); + + vec_validate (im->inb_sa_runtimes, sa_index); + vec_validate (im->outb_sa_runtimes, sa_index); - irt = clib_mem_alloc_aligned (sizeof (ipsec_sa_inb_rt_t), - alignof (ipsec_sa_inb_rt_t)); + irt_sz = sizeof (ipsec_sa_inb_rt_t); + irt_sz += anti_replay_window_size / 8; + irt_sz = round_pow2 (irt_sz, CLIB_CACHE_LINE_BYTES); + + irt = clib_mem_alloc_aligned (irt_sz, alignof (ipsec_sa_inb_rt_t)); ort = clib_mem_alloc_aligned (sizeof (ipsec_sa_outb_rt_t), alignof (ipsec_sa_outb_rt_t)); im->inb_sa_runtimes[sa_index] = irt; @@ -611,15 +614,8 @@ 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)) - { - irt->replay_window_huge = - clib_bitmap_set_region (0, 0, 1, anti_replay_window_size); - } - else - { - irt->replay_window = ~0; - } + for (u32 i = 0; i < anti_replay_window_size / uword_bits; i++) + irt->replay_window[i] = ~0ULL; hash_set (im->sa_index_by_sa_id, sa->id, sa_index); @@ -660,9 +656,6 @@ ipsec_sa_del (ipsec_sa_t * sa) vnet_crypto_key_del (vm, sa->crypto_sync_key_index); if (sa->integ_alg != IPSEC_INTEG_ALG_NONE) vnet_crypto_key_del (vm, sa->integ_sync_key_index); - if (ipsec_sa_is_set_ANTI_REPLAY_HUGE (sa)) - if (irt && irt->replay_window_huge) - clib_bitmap_free (irt->replay_window_huge); foreach_pointer (p, irt, ort) if (p) clib_mem_free (p); diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index 4509a44b9db..346e71464de 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -167,11 +167,7 @@ typedef struct 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; - clib_bitmap_t *replay_window_huge; - }; + uword replay_window[]; } ipsec_sa_inb_rt_t; typedef struct @@ -333,34 +329,25 @@ extern uword unformat_ipsec_key (unformat_input_t *input, va_list *args); #define IPSEC_UDP_PORT_NONE ((u16) ~0) -/* - * Anti Replay definitions - */ - -#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)) - always_inline u64 ipsec_sa_anti_replay_get_64b_window (const ipsec_sa_inb_rt_t *irt) { + uword *bmp = (uword *) irt->replay_window; + if (!irt->anti_reply_huge) - return irt->replay_window; + return irt->replay_window[0]; u64 w; u32 window_size = irt->anti_replay_window_size; u32 tl_win_index = irt->seq & (window_size - 1); if (PREDICT_TRUE (tl_win_index >= 63)) - return clib_bitmap_get_multiple (irt->replay_window_huge, - tl_win_index - 63, 64); + return uword_bitmap_get_multiple (bmp, tl_win_index - 63, 64); - w = clib_bitmap_get_multiple_no_check (irt->replay_window_huge, 0, - tl_win_index + 1) + w = uword_bitmap_get_multiple_no_check (bmp, 0, tl_win_index + 1) << (63 - tl_win_index); - w |= clib_bitmap_get_multiple_no_check (irt->replay_window_huge, - window_size - 63 + tl_win_index, - 63 - tl_win_index); + w |= uword_bitmap_get_multiple_no_check ( + bmp, window_size - 63 + tl_win_index, 63 - tl_win_index); return w; } @@ -376,9 +363,10 @@ ipsec_sa_anti_replay_check (const ipsec_sa_inb_rt_t *irt, u32 seq, * the result is wrong */ if (ar_huge) - return clib_bitmap_get (irt->replay_window_huge, seq & (window_size - 1)); + return uword_bitmap_is_bit_set ((uword *) irt->replay_window, + seq & (window_size - 1)); else - return (irt->replay_window >> (window_size + seq - irt->seq - 1)) & 1; + return (irt->replay_window[0] >> (window_size + seq - irt->seq - 1)) & 1; return 0; } @@ -592,13 +580,13 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc, u32 n_lost = 0; u32 seen = 0; u32 window_size = irt->anti_replay_window_size; + uword *window = irt->replay_window; if (inc < window_size) { if (ar_huge) { /* the number of packets we saw in this section of the window */ - clib_bitmap_t *window = irt->replay_window_huge; u32 window_lower_bound = (irt->seq + 1) & (window_size - 1); u32 window_next_lower_bound = (window_lower_bound + inc) & (window_size - 1); @@ -684,8 +672,8 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc, window[i_block] &= ~mask; } - clib_bitmap_set_no_check (window, - (irt->seq + inc) & (window_size - 1), 1); + uword_bitmap_set_bits_at_index ( + window, (irt->seq + inc) & (window_size - 1), 1); } else { @@ -694,11 +682,11 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc, * of the window that we will right shift of the end * as a result of this increments */ - u64 old = irt->replay_window & pow2_mask (inc); + u64 old = irt->replay_window[0] & pow2_mask (inc); /* the number of packets we saw in this section of the window */ seen = count_set_bits (old); - irt->replay_window = - ((irt->replay_window) >> inc) | (1ULL << (window_size - 1)); + irt->replay_window[0] = + ((irt->replay_window[0]) >> inc) | (1ULL << (window_size - 1)); } /* @@ -709,9 +697,12 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc, } else { + u32 n_uwords = window_size / uword_bits; /* holes in the replay window are lost packets */ - n_lost = window_size - - IPSEC_SA_ANTI_REPLAY_WINDOW_N_SEEN_KNOWN_WIN (irt, ar_huge); + if (ar_huge) + n_lost = window_size - uword_bitmap_count_set_bits (window, n_uwords); + else + n_lost = window_size - count_set_bits (irt->replay_window[0]); /* any sequence numbers that now fall outside the window * are forever lost */ @@ -719,13 +710,13 @@ ipsec_sa_anti_replay_window_shift (ipsec_sa_inb_rt_t *irt, u32 inc, if (PREDICT_FALSE (ar_huge)) { - clib_bitmap_zero (irt->replay_window_huge); - clib_bitmap_set_no_check (irt->replay_window_huge, - (irt->seq + inc) & (window_size - 1), 1); + uword_bitmap_clear (window, n_uwords); + uword_bitmap_set_bits_at_index ( + window, (irt->seq + inc) & (window_size - 1), 1); } else { - irt->replay_window = 1ULL << (window_size - 1); + irt->replay_window[0] = 1ULL << (window_size - 1); } } @@ -770,19 +761,19 @@ ipsec_sa_anti_replay_advance (ipsec_sa_inb_rt_t *irt, u32 thread_index, { pos = ~seq + irt->seq + 1; if (ar_huge) - clib_bitmap_set_no_check (irt->replay_window_huge, - seq & (window_size - 1), 1); + uword_bitmap_set_bits_at_index (irt->replay_window, + seq & (window_size - 1), 1); else - irt->replay_window |= (1ULL << (window_size - 1 - pos)); + irt->replay_window[0] |= (1ULL << (window_size - 1 - pos)); } else { pos = irt->seq - seq; if (ar_huge) - clib_bitmap_set_no_check (irt->replay_window_huge, - seq & (window_size - 1), 1); + uword_bitmap_set_bits_at_index (irt->replay_window, + seq & (window_size - 1), 1); else - irt->replay_window |= (1ULL << (window_size - 1 - pos)); + irt->replay_window[0] |= (1ULL << (window_size - 1 - pos)); } } else @@ -797,10 +788,10 @@ ipsec_sa_anti_replay_advance (ipsec_sa_inb_rt_t *irt, u32 thread_index, { pos = irt->seq - seq; if (ar_huge) - clib_bitmap_set_no_check (irt->replay_window_huge, - seq & (window_size - 1), 1); + uword_bitmap_set_bits_at_index (irt->replay_window, + seq & (window_size - 1), 1); else - irt->replay_window |= (1ULL << (window_size - 1 - pos)); + irt->replay_window[0] |= (1ULL << (window_size - 1 - pos)); } } |