diff options
author | Janne Peltonen <janne.peltonen@nokia.com> | 2021-05-07 17:49:39 +0300 |
---|---|---|
committer | Matias Elo <matias.elo@nokia.com> | 2021-05-11 10:50:27 +0300 |
commit | 2b84189a0cb8f707da35824a342ffa3970735625 (patch) | |
tree | c0650d8e44fc08120a457a9d8fcea41a93eeb519 | |
parent | 72d719e4dc0ccc11c58ad3ece26c9c28e0a901ca (diff) |
linux-gen: ipsec: simplify and describe SA states
Now that free SAs are allocated from a freelist, there is no need for
the reserved state anymore. A free SA taken away from the list cannot
be allocated by any other thread and will change state to active when
published at the end of SA creation.
Get rid of the reserved state, define the existing active state
explicitly, get rid of state value dependent trickery and describe
the states better.
Signed-off-by: Janne Peltonen <janne.peltonen@nokia.com>
Reviewed-by: Jere Leppänen <jere.leppanen@nokia.com>
-rw-r--r-- | platform/linux-generic/odp_ipsec_sad.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c index b6233fa2d..18fc72c8a 100644 --- a/platform/linux-generic/odp_ipsec_sad.c +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -22,9 +22,22 @@ #include <string.h> -#define IPSEC_SA_STATE_DISABLE 0x40000000 -#define IPSEC_SA_STATE_FREE 0xc0000000 -#define IPSEC_SA_STATE_RESERVED 0x80000000 +/* + * SA state consists of state value in the high order bits of ipsec_sa_t::state + * and use counter in the low order bits. + * + * An SA cannot be destroyed if its use count is higher than one. Use counter + * is needed for the case SA lookup is done by us and not the application. + * In the latter case we rely on the fact that the application may not pass + * the SA as a parameter to an IPsec operation concurrently with a call + * to odp_ipsec_sa_disable(). + * + * SAs that are free or being disabled cannot be found in SA lookup by ODP. + */ +#define IPSEC_SA_STATE_ACTIVE 0x00000000 /* SA is in use */ +#define IPSEC_SA_STATE_DISABLE 0x40000000 /* SA is being disabled */ +#define IPSEC_SA_STATE_FREE 0xc0000000 /* SA is unused and free */ +#define IPSEC_SA_STATE_MASK 0xc0000000 /* mask of state bits */ #define SA_IDX_NONE UINT32_MAX @@ -264,8 +277,6 @@ static ipsec_sa_t *ipsec_sa_reserve(void) if (sa_idx != SA_IDX_NONE) { ipsec_sa = ipsec_sa_entry(sa_idx); ipsec_sa_tbl->sa_freelist.head = ipsec_sa->next_sa; - odp_atomic_store_u32(&ipsec_sa->state, - IPSEC_SA_STATE_RESERVED); } odp_spinlock_unlock(&ipsec_sa_tbl->sa_freelist.lock); return ipsec_sa; @@ -283,7 +294,7 @@ static void ipsec_sa_release(ipsec_sa_t *ipsec_sa) /* Mark reserved SA as available now */ static void ipsec_sa_publish(ipsec_sa_t *ipsec_sa) { - odp_atomic_store_rel_u32(&ipsec_sa->state, 0); + odp_atomic_store_rel_u32(&ipsec_sa->state, IPSEC_SA_STATE_ACTIVE); } static int ipsec_sa_lock(ipsec_sa_t *ipsec_sa) @@ -294,11 +305,9 @@ static int ipsec_sa_lock(ipsec_sa_t *ipsec_sa) while (0 == cas) { /* * This can be called from lookup path, so we really need this - * check. Thanks to the way flags are defined we actually test - * that the SA is not DISABLED, FREE or RESERVED using just one - * condition. + * check. */ - if (state & IPSEC_SA_STATE_FREE) + if ((state & IPSEC_SA_STATE_MASK) != IPSEC_SA_STATE_ACTIVE) return -1; cas = odp_atomic_cas_acq_u32(&ipsec_sa->state, &state, |