All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: "Medvedkin, Vladimir" <vladimir.medvedkin@intel.com>,
	"dev@dpdk.org" <dev@dpdk.org>
Cc: "Iremonger, Bernard" <bernard.iremonger@intel.com>,
	"akhil.goyal@nxp.com" <akhil.goyal@nxp.com>
Subject: Re: [dpdk-dev] [PATCH v1 3/5] ipsec: add SAD add/delete/lookup implementation
Date: Thu, 12 Sep 2019 17:58:44 +0000	[thread overview]
Message-ID: <2601191342CEEE43887BDE71AB9772580191964A5F@irsmsx105.ger.corp.intel.com> (raw)
In-Reply-To: <35869a61ec4294e0c991eb145c385b05f2db1e0d.1567529480.git.vladimir.medvedkin@intel.com>

Hi Vladimir,

> 
> Replace rte_ipsec_sad_add(), rte_ipsec_sad_del() and
> rte_ipsec_sad_lookup() stubs with actual implementation.
> 
> It uses three librte_hash tables each of which contains
> an entries for a specific SA type (either it is addressed by SPI only
> or SPI+DIP or SPI+DIP+SIP)
> 
> Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> ---
>  lib/librte_ipsec/ipsec_sad.c | 245 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 233 insertions(+), 12 deletions(-)
> 
> diff --git a/lib/librte_ipsec/ipsec_sad.c b/lib/librte_ipsec/ipsec_sad.c
> index 7797628..4bf2206 100644
> --- a/lib/librte_ipsec/ipsec_sad.c
> +++ b/lib/librte_ipsec/ipsec_sad.c
> @@ -13,6 +13,13 @@
> 
>  #include "rte_ipsec_sad.h"
> 
> +/*
> + * Rules are stored in three hash tables depending on key_type.
> + * Each rule will also be stored in SPI_ONLY table.
> + * for each data entry within this table last two bits are reserved to
> + * indicate presence of entries with the same SPI in DIP and DIP+SIP tables.
> + */
> +
>  #define IPSEC_SAD_NAMESIZE	64
>  #define SAD_PREFIX		"SAD_"
>  /* "SAD_<name>" */
> @@ -37,20 +44,158 @@ static struct rte_tailq_elem rte_ipsec_sad_tailq = {
>  };
>  EAL_REGISTER_TAILQ(rte_ipsec_sad_tailq)
> 
> +#define SET_BIT(ptr, bit)	(void *)((uintptr_t)(ptr) | (uintptr_t)(bit))
> +#define CLEAR_BIT(ptr, bit)	(void *)((uintptr_t)(ptr) & ~(uintptr_t)(bit))
> +#define GET_BIT(ptr, bit)	(void *)((uintptr_t)(ptr) & (uintptr_t)(bit))
> +
> +/*
> + * @internal helper function
> + * Add a rule of type SPI_DIP or SPI_DIP_SIP.
> + * Inserts a rule into an appropriate hash table,
> + * updates the value for a given SPI in SPI_ONLY hash table
> + * reflecting presence of more specific rule type in two LSBs.
> + * Updates a counter that reflects the number of rules whith the same SPI.
> + */
> +static inline int
> +add_specific(struct rte_ipsec_sad *sad, void *key,
> +		int key_type, void *sa)
> +{
> +	void *tmp_val;
> +	int ret, notexist;
> +
> +	ret = rte_hash_lookup(sad->hash[key_type], key);
> +	notexist = (ret == -ENOENT);
> +	ret = rte_hash_add_key_data(sad->hash[key_type], key, sa);
> +	if (ret != 0)
> +		return ret;
> +	ret = rte_hash_lookup_data(sad->hash[RTE_IPSEC_SAD_SPI_ONLY],
> +		key, &tmp_val);
> +	if (ret < 0)
> +		tmp_val = NULL;
> +	tmp_val = SET_BIT(tmp_val, key_type);
> +	ret = rte_hash_add_key_data(sad->hash[RTE_IPSEC_SAD_SPI_ONLY],
> +		key, tmp_val);
> +	if (ret != 0)
> +		return ret;
> +	ret = rte_hash_lookup(sad->hash[RTE_IPSEC_SAD_SPI_ONLY], key);
> +	if (key_type == RTE_IPSEC_SAD_SPI_DIP)
> +		sad->cnt_arr[ret].cnt_2 += notexist;
> +	else
> +		sad->cnt_arr[ret].cnt_3 += notexist;
> +
> +	return 0;
> +}
> +
>  int
> -rte_ipsec_sad_add(__rte_unused struct rte_ipsec_sad *sad,
> -		__rte_unused union rte_ipsec_sad_key *key,
> -		__rte_unused int key_type, __rte_unused void *sa)
> +rte_ipsec_sad_add(struct rte_ipsec_sad *sad, union rte_ipsec_sad_key *key,
> +		int key_type, void *sa)
> +{
> +	void *tmp_val;
> +	int ret;
> +
> +	if ((sad == NULL) || (key == NULL) || (sa == NULL) ||
> +			/* sa must be 4 byte aligned */
> +			(GET_BIT(sa, RTE_IPSEC_SAD_KEY_TYPE_MASK) != 0))
> +		return -EINVAL;
> +
> +	/*
> +	 * Rules are stored in three hash tables depending on key_type.
> +	 * All rules will also have an entry in SPI_ONLY table, with entry
> +	 * value's two LSB's also indicating presence of rule with this SPI
> +	 * in other tables.
> +	 */
> +	switch (key_type) {
> +	case(RTE_IPSEC_SAD_SPI_ONLY):
> +		ret = rte_hash_lookup_data(sad->hash[key_type],
> +			key, &tmp_val);
> +		if (ret >= 0)
> +			tmp_val = SET_BIT(sa, GET_BIT(tmp_val,
> +				RTE_IPSEC_SAD_KEY_TYPE_MASK));
> +		else
> +			tmp_val = sa;
> +		ret = rte_hash_add_key_data(sad->hash[key_type],
> +			key, tmp_val);
> +		return ret;
> +	case(RTE_IPSEC_SAD_SPI_DIP):
> +	case(RTE_IPSEC_SAD_SPI_DIP_SIP):
> +		return add_specific(sad, key, key_type, sa);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +/*
> + * @internal helper function
> + * Delete a rule of type SPI_DIP or SPI_DIP_SIP.
> + * Deletes an entry from an appropriate hash table and decrements
> + * an entry counter for given SPI.
> + * If entry to remove is the last one with given SPI within the table,
> + * then it will also update related entry in SPI_ONLY table.
> + * Removes an entry from SPI_ONLY hash table if there no rule left
> + * for this SPI in any table.
> + */
> +static inline int
> +del_specific(struct rte_ipsec_sad *sad, void *key, int key_type)
>  {

const void *key
? 

> -	return -ENOTSUP;
> +	void *tmp_val;
> +	int ret;
> +	uint32_t *cnt;

Few extra comments inside that function and add_specific() wouldn't hurt.

> +
> +	ret = rte_hash_del_key(sad->hash[key_type], key);
> +	if (ret < 0)
> +		return ret;
> +	ret = rte_hash_lookup_data(sad->hash[RTE_IPSEC_SAD_SPI_ONLY],
> +		key, &tmp_val);
> +	if (ret < 0)
> +		return ret;
> +	cnt = (key_type == RTE_IPSEC_SAD_SPI_DIP) ? &sad->cnt_arr[ret].cnt_2 :
> +			&sad->cnt_arr[ret].cnt_3;
> +	if (--(*cnt) != 0)
> +		return 0;
> +
> +	tmp_val = CLEAR_BIT(tmp_val, key_type);
> +	if (tmp_val == NULL)
> +		ret = rte_hash_del_key(sad->hash[RTE_IPSEC_SAD_SPI_ONLY], key);
> +	else
> +		ret = rte_hash_add_key_data(sad->hash[RTE_IPSEC_SAD_SPI_ONLY],
> +			key, tmp_val);
> +	if (ret < 0)
> +		return ret;
> +	return 0;
>  }
> 
>  int
> -rte_ipsec_sad_del(__rte_unused struct rte_ipsec_sad *sad,
> -		__rte_unused union rte_ipsec_sad_key *key,
> -		__rte_unused int key_type)
> +rte_ipsec_sad_del(struct rte_ipsec_sad *sad, union rte_ipsec_sad_key *key,

const union rte_ipsec_sad_key *key
?

> +		int key_type)
>  {
> -	return -ENOTSUP;
> +	void *tmp_val;
> +	int ret;
> +
> +	if ((sad == NULL) || (key == NULL))
> +		return -EINVAL;
> +	switch (key_type) {
> +	case(RTE_IPSEC_SAD_SPI_ONLY):
> +		ret = rte_hash_lookup_data(sad->hash[key_type],
> +			key, &tmp_val);
> +		if (ret < 0)
> +			return ret;
> +		if (GET_BIT(tmp_val, RTE_IPSEC_SAD_KEY_TYPE_MASK) == 0) {
> +			RTE_ASSERT((cnt_2 == 0) && (cnt_3 == 0));
> +			ret = rte_hash_del_key(sad->hash[key_type],
> +				key);

I think something like:
ret = ret < 0 ? ret : 0;
is needed here.

> +		} else {
> +			tmp_val = GET_BIT(tmp_val,
> +				RTE_IPSEC_SAD_KEY_TYPE_MASK);
> +			ret = rte_hash_add_key_data(sad->hash[key_type],
> +				key, tmp_val);
> +		}
> +		return ret;
> +	case(RTE_IPSEC_SAD_SPI_DIP):
> +	case(RTE_IPSEC_SAD_SPI_DIP_SIP):
> +		return del_specific(sad, key, key_type);
> +	default:
> +		return -EINVAL;
> +	}
>  }
> 
>  struct rte_ipsec_sad *
> @@ -248,10 +393,86 @@ rte_ipsec_sad_free(struct rte_ipsec_sad *sad)
>  		rte_free(te);
>  }
> 

Pls add a comment for that one and other internal function.
Even if you do remember what exactly it does now, you won't a year later :)

> +static int
> +__ipsec_sad_lookup(const struct rte_ipsec_sad *sad,
> +		const union rte_ipsec_sad_key *keys[], uint32_t n, void *sa[])
> +{
> +	const void *keys_2[RTE_HASH_LOOKUP_BULK_MAX];
> +	const void *keys_3[RTE_HASH_LOOKUP_BULK_MAX];
> +	void *vals_2[RTE_HASH_LOOKUP_BULK_MAX] = {NULL};
> +	void *vals_3[RTE_HASH_LOOKUP_BULK_MAX] = {NULL};
> +	uint32_t idx_2[RTE_HASH_LOOKUP_BULK_MAX];
> +	uint32_t idx_3[RTE_HASH_LOOKUP_BULK_MAX];
> +	uint64_t mask_1, mask_2, mask_3;
> +	uint64_t map, map_spec;
> +	uint32_t n_2 = 0;
> +	uint32_t n_3 = 0;
> +	uint32_t i;
> +	int n_pkts = 0;

s/n_pkts/found/
?

> +
> +	for (i = 0; i < n; i++)
> +		sa[i] = NULL;
> +
> +	/*
> +	 * Lookup keys in SPI only hash table first.
> +	 */
> +	rte_hash_lookup_bulk_data(sad->hash[RTE_IPSEC_SAD_SPI_ONLY],
> +		(const void **)keys, n, &mask_1, sa);
> +	for (map = mask_1; map; map &= (map - 1)) {
> +		i = rte_bsf64(map);
> +		/*
> +		 * if returned value indicates presence of a rule in other
> +		 * tables save a key for further lookup.
> +		 */
> +		if ((uintptr_t)sa[i] & RTE_IPSEC_SAD_SPI_DIP_SIP) {
> +			idx_3[n_3] = i;
> +			keys_3[n_3++] = keys[i];
> +		}
> +		if ((uintptr_t)sa[i] & RTE_IPSEC_SAD_SPI_DIP) {
> +			idx_2[n_2] = i;
> +			keys_2[n_2++] = keys[i];
> +		}
> +		sa[i] = CLEAR_BIT(sa[i], RTE_IPSEC_SAD_KEY_TYPE_MASK);
> +	}

Just as a thought - instead of setting all sa[] to NULL first, and then
going though only found in the loop above, wouldn't it be a bit faster -
after lookup bulk go through all sa[] and set them depending on mask value?
Then first(zero sa[] loop) can be removed.

> +
> +	if (n_2 != 0) {
> +		rte_hash_lookup_bulk_data(sad->hash[RTE_IPSEC_SAD_SPI_DIP],
> +			keys_2, n_2, &mask_2, vals_2);
> +		for (map_spec = mask_2; map_spec; map_spec &= (map_spec - 1)) {
> +			i = rte_bsf64(map_spec);
> +			sa[idx_2[i]] = vals_2[i];
> +		}
> +	}
> +	if (n_3 != 0) {
> +		rte_hash_lookup_bulk_data(sad->hash[RTE_IPSEC_SAD_SPI_DIP_SIP],
> +			keys_3, n_3, &mask_3, vals_3);
> +		for (map_spec = mask_3; map_spec; map_spec &= (map_spec - 1)) {
> +			i = rte_bsf64(map_spec);
> +			sa[idx_3[i]] = vals_3[i];
> +		}
> +	}
> +	for (i = 0; i < n; i++)
> +		n_pkts += (sa[i] != NULL);
> +
> +	return n_pkts;
> +}
> +
>  int
> -rte_ipsec_sad_lookup(__rte_unused const struct rte_ipsec_sad *sad,
> -		__rte_unused const union rte_ipsec_sad_key *keys[],
> -		__rte_unused uint32_t n, __rte_unused void *sa[])
> +rte_ipsec_sad_lookup(const struct rte_ipsec_sad *sad,
> +		const union rte_ipsec_sad_key *keys[], uint32_t n, void *sa[])

Better to follow usual parameter convention and move 'n' after pointers, i.e.:

int rte_ipsec_sad_lookup(const struct rte_ipsec_sad *sad, const union rte_ipsec_sad_key *keys[], void *sa[], uint32_t n)

Or provably even better:
int rte_ipsec_sad_lookup(const struct rte_ipsec_sad *sad, const union rte_ipsec_sad_key *keys[], const void *sa[], uint32_t n)


>  {
> -	return -ENOTSUP;
> +	uint32_t num, i = 0;
> +	int n_pkts = 0;
> +
> +	if (unlikely((sad == NULL) || (keys == NULL) || (sa == NULL)))
> +		return -EINVAL;
> +
> +	do {
> +		num = RTE_MIN(n - i, (uint32_t)RTE_HASH_LOOKUP_BULK_MAX);
> +		n_pkts += __ipsec_sad_lookup(sad,
> +			&keys[i], num, &sa[i]);
> +		i += num;
> +	} while (i != n);
> +
> +	return n_pkts;
>  }
> --
> 2.7.4


  reply	other threads:[~2019-09-12 17:58 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-13 15:13 [dpdk-dev] [RFC 0/5] ipsec: add inbound SAD Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 2/5] ipsec: add SAD create/free API Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 5/5] app: add test-sad application Vladimir Medvedkin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 0/5] ipsec: add inbound SAD Vladimir Medvedkin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 " Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 " Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 " Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 " Vladimir Medvedkin
2019-10-11 11:34           ` Akhil Goyal
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 0/6] " Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 0/5] " Vladimir Medvedkin
2019-10-22  7:53               ` Akhil Goyal
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 1/6] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 2/6] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 3/6] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 4/6] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 5/6] app: add test-sad application Vladimir Medvedkin
2019-10-21  9:57             ` Akhil Goyal
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 6/6] doc/ipsec: update ipsec programmer's guide Vladimir Medvedkin
2019-10-18 10:09             ` Ananyev, Konstantin
2019-10-21  8:19             ` Akhil Goyal
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-11 10:42           ` Akhil Goyal
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-09 10:49         ` Ananyev, Konstantin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-09 10:56         ` Ananyev, Konstantin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-02 11:24     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-02 11:55     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-02 12:04     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-02 11:16     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-02 13:27     ` Ananyev, Konstantin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-09-14 23:05   ` Ananyev, Konstantin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 2/5] ipsec: add SAD create/free API Vladimir Medvedkin
2019-09-12 18:08   ` Ananyev, Konstantin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-09-12 17:58   ` Ananyev, Konstantin [this message]
2019-10-01 17:24     ` Medvedkin, Vladimir
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 5/5] app: add test-sad application Vladimir Medvedkin
2019-09-12 18:30   ` Ananyev, Konstantin
2019-09-12 18:33     ` Ananyev, Konstantin
2019-09-12 18:34 ` [dpdk-dev] [RFC 0/5] ipsec: add inbound SAD Ananyev, Konstantin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2601191342CEEE43887BDE71AB9772580191964A5F@irsmsx105.ger.corp.intel.com \
    --to=konstantin.ananyev@intel.com \
    --cc=akhil.goyal@nxp.com \
    --cc=bernard.iremonger@intel.com \
    --cc=dev@dpdk.org \
    --cc=vladimir.medvedkin@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.